/*
 * 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 com.android.tv.ui;

import android.content.Context;
import android.content.res.Resources;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.media.tv.TvInputManager.TvInputCallback;
import android.support.annotation.NonNull;
import android.support.v17.leanback.widget.VerticalGridView;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.android.tv.ApplicationSingletons;
import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.analytics.DurationTimer;
import com.android.tv.analytics.Tracker;
import com.android.tv.data.Channel;
import com.android.tv.util.TvInputManagerHelper;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SelectInputView extends VerticalGridView implements
        TvTransitionManager.TransitionLayout {
    private static final String TAG = "SelectInputView";
    private static final boolean DEBUG = false;
    public static final String SCREEN_NAME = "Input selection";
    private static final int TUNER_INPUT_POSITION = 0;

    private final TvInputManagerHelper mTvInputManagerHelper;
    private final List<TvInputInfo> mInputList = new ArrayList<>();
    private final InputsComparator mComparator = new InputsComparator();
    private final Tracker mTracker;
    private final DurationTimer mViewDurationTimer = new DurationTimer();
    private final TvInputCallback mTvInputCallback = new TvInputCallback() {
        @Override
        public void onInputAdded(String inputId) {
            buildInputListAndNotify();
            updateSelectedPositionIfNeeded();
        }

        @Override
        public void onInputRemoved(String inputId) {
            buildInputListAndNotify();
            updateSelectedPositionIfNeeded();
        }

        @Override
        public void onInputUpdated(String inputId) {
            buildInputListAndNotify();
            updateSelectedPositionIfNeeded();
        }

        @Override
        public void onInputStateChanged(String inputId, int state) {
            buildInputListAndNotify();
            updateSelectedPositionIfNeeded();
        }

        private void updateSelectedPositionIfNeeded() {
            if (!isFocusable() || mSelectedInput == null) {
                return;
            }
            if (!isInputEnabled(mSelectedInput)) {
                setSelectedPosition(TUNER_INPUT_POSITION);
                return;
            }
            if (getInputPosition(mSelectedInput.getId()) != getSelectedPosition()) {
                setSelectedPosition(getInputPosition(mSelectedInput.getId()));
            }
        }
    };

    private Channel mCurrentChannel;
    private OnInputSelectedCallback mCallback;

    private final Runnable mHideRunnable = new Runnable() {
        @Override
        public void run() {
            if (mSelectedInput == null) {
                return;
            }
            // TODO: pass english label to tracker http://b/22355024
            final String label = mSelectedInput.loadLabel(getContext()).toString();
            mTracker.sendInputSelected(label);
            if (mCallback != null) {
                if (mSelectedInput.isPassthroughInput()) {
                    mCallback.onPassthroughInputSelected(mSelectedInput);
                } else {
                    mCallback.onTunerInputSelected();
                }
            }
        }
    };

    private final int mInputItemHeight;
    private final long mShowDurationMillis;
    private final long mRippleAnimDurationMillis;
    private final int mTextColorPrimary;
    private final int mTextColorSecondary;
    private final int mTextColorDisabled;
    private final View mItemViewForMeasure;

    private boolean mResetTransitionAlpha;
    private TvInputInfo mSelectedInput;
    private int mMaxItemWidth;

    public SelectInputView(Context context) {
        this(context, null, 0);
    }

    public SelectInputView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SelectInputView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setAdapter(new InputListAdapter());

        ApplicationSingletons appSingletons = TvApplication.getSingletons(context);
        mTracker = appSingletons.getTracker();
        mTvInputManagerHelper = appSingletons.getTvInputManagerHelper();

        Resources resources = context.getResources();
        mInputItemHeight = resources.getDimensionPixelSize(R.dimen.input_banner_item_height);
        mShowDurationMillis = resources.getInteger(R.integer.select_input_show_duration);
        mRippleAnimDurationMillis = resources.getInteger(
                R.integer.select_input_ripple_anim_duration);
        mTextColorPrimary = resources.getColor(R.color.select_input_text_color_primary, null);
        mTextColorSecondary = resources.getColor(R.color.select_input_text_color_secondary, null);
        mTextColorDisabled = resources.getColor(R.color.select_input_text_color_disabled, null);

        mItemViewForMeasure = LayoutInflater.from(context).inflate(
                R.layout.select_input_item, this, false);
        buildInputListAndNotify();
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (DEBUG) Log.d(TAG, "onKeyUp(keyCode=" + keyCode + ", event=" + event + ")");
        scheduleHide();

        if (keyCode == KeyEvent.KEYCODE_TV_INPUT) {
            // Go down to the next available input.
            int currentPosition = mInputList.indexOf(mSelectedInput);
            int nextPosition = currentPosition;
            while (true) {
                nextPosition = (nextPosition + 1) % mInputList.size();
                if (isInputEnabled(mInputList.get(nextPosition))) {
                    break;
                }
                if (nextPosition == currentPosition) {
                    nextPosition = 0;
                    break;
                }
            }
            setSelectedPosition(nextPosition);
            return true;
        }
        return super.onKeyUp(keyCode, event);
    }

    @Override
    public void onEnterAction(boolean fromEmptyScene) {
        mTracker.sendShowInputSelection();
        mTracker.sendScreenView(SCREEN_NAME);
        mViewDurationTimer.start();
        scheduleHide();

        mResetTransitionAlpha = fromEmptyScene;
        buildInputListAndNotify();
        mTvInputManagerHelper.addCallback(mTvInputCallback);
        String currentInputId = mCurrentChannel != null && mCurrentChannel.isPassthrough() ?
                mCurrentChannel.getInputId() : null;
        if (currentInputId != null
                && !isInputEnabled(mTvInputManagerHelper.getTvInputInfo(currentInputId))) {
            // If current input is disabled, the tuner input will be focused.
            setSelectedPosition(TUNER_INPUT_POSITION);
        } else {
            setSelectedPosition(getInputPosition(currentInputId));
        }
        setFocusable(true);
        requestFocus();
    }

    private int getInputPosition(String inputId) {
        if (inputId != null) {
            for (int i = 0; i < mInputList.size(); ++i) {
                if (TextUtils.equals(mInputList.get(i).getId(), inputId)) {
                    return i;
                }
            }
        }
        return TUNER_INPUT_POSITION;
    }

    @Override
    public void onExitAction() {
        mTracker.sendHideInputSelection(mViewDurationTimer.reset());
        mTvInputManagerHelper.removeCallback(mTvInputCallback);
        removeCallbacks(mHideRunnable);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int height = mInputItemHeight * mInputList.size();
        super.onMeasure(MeasureSpec.makeMeasureSpec(mMaxItemWidth, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
    }

    private void scheduleHide() {
        removeCallbacks(mHideRunnable);
        postDelayed(mHideRunnable, mShowDurationMillis);
    }

    private void buildInputListAndNotify() {
        mInputList.clear();
        Map<String, TvInputInfo> inputMap = new HashMap<>();
        boolean foundTuner = false;
        for (TvInputInfo input : mTvInputManagerHelper.getTvInputInfos(false, false)) {
            if (input.isPassthroughInput()) {
                if (!input.isHidden(getContext())) {
                    mInputList.add(input);
                    inputMap.put(input.getId(), input);
                }
            } else if (!foundTuner) {
                foundTuner = true;
                mInputList.add(input);
            }
        }
        // Do not show HDMI ports if a CEC device is directly connected to the port.
        for (TvInputInfo input : inputMap.values()) {
            if (input.getParentId() != null && !input.isConnectedToHdmiSwitch()) {
                mInputList.remove(inputMap.get(input.getParentId()));
            }
        }
        Collections.sort(mInputList, mComparator);

        // Update the max item width.
        mMaxItemWidth = 0;
        for (TvInputInfo input : mInputList) {
            setItemViewText(mItemViewForMeasure, input);
            mItemViewForMeasure.measure(0, 0);
            int width = mItemViewForMeasure.getMeasuredWidth();
            if (width > mMaxItemWidth) {
                mMaxItemWidth = width;
            }
        }

        getAdapter().notifyDataSetChanged();
    }

    private void setItemViewText(View v, TvInputInfo input) {
        TextView inputLabelView = (TextView) v.findViewById(R.id.input_label);
        TextView secondaryInputLabelView = (TextView) v.findViewById(R.id.secondary_input_label);
        CharSequence customLabel = input.loadCustomLabel(getContext());
        CharSequence label = input.loadLabel(getContext());
        if (TextUtils.isEmpty(customLabel) || customLabel.equals(label)) {
            inputLabelView.setText(label);
            secondaryInputLabelView.setVisibility(View.GONE);
        } else {
            inputLabelView.setText(customLabel);
            secondaryInputLabelView.setText(label);
            secondaryInputLabelView.setVisibility(View.VISIBLE);
        }
    }

    private boolean isInputEnabled(TvInputInfo input) {
        return mTvInputManagerHelper.getInputState(input)
                != TvInputManager.INPUT_STATE_DISCONNECTED;
    }

    /**
     * Sets a callback which receives the notifications of input selection.
     */
    public void setOnInputSelectedCallback(OnInputSelectedCallback callback) {
        mCallback = callback;
    }

    /**
     * Sets the current channel. The initial selection will be the input which contains the
     * {@code channel}.
     */
    public void setCurrentChannel(Channel channel) {
        mCurrentChannel = channel;
    }

    class InputListAdapter extends RecyclerView.Adapter<InputListAdapter.ViewHolder> {
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View v = LayoutInflater.from(parent.getContext()).inflate(
                    R.layout.select_input_item, parent, false);
            return new ViewHolder(v);
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, final int position) {
            TvInputInfo input = mInputList.get(position);
            if (input.isPassthroughInput()) {
                if (isInputEnabled(input)) {
                    holder.itemView.setFocusable(true);
                    holder.inputLabelView.setTextColor(mTextColorPrimary);
                    holder.secondaryInputLabelView.setTextColor(mTextColorSecondary);
                } else {
                    holder.itemView.setFocusable(false);
                    holder.inputLabelView.setTextColor(mTextColorDisabled);
                    holder.secondaryInputLabelView.setTextColor(mTextColorDisabled);
                }
                setItemViewText(holder.itemView, input);
            } else {
                holder.itemView.setFocusable(true);
                holder.inputLabelView.setTextColor(mTextColorPrimary);
                holder.inputLabelView.setText(R.string.input_long_label_for_tuner);
                holder.secondaryInputLabelView.setVisibility(View.GONE);
            }

            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mSelectedInput = mInputList.get(position);
                    // The user made a selection. Hide this view after the ripple animation. But
                    // first, disable focus to avoid any further focus change during the animation.
                    setFocusable(false);
                    removeCallbacks(mHideRunnable);
                    postDelayed(mHideRunnable, mRippleAnimDurationMillis);
                }
            });
            holder.itemView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                @Override
                public void onFocusChange(View view, boolean hasFocus) {
                    if (hasFocus) {
                        mSelectedInput = mInputList.get(position);
                    }
                }
            });

            if (mResetTransitionAlpha) {
                ViewUtils.setTransitionAlpha(holder.itemView, 1f);
            }
        }

        @Override
        public int getItemCount() {
            return mInputList.size();
        }

        class ViewHolder extends RecyclerView.ViewHolder {
            final TextView inputLabelView;
            final TextView secondaryInputLabelView;

            ViewHolder(View v) {
                super(v);
                inputLabelView = (TextView) v.findViewById(R.id.input_label);
                secondaryInputLabelView = (TextView) v.findViewById(R.id.secondary_input_label);
            }
        }
    }

    private class InputsComparator implements Comparator<TvInputInfo> {
        @Override
        public int compare(TvInputInfo lhs, TvInputInfo rhs) {
            if (lhs == null) {
                return (rhs == null) ? 0 : 1;
            }
            if (rhs == null) {
                return -1;
            }

            boolean enabledL = isInputEnabled(lhs);
            boolean enabledR = isInputEnabled(rhs);
            if (enabledL != enabledR) {
                return enabledL ? -1 : 1;
            }

            int priorityL = getPriority(lhs);
            int priorityR = getPriority(rhs);
            if (priorityL != priorityR) {
                return priorityR - priorityL;
            }

            String customLabelL = (String) lhs.loadCustomLabel(getContext());
            String customLabelR = (String) rhs.loadCustomLabel(getContext());
            if (!TextUtils.equals(customLabelL, customLabelR)) {
                customLabelL = customLabelL == null ? "" : customLabelL;
                customLabelR = customLabelR == null ? "" : customLabelR;
                return customLabelL.compareToIgnoreCase(customLabelR);
            }

            String labelL = (String) lhs.loadLabel(getContext());
            String labelR = (String) rhs.loadLabel(getContext());
            labelL = labelL == null ? "" : labelL;
            labelR = labelR == null ? "" : labelR;
            return labelL.compareToIgnoreCase(labelR);
        }

        private int getPriority(TvInputInfo info) {
            switch (info.getType()) {
                case TvInputInfo.TYPE_TUNER:
                    return 9;
                case TvInputInfo.TYPE_HDMI:
                    HdmiDeviceInfo hdmiInfo = info.getHdmiDeviceInfo();
                    if (hdmiInfo != null && hdmiInfo.isCecDevice()) {
                        return 8;
                    }
                    return 7;
                case TvInputInfo.TYPE_DVI:
                    return 6;
                case TvInputInfo.TYPE_COMPONENT:
                    return 5;
                case TvInputInfo.TYPE_SVIDEO:
                    return 4;
                case TvInputInfo.TYPE_COMPOSITE:
                    return 3;
                case TvInputInfo.TYPE_DISPLAY_PORT:
                    return 2;
                case TvInputInfo.TYPE_VGA:
                    return 1;
                case TvInputInfo.TYPE_SCART:
                default:
                    return 0;
            }
        }
    }

    /**
     * A callback interface for the input selection.
     */
    public interface OnInputSelectedCallback {
        /**
         * Called when the tuner input is selected.
         */
        void onTunerInputSelected();

        /**
         * Called when the passthrough input is selected.
         */
        void onPassthroughInputSelected(@NonNull TvInputInfo input);
    }
}
