/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.test.voiceinteraction;

import android.app.ActivityManager;
import android.app.VoiceInteractor;
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.service.voice.VoiceInteractionSession;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;

public class MainInteractionSession extends VoiceInteractionSession
        implements View.OnClickListener {
    static final String TAG = "MainInteractionSession";

    Intent mStartIntent;
    View mContentView;
    AssistVisualizer mAssistVisualizer;
    View mTopContent;
    View mBottomContent;
    TextView mText;
    Button mTreeButton;
    Button mTextButton;
    Button mStartButton;
    CheckBox mOptionsCheck;
    View mOptionsContainer;
    CheckBox mDisallowAssist;
    CheckBox mDisallowScreenshot;
    TextView mOptionsText;
    ImageView mScreenshot;
    ImageView mFullScreenshot;
    Button mConfirmButton;
    Button mCompleteButton;
    Button mAbortButton;

    Bundle mAssistData;
    AssistStructure mAssistStructure;
    AssistContent mAssistContent;

    static final int STATE_IDLE = 0;
    static final int STATE_LAUNCHING = 1;
    static final int STATE_CONFIRM = 2;
    static final int STATE_PICK_OPTION = 3;
    static final int STATE_COMMAND = 4;
    static final int STATE_ABORT_VOICE = 5;
    static final int STATE_COMPLETE_VOICE = 6;
    static final int STATE_DONE = 7;

    int mState = STATE_IDLE;
    VoiceInteractor.PickOptionRequest.Option[] mPendingOptions;
    CharSequence mPendingPrompt;
    Request mPendingRequest;
    int mCurrentTask = -1;
    int mShowFlags;

    MainInteractionSession(Context context) {
        super(context);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        ActivityManager am = getContext().getSystemService(ActivityManager.class);
        am.setWatchHeapLimit(40 * 1024 * 1024);
    }

    @Override
    public void onShow(Bundle args, int showFlags) {
        super.onShow(args, showFlags);
        mShowFlags = showFlags;
        Log.i(TAG, "onShow: flags=0x" + Integer.toHexString(showFlags) + " args=" + args);
        mState = STATE_IDLE;
        mStartIntent = args != null ? (Intent)args.getParcelable("intent") : null;
        if (mStartIntent == null) {
            mStartIntent = new Intent(getContext(), TestInteractionActivity.class);
        }
        if (mAssistVisualizer != null) {
            mAssistVisualizer.clearAssistData();
        }
        onHandleScreenshot(null);
        updateState();
        refreshOptions();
    }

    @Override
    public void onHide() {
        super.onHide();
        if (mAssistVisualizer != null) {
            mAssistVisualizer.clearAssistData();
        }
        mState = STATE_DONE;
        updateState();
    }

    @Override
    public View onCreateContentView() {
        mContentView = getLayoutInflater().inflate(R.layout.voice_interaction_session, null);
        mAssistVisualizer = (AssistVisualizer)mContentView.findViewById(R.id.assist_visualizer);
        if (mAssistStructure != null) {
            mAssistVisualizer.setAssistStructure(mAssistStructure);
        }
        mTopContent = mContentView.findViewById(R.id.top_content);
        mBottomContent = mContentView.findViewById(R.id.bottom_content);
        mText = (TextView)mContentView.findViewById(R.id.text);
        mTreeButton = (Button)mContentView.findViewById(R.id.do_tree);
        mTreeButton.setOnClickListener(this);
        mTextButton = (Button)mContentView.findViewById(R.id.do_text);
        mTextButton.setOnClickListener(this);
        mStartButton = (Button)mContentView.findViewById(R.id.start);
        mStartButton.setOnClickListener(this);
        mScreenshot = (ImageView)mContentView.findViewById(R.id.screenshot);
        mScreenshot.setOnClickListener(this);
        mFullScreenshot = (ImageView)mContentView.findViewById(R.id.full_screenshot);
        mOptionsCheck = (CheckBox)mContentView.findViewById(R.id.show_options);
        mOptionsCheck.setOnClickListener(this);
        mOptionsContainer = mContentView.findViewById(R.id.options);
        mDisallowAssist = (CheckBox)mContentView.findViewById(R.id.disallow_structure);
        mDisallowAssist.setOnClickListener(this);
        mDisallowScreenshot = (CheckBox)mContentView.findViewById(R.id.disallow_screenshot);
        mDisallowScreenshot.setOnClickListener(this);
        mOptionsText = (TextView)mContentView.findViewById(R.id.options_text);
        mConfirmButton = (Button)mContentView.findViewById(R.id.confirm);
        mConfirmButton.setOnClickListener(this);
        mCompleteButton = (Button)mContentView.findViewById(R.id.complete);
        mCompleteButton.setOnClickListener(this);
        mAbortButton = (Button)mContentView.findViewById(R.id.abort);
        mAbortButton.setOnClickListener(this);
        refreshOptions();
        return mContentView;
    }

    void refreshOptions() {
        if (mOptionsContainer != null) {
            if (mOptionsCheck.isChecked()) {
                mOptionsContainer.setVisibility(View.VISIBLE);
                int flags = getDisabledShowContext();
                mDisallowAssist.setChecked((flags & SHOW_WITH_ASSIST) != 0);
                mDisallowScreenshot.setChecked((flags & SHOW_WITH_SCREENSHOT) != 0);
                int disabled = getUserDisabledShowContext();
                mOptionsText.setText("Disabled: 0x" + Integer.toHexString(disabled));
            } else {
                mOptionsContainer.setVisibility(View.GONE);
            }
        }
    }

    public void onHandleAssist(Bundle assistBundle) {
    }

    private void logAssistContentAndData(AssistContent content, Bundle data) {
        if (content != null) {
            Log.i(TAG, "Assist intent: " + content.getIntent());
            Log.i(TAG, "Assist intent from app: " + content.isAppProvidedIntent());
            Log.i(TAG, "Assist clipdata: " + content.getClipData());
            Log.i(TAG, "Assist structured data: " + content.getStructuredData());
            Log.i(TAG, "Assist web uri: " + content.getWebUri());
            Log.i(TAG, "Assist web uri from app: " + content.isAppProvidedWebUri());
            Log.i(TAG, "Assist extras: " + content.getExtras());
        }
        if (data != null) {
            Uri referrer = data.getParcelable(Intent.EXTRA_REFERRER);
            if (referrer != null) {
                Log.i(TAG, "Referrer: " + referrer);
            }
        }
    }

    @Override
    public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) {
        mAssistData = data;
        mAssistStructure = structure;
        mAssistContent = content;
        if (mAssistVisualizer != null) {
            if (mAssistStructure != null) {
                mAssistVisualizer.setAssistStructure(mAssistStructure);
            } else {
                mAssistVisualizer.clearAssistData();
            }
        }
        logAssistContentAndData(content, data);
    }

    @Override
    public void onHandleAssistSecondary(final Bundle data, final AssistStructure structure,
            final AssistContent content, int index, int count) {
        Log.i(TAG, "Got secondary activity assist data " + index + " of " + count);
        Log.i(TAG, "Showing assist structure after a few seconds...");
        mContentView.postDelayed(new Runnable() {
            public void run() {
                onHandleAssist(data, structure, content);
            }
        }, 2000 * index);
    }

    @Override
    public void onHandleScreenshot(Bitmap screenshot) {
        if (mScreenshot != null) {
            if (screenshot != null) {
                mScreenshot.setImageBitmap(screenshot);
                mScreenshot.setAdjustViewBounds(true);
                mScreenshot.setMaxWidth(screenshot.getWidth() / 3);
                mScreenshot.setMaxHeight(screenshot.getHeight() / 3);
                mFullScreenshot.setImageBitmap(screenshot);
            } else {
                mScreenshot.setImageDrawable(null);
                mFullScreenshot.setImageDrawable(null);
            }
        }
    }

    void updateState() {
        if (mTopContent == null) {
            return;
        }
        if (mState == STATE_IDLE) {
            mTopContent.setVisibility(View.VISIBLE);
            mBottomContent.setVisibility(View.GONE);
            mAssistVisualizer.setVisibility(View.VISIBLE);
        } else if (mState == STATE_DONE) {
            mTopContent.setVisibility(View.GONE);
            mBottomContent.setVisibility(View.GONE);
            mAssistVisualizer.setVisibility(View.GONE);
        } else {
            mTopContent.setVisibility(View.GONE);
            mBottomContent.setVisibility(View.VISIBLE);
            mAssistVisualizer.setVisibility(View.GONE);
        }
        mStartButton.setEnabled(mState == STATE_IDLE);
        mConfirmButton.setEnabled(mState == STATE_CONFIRM || mState == STATE_PICK_OPTION
                || mState == STATE_COMMAND);
        mAbortButton.setEnabled(mState == STATE_ABORT_VOICE);
        mCompleteButton.setEnabled(mState == STATE_COMPLETE_VOICE);
    }

    public void onClick(View v) {
        if (v == mTreeButton) {
            if (mAssistVisualizer != null) {
                logAssistContentAndData(mAssistContent, mAssistData);
                mAssistVisualizer.logTree();
            }
        } else if (v == mTextButton) {
            if (mAssistVisualizer != null) {
                mAssistVisualizer.logText();
            }
        } else if (v == mOptionsCheck) {
            refreshOptions();
        } else if (v == mDisallowAssist) {
            int flags = getDisabledShowContext();
            if (mDisallowAssist.isChecked()) {
                flags |= SHOW_WITH_ASSIST;
            } else {
                flags &= ~SHOW_WITH_ASSIST;
            }
            setDisabledShowContext(flags);
        } else if (v == mDisallowScreenshot) {
            int flags = getDisabledShowContext();
            if (mDisallowScreenshot.isChecked()) {
                flags |= SHOW_WITH_SCREENSHOT;
            } else {
                flags &= ~SHOW_WITH_SCREENSHOT;
            }
            setDisabledShowContext(flags);
        } else if (v == mStartButton) {
            mState = STATE_LAUNCHING;
            updateState();
            startVoiceActivity(mStartIntent);
        } else if (v == mConfirmButton) {
            if (mPendingRequest instanceof ConfirmationRequest) {
                ((ConfirmationRequest)mPendingRequest).sendConfirmationResult(true, null);
                mPendingRequest = null;
                mState = STATE_LAUNCHING;
            } else if (mPendingRequest instanceof PickOptionRequest) {
                PickOptionRequest pick = (PickOptionRequest)mPendingRequest;
                int numReturn = mPendingOptions.length/2;
                if (numReturn <= 0) {
                    numReturn = 1;
                }
                VoiceInteractor.PickOptionRequest.Option[] picked
                        = new VoiceInteractor.PickOptionRequest.Option[numReturn];
                for (int i=0; i<picked.length; i++) {
                    picked[i] = mPendingOptions[i*2];
                }
                mPendingOptions = picked;
                if (picked.length <= 1) {
                    pick.sendPickOptionResult(picked, null);
                    mPendingRequest = null;
                    mState = STATE_LAUNCHING;
                } else {
                    pick.sendIntermediatePickOptionResult(picked, null);
                    updatePickText();
                }
            } else if (mPendingRequest instanceof CommandRequest) {
                Bundle result = new Bundle();
                result.putString("key", "a result!");
                ((CommandRequest)mPendingRequest).sendResult(result);
                mPendingRequest = null;
                mState = STATE_LAUNCHING;
            }
        } else if (v == mAbortButton && mPendingRequest instanceof AbortVoiceRequest) {
            ((AbortVoiceRequest)mPendingRequest).sendAbortResult(null);
            mPendingRequest = null;
        } else if (v == mCompleteButton && mPendingRequest instanceof CompleteVoiceRequest) {
            ((CompleteVoiceRequest)mPendingRequest).sendCompleteResult(null);
            mPendingRequest = null;
        } else if (v == mScreenshot) {
            if (mFullScreenshot.getVisibility() != View.VISIBLE) {
                mFullScreenshot.setVisibility(View.VISIBLE);
            } else {
                mFullScreenshot.setVisibility(View.INVISIBLE);
            }
        }
        updateState();
    }

    @Override
    public void onComputeInsets(Insets outInsets) {
        super.onComputeInsets(outInsets);
        if (mState != STATE_IDLE) {
            outInsets.contentInsets.top = mBottomContent.getTop();
            outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_CONTENT;
        } else if ((mShowFlags & SHOW_SOURCE_ACTIVITY) != 0) {
            outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_CONTENT;
        }
    }

    @Override
    public void onTaskStarted(Intent intent, int taskId) {
        super.onTaskStarted(intent, taskId);
        mCurrentTask = taskId;
    }

    @Override
    public void onTaskFinished(Intent intent, int taskId) {
        super.onTaskFinished(intent, taskId);
        if (mCurrentTask == taskId) {
            mCurrentTask = -1;
        }
    }

    @Override
    public void onLockscreenShown() {
        if (mCurrentTask < 0) {
            hide();
        }
    }

    @Override
    public boolean[] onGetSupportedCommands(String[] commands) {
        boolean[] res = new boolean[commands.length];
        for (int i=0; i<commands.length; i++) {
            if ("com.android.test.voiceinteraction.COMMAND".equals(commands[i])) {
                res[i] = true;
            }
        }
        return res;
    }

    void setPrompt(VoiceInteractor.Prompt prompt) {
        if (prompt == null) {
            mText.setText("(null)");
            mPendingPrompt = "";
        } else {
            mText.setText(prompt.getVisualPrompt());
            mPendingPrompt = prompt.getVisualPrompt();
        }
    }

    @Override
    public void onRequestConfirmation(ConfirmationRequest request) {
        Log.i(TAG, "onConfirm: prompt=" + request.getVoicePrompt() + " extras="
                + request.getExtras());
        setPrompt(request.getVoicePrompt());
        mConfirmButton.setText("Confirm");
        mPendingRequest = request;
        mState = STATE_CONFIRM;
        updateState();
    }

    @Override
    public void onRequestPickOption(PickOptionRequest request) {
        Log.i(TAG, "onPickOption: prompt=" + request.getVoicePrompt() + " options="
                + request.getOptions() + " extras=" + request.getExtras());
        mConfirmButton.setText("Pick Option");
        mPendingRequest = request;
        setPrompt(request.getVoicePrompt());
        mPendingOptions = request.getOptions();
        mState = STATE_PICK_OPTION;
        updatePickText();
        updateState();
    }

    void updatePickText() {
        StringBuilder sb = new StringBuilder();
        sb.append(mPendingPrompt);
        sb.append(": ");
        for (int i=0; i<mPendingOptions.length; i++) {
            if (i > 0) {
                sb.append(", ");
            }
            sb.append(mPendingOptions[i].getLabel());
        }
        mText.setText(sb.toString());
    }

    @Override
    public void onRequestCompleteVoice(CompleteVoiceRequest request) {
        Log.i(TAG, "onCompleteVoice: message=" + request.getVoicePrompt() + " extras="
                + request.getExtras());
        setPrompt(request.getVoicePrompt());
        mPendingRequest = request;
        mState = STATE_COMPLETE_VOICE;
        updateState();
    }

    @Override
    public void onRequestAbortVoice(AbortVoiceRequest request) {
        Log.i(TAG, "onAbortVoice: message=" + request.getVoicePrompt() + " extras="
                + request.getExtras());
        setPrompt(request.getVoicePrompt());
        mPendingRequest = request;
        mState = STATE_ABORT_VOICE;
        updateState();
    }

    @Override
    public void onRequestCommand(CommandRequest request) {
        Bundle extras = request.getExtras();
        if (extras != null) {
            extras.getString("arg");
        }
        Log.i(TAG, "onCommand: command=" + request.getCommand() + " extras=" + extras);
        mText.setText("Command: " + request.getCommand() + ", " + extras);
        mConfirmButton.setText("Finish Command");
        mPendingRequest = request;
        mState = STATE_COMMAND;
        updateState();
    }

    @Override
    public void onCancelRequest(Request request) {
        Log.i(TAG, "onCancel");
        if (mPendingRequest == request) {
            mPendingRequest = null;
            mState = STATE_LAUNCHING;
            updateState();
        }
        request.cancel();
    }
}
