/*
 * Copyright (C) 2015 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 android.support.v17.leanback.app;

import android.content.Context;
import android.database.DataSetObserver;
import android.media.AudioManager;
import android.support.v17.leanback.R;
import android.support.v17.leanback.widget.GuidedAction;
import android.support.v17.leanback.widget.GuidedActionsStylist;
import android.support.v17.leanback.widget.ImeKeyMonitor;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;

import java.util.ArrayList;
import java.util.List;

/**
 * GuidedActionAdapter instantiates views for guided actions, and manages their interactions.
 * Presentation (view creation and state animation) is delegated to a {@link
 * GuidedActionsStylist}, while clients are notified of interactions via
 * {@link GuidedActionAdapter.ClickListener} and {@link GuidedActionAdapter.FocusListener}.
 */
class GuidedActionAdapter extends RecyclerView.Adapter {
    private static final String TAG = "GuidedActionAdapter";
    private static final boolean DEBUG = false;

    private static final String TAG_EDIT = "EditableAction";
    private static final boolean DEBUG_EDIT = false;

    /**
     * Object listening for click events within a {@link GuidedActionAdapter}.
     */
    public interface ClickListener {

        /**
         * Called when the user clicks on an action.
         */
        public void onGuidedActionClicked(GuidedAction action);
    }

    /**
     * Object listening for focus events within a {@link GuidedActionAdapter}.
     */
    public interface FocusListener {

        /**
         * Called when the user focuses on an action.
         */
        public void onGuidedActionFocused(GuidedAction action);
    }

    /**
     * Object listening for edit events within a {@link GuidedActionAdapter}.
     */
    public interface EditListener {

        /**
         * Called when the user exits edit mode on an action.
         */
        public long onGuidedActionEdited(GuidedAction action);

        /**
         * Called when Ime Open
         */
        public void onImeOpen();

        /**
         * Called when Ime Close
         */
        public void onImeClose();
    }

    /**
     * View holder containing a {@link GuidedAction}.
     */
    private static class ActionViewHolder extends ViewHolder {

        private final GuidedActionsStylist.ViewHolder mStylistViewHolder;
        private GuidedAction mAction;

        /**
         * Constructs a view holder that can be associated with a GuidedAction.
         */
        public ActionViewHolder(View v, GuidedActionsStylist.ViewHolder subViewHolder) {
            super(v);
            mStylistViewHolder = subViewHolder;
        }

        /**
         * Retrieves the action associated with this view holder.
         * @return The GuidedAction associated with this view holder.
         */
        public GuidedAction getAction() {
            return mAction;
        }

        /**
         * Sets the action associated with this view holder.
         * @param action The GuidedAction associated with this view holder.
         */
        public void setAction(GuidedAction action) {
            mAction = action;
        }
    }

    private RecyclerView mRecyclerView;
    private final ActionOnKeyListener mActionOnKeyListener;
    private final ActionOnFocusListener mActionOnFocusListener;
    private final ActionEditListener mActionEditListener;
    private final List<GuidedAction> mActions;
    private ClickListener mClickListener;
    private GuidedActionsStylist mStylist;
    private final View.OnClickListener mOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (v != null && v.getWindowToken() != null && mClickListener != null) {
                ActionViewHolder avh = (ActionViewHolder)mRecyclerView.getChildViewHolder(v);
                GuidedAction action = avh.getAction();
                if (action.isEnabled() && !action.infoOnly()) {
                    mClickListener.onGuidedActionClicked(action);
                }
            }
        }
    };
    private boolean mImeOpened;

    /**
     * Constructs a GuidedActionAdapter with the given list of guided actions, the given click and
     * focus listeners, and the given presenter.
     * @param actions The list of guided actions this adapter will manage.
     * @param clickListener The click listener for items in this adapter.
     * @param focusListener The focus listener for items in this adapter.
     * @param presenter The presenter that will manage the display of items in this adapter.
     */
    public GuidedActionAdapter(List<GuidedAction> actions, ClickListener clickListener,
            FocusListener focusListener, EditListener editListener,
            GuidedActionsStylist presenter) {
        super();
        mActions = new ArrayList<GuidedAction>(actions);
        mClickListener = clickListener;
        mStylist = presenter;
        mActionOnKeyListener = new ActionOnKeyListener();
        mActionOnFocusListener = new ActionOnFocusListener(focusListener);
        mActionEditListener = new ActionEditListener(editListener);
    }

    /**
     * Sets the list of actions managed by this adapter.
     * @param actions The list of actions to be managed.
     */
    public void setActions(List<GuidedAction> actions) {
        mActionOnFocusListener.unFocus();
        mActions.clear();
        mActions.addAll(actions);
        notifyDataSetChanged();
    }

    /**
     * Returns the count of actions managed by this adapter.
     * @return The count of actions managed by this adapter.
     */
    public int getCount() {
        return mActions.size();
    }

    /**
     * Returns the GuidedAction at the given position in the managed list.
     * @param position The position of the desired GuidedAction.
     * @return The GuidedAction at the given position.
     */
    public GuidedAction getItem(int position) {
        return mActions.get(position);
    }

    /**
     * Sets the click listener for items managed by this adapter.
     * @param clickListener The click listener for this adapter.
     */
    public void setClickListener(ClickListener clickListener) {
        mClickListener = clickListener;
    }

    /**
     * Sets the focus listener for items managed by this adapter.
     * @param focusListener The focus listener for this adapter.
     */
    public void setFocusListener(FocusListener focusListener) {
        mActionOnFocusListener.setFocusListener(focusListener);
    }

    /**
     * Used for serialization only.
     * @hide
     */
    public List<GuidedAction> getActions() {
        return new ArrayList<GuidedAction>(mActions);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        mRecyclerView = recyclerView;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int getItemViewType(int position) {
        return mStylist.getItemViewType(mActions.get(position));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
        mRecyclerView = null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        GuidedActionsStylist.ViewHolder vh = mStylist.onCreateViewHolder(parent, viewType);
        View v = vh.view;
        v.setOnKeyListener(mActionOnKeyListener);
        v.setOnClickListener(mOnClickListener);
        v.setOnFocusChangeListener(mActionOnFocusListener);

        setupListeners(vh.getEditableTitleView());
        setupListeners(vh.getEditableDescriptionView());

        return new ActionViewHolder(v, vh);
    }

    private void setupListeners(EditText edit) {
        if (edit != null) {
            edit.setPrivateImeOptions("EscapeNorth=1;");
            edit.setOnEditorActionListener(mActionEditListener);
            if (edit instanceof ImeKeyMonitor) {
                ImeKeyMonitor monitor = (ImeKeyMonitor)edit;
                monitor.setImeKeyListener(mActionEditListener);
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        if (position >= mActions.size()) {
            return;
        }
        final ActionViewHolder avh = (ActionViewHolder)holder;
        GuidedAction action = mActions.get(position);
        avh.setAction(action);
        mStylist.onBindViewHolder(avh.mStylistViewHolder, action);

        setupNextImeOptions(avh.mStylistViewHolder.getEditableTitleView());
        setupNextImeOptions(avh.mStylistViewHolder.getEditableDescriptionView());
    }

    private void setupNextImeOptions(EditText edit) {
        if (edit != null) {
            edit.setImeOptions(EditorInfo.IME_ACTION_NEXT);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int getItemCount() {
        return mActions.size();
    }

    private int getNextActionIndex(GuidedAction action, long nextActionId) {
        if (nextActionId == GuidedAction.ACTION_ID_NEXT) {
            int i, size = mActions.size();
            for (i = 0; i < size; i++) {
                GuidedAction a = mActions.get(i);
                if (mActions.get(i) == action) {
                    break;
                }
            }
            do {
                i++;
            } while (i < size && !mActions.get(i).isFocusable());
            return (i == size) ? -1 : i;
        } else {
            int i, size = mActions.size();
            for (i = 0; i < size; i++) {
                GuidedAction a = mActions.get(i);
                if (mActions.get(i).getId() == nextActionId) {
                    break;
                }
            }
            return (i == size) ? -1 : i;
        }
    }

    private class ActionOnFocusListener implements View.OnFocusChangeListener {

        private FocusListener mFocusListener;
        private View mSelectedView;

        ActionOnFocusListener(FocusListener focusListener) {
            mFocusListener = focusListener;
        }

        public void setFocusListener(FocusListener focusListener) {
            mFocusListener = focusListener;
        }

        public void unFocus() {
            if (mSelectedView != null) {
                ViewHolder vh = mRecyclerView.getChildViewHolder(mSelectedView);
                if (vh != null) {
                    ActionViewHolder avh = (ActionViewHolder)vh;
                    mStylist.onAnimateItemFocused(avh.mStylistViewHolder, false);
                } else {
                    Log.w(TAG, "RecyclerView returned null view holder",
                            new Throwable());
                }
            }
        }

        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            ActionViewHolder avh = (ActionViewHolder)mRecyclerView.getChildViewHolder(v);
            if (hasFocus) {
                mSelectedView = v;
                if (mFocusListener != null) {
                    // We still call onGuidedActionFocused so that listeners can clear
                    // state if they want.
                    mFocusListener.onGuidedActionFocused(avh.getAction());
                }
            } else {
                if (mSelectedView == v) {
                    mStylist.onAnimateItemPressedCancelled(avh.mStylistViewHolder);
                    mSelectedView = null;
                }
            }
            mStylist.onAnimateItemFocused(avh.mStylistViewHolder, hasFocus);
        }
    }

    public void openIme(ActionViewHolder avh) {
        mStylist.setEditingMode(avh.mStylistViewHolder,
                avh.getAction(), true);
        mActionEditListener.openIme(avh);
    }

    private class ActionOnKeyListener implements View.OnKeyListener {

        private boolean mKeyPressed = false;

        private void playSound(View v, int soundEffect) {
            if (v.isSoundEffectsEnabled()) {
                Context ctx = v.getContext();
                AudioManager manager = (AudioManager)ctx.getSystemService(Context.AUDIO_SERVICE);
                manager.playSoundEffect(soundEffect);
            }
        }

        /**
         * Now only handles KEYCODE_ENTER and KEYCODE_NUMPAD_ENTER key event.
         */
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (v == null || event == null) {
                return false;
            }
            boolean handled = false;
            switch (keyCode) {
                case KeyEvent.KEYCODE_DPAD_CENTER:
                case KeyEvent.KEYCODE_NUMPAD_ENTER:
                case KeyEvent.KEYCODE_BUTTON_X:
                case KeyEvent.KEYCODE_BUTTON_Y:
                case KeyEvent.KEYCODE_ENTER:

                    ActionViewHolder avh = (ActionViewHolder)mRecyclerView.getChildViewHolder(v);
                    GuidedAction action = avh.getAction();

                    if (!action.isEnabled() || action.infoOnly()) {
                        if (event.getAction() == KeyEvent.ACTION_DOWN) {
                            // TODO: requires API 19
                            //playSound(v, AudioManager.FX_KEYPRESS_INVALID);
                        }
                        return true;
                    }

                    switch (event.getAction()) {
                        case KeyEvent.ACTION_DOWN:
                            if (!mKeyPressed) {
                                mKeyPressed = true;

                                playSound(v, AudioManager.FX_KEY_CLICK);

                                if (DEBUG) {
                                    Log.d(TAG, "Enter Key down");
                                }

                                mStylist.onAnimateItemPressed(avh.mStylistViewHolder,
                                        mKeyPressed);
                                handled = true;
                            }
                            break;
                        case KeyEvent.ACTION_UP:
                            if (mKeyPressed) {
                                mKeyPressed = false;

                                if (DEBUG) {
                                    Log.d(TAG, "Enter Key up");
                                }

                                mStylist.onAnimateItemPressed(avh.mStylistViewHolder, mKeyPressed);
                                if (action.isEditable() || action.isDescriptionEditable()) {
                                    if (DEBUG_EDIT) Log.v(TAG_EDIT, "openIme click");
                                    openIme(avh);
                                } else {
                                    handleCheckedActions(avh, action);
                                    mClickListener.onGuidedActionClicked(action);
                                }
                                handled = true;
                            }
                            break;
                        default:
                            break;
                    }
                    break;
                default:
                    break;
            }
            return handled;
        }

        private void handleCheckedActions(ActionViewHolder avh, GuidedAction action) {
            int actionCheckSetId = action.getCheckSetId();
            if (actionCheckSetId != GuidedAction.NO_CHECK_SET) {
                // Find any actions that are checked and are in the same group
                // as the selected action. Fade their checkmarks out.
                for (int i = 0, size = mActions.size(); i < size; i++) {
                    GuidedAction a = mActions.get(i);
                    if (a != action && a.getCheckSetId() == actionCheckSetId && a.isChecked()) {
                        a.setChecked(false);
                        ViewHolder vh = mRecyclerView.findViewHolderForPosition(i);
                        if (vh != null) {
                            GuidedActionsStylist.ViewHolder subViewHolder =
                                    ((ActionViewHolder)vh).mStylistViewHolder;
                            mStylist.onAnimateItemChecked(subViewHolder, false);
                        }
                    }
                }

                // If we we'ren't already checked, fade our checkmark in.
                if (!action.isChecked()) {
                    action.setChecked(true);
                    mStylist.onAnimateItemChecked(avh.mStylistViewHolder, true);
                }
            }
        }
    }

    private class ActionEditListener implements OnEditorActionListener,
            ImeKeyMonitor.ImeKeyListener {

        private EditListener mEditListener;

        public ActionEditListener(EditListener listener) {
            mEditListener = listener;
        }

        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            if (DEBUG_EDIT) Log.v(TAG_EDIT, "IME action: " + actionId);
            boolean handled = false;
            if (actionId == EditorInfo.IME_ACTION_NEXT ||
                actionId == EditorInfo.IME_ACTION_DONE) {

                ActionViewHolder avh = findSubChildViewHolder(v);
                updateTextIntoAction(avh, v);
                mClickListener.onGuidedActionClicked(avh.getAction());
                long nextActionId = finishEditing(avh);
                if (nextActionId != GuidedAction.ACTION_ID_CURRENT
                        && nextActionId != avh.getAction().getId()) {
                    int next = getNextActionIndex(avh.getAction(), nextActionId);
                    if (next != -1) {
                        ActionViewHolder vh = (ActionViewHolder) mRecyclerView
                                .findViewHolderForPosition(next);
                        if (vh != null) {
                            handled = true;
                            if (vh.getAction().isEditable() ||
                                    vh.getAction().isDescriptionEditable()) {
                                if (DEBUG_EDIT) Log.v(TAG_EDIT, "openIme next/done");
                                mStylist.setEditingMode(vh.mStylistViewHolder,
                                        vh.getAction(), true);
                                // open Ime on next action.
                                openIme(vh);
                            } else {
                                // close IME and focus to next (not editable) action
                                closeIme(v);
                                vh.mStylistViewHolder.view.requestFocus();
                            }
                        }
                    }
                }
                if (!handled) {
                    if (DEBUG_EDIT) Log.v(TAG_EDIT, "closeIme no next action");
                    handled = true;
                    closeIme(v);
                    // requestFocus() otherwise the focus might be stolen by other fragments.
                    avh.mStylistViewHolder.view.requestFocus();
                }
            } else if (actionId == EditorInfo.IME_ACTION_NONE) {
                if (DEBUG_EDIT) Log.v(TAG_EDIT, "closeIme escape north");
                // Escape north handling: stay on current item, but close editor
                handled = true;
                ActionViewHolder avh = findSubChildViewHolder(v);
                finishEditing(avh);
                avh.mStylistViewHolder.view.requestFocus();
                closeIme(v);
            }
            return handled;
        }

        private void updateTextIntoAction(ActionViewHolder avh, TextView v) {
            GuidedAction action = avh.getAction();
            if (v == avh.mStylistViewHolder.getDescriptionView()) {
                if (action.getEditDescription() != null) {
                    action.setEditDescription(v.getText());
                } else {
                    action.setDescription(v.getText());
                }
            } else if (v == avh.mStylistViewHolder.getTitleView()) {
                if (action.getEditTitle() != null) {
                    action.setEditTitle(v.getText());
                } else {
                    action.setTitle(v.getText());
                }
            }
        }

        @Override
        public boolean onKeyPreIme(EditText editText, int keyCode, KeyEvent event) {
            if (DEBUG_EDIT) Log.v(TAG_EDIT, "IME key: " + keyCode);
            if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
                ActionViewHolder avh = findSubChildViewHolder(editText);
                updateTextIntoAction(avh, editText);
                editText.clearFocus();
                finishEditing(avh);
                avh.mStylistViewHolder.view.requestFocus();
                if (mImeOpened) {
                    mImeOpened = false;
                    mEditListener.onImeClose();
                }
            }
            return false;
        }

        public void openIme(ActionViewHolder avh) {
            View v = avh.mStylistViewHolder.getEditingView();
            InputMethodManager mgr = (InputMethodManager)
                    v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            v.requestFocus();
            mgr.showSoftInput(v, 0);
            if (!mImeOpened) {
                mImeOpened = true;
                mEditListener.onImeOpen();
            }
        }

        public long finishEditing(ActionViewHolder avh) {
            long nextActionId = mEditListener.onGuidedActionEdited(avh.getAction());
            mStylist.setEditingMode(avh.mStylistViewHolder, avh.getAction(), false);
            return nextActionId;
        }

        public void closeIme(View v) {
            if (mImeOpened) {
                mImeOpened = false;
                InputMethodManager mgr = (InputMethodManager)
                        v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                v.clearFocus();
                mgr.hideSoftInputFromWindow(v.getWindowToken(), 0);
                mEditListener.onImeClose();
            }
        }

        private ActionViewHolder findSubChildViewHolder(View v) {
            // Needed because RecyclerView.getChildViewHolder does not traverse the hierarchy
            ActionViewHolder result = null;
            ViewParent parent = v.getParent();
            while (parent != mRecyclerView && parent != null && v != null) {
                v = (View)parent;
                parent = parent.getParent();
            }
            if (parent != null && v != null) {
                result = (ActionViewHolder)mRecyclerView.getChildViewHolder(v);
            }
            return result;
        }
    }

}
