/*
 * 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.animation.Animator;
import android.animation.AnimatorInflater;
import android.support.annotation.IntDef;
import android.transition.Fade;
import android.transition.Scene;
import android.transition.Transition;
import android.transition.TransitionInflater;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.transition.TransitionValues;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.FrameLayout.LayoutParams;
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.data.api.Channel;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

public class TvTransitionManager extends TransitionManager {
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({
        SCENE_TYPE_EMPTY,
        SCENE_TYPE_CHANNEL_BANNER,
        SCENE_TYPE_INPUT_BANNER,
        SCENE_TYPE_KEYPAD_CHANNEL_SWITCH,
        SCENE_TYPE_SELECT_INPUT
    })
    public @interface SceneType {}

    public static final int SCENE_TYPE_EMPTY = 0;
    public static final int SCENE_TYPE_CHANNEL_BANNER = 1;
    public static final int SCENE_TYPE_INPUT_BANNER = 2;
    public static final int SCENE_TYPE_KEYPAD_CHANNEL_SWITCH = 3;
    public static final int SCENE_TYPE_SELECT_INPUT = 4;

    private final MainActivity mMainActivity;
    private final ViewGroup mSceneContainer;
    private final ChannelBannerView mChannelBannerView;
    private final InputBannerViewBase mInputBannerView;
    private final KeypadChannelSwitchView mKeypadChannelSwitchView;
    private final SelectInputView mSelectInputView;
    private final FrameLayout mEmptyView;
    private ViewGroup mCurrentSceneView;
    private Animator mEnterAnimator;
    private Animator mExitAnimator;

    private boolean mInitialized;
    private Scene mEmptyScene;
    private Scene mChannelBannerScene;
    private Scene mInputBannerScene;
    private Scene mKeypadChannelSwitchScene;
    private Scene mSelectInputScene;
    private Scene mCurrentScene;

    private Listener mListener;

    public TvTransitionManager(
            MainActivity mainActivity,
            ViewGroup sceneContainer,
            ChannelBannerView channelBannerView,
            InputBannerViewBase inputBannerView,
            KeypadChannelSwitchView keypadChannelSwitchView,
            SelectInputView selectInputView) {
        mMainActivity = mainActivity;
        mSceneContainer = sceneContainer;
        mChannelBannerView = channelBannerView;
        mInputBannerView = inputBannerView;
        mKeypadChannelSwitchView = keypadChannelSwitchView;
        mSelectInputView = selectInputView;
        mEmptyView =
                (FrameLayout)
                        mMainActivity
                                .getLayoutInflater()
                                .inflate(R.layout.empty_info_banner, sceneContainer, false);
        mCurrentSceneView = mEmptyView;
    }

    public void goToEmptyScene(boolean withAnimation) {
        if (mCurrentScene == mEmptyScene) {
            return;
        }
        initIfNeeded();
        if (withAnimation) {
            mEmptyView.setAlpha(1.0f);
            transitionTo(mEmptyScene);
        } else {
            TransitionManager.go(mEmptyScene, null);
            // When transition is null, transition got stuck without calling endTransitions.
            TransitionManager.endTransitions(mEmptyScene.getSceneRoot());
            // Since Fade.OUT transition doesn't run, we need to set alpha manually.
            mEmptyView.setAlpha(0);
        }
    }

    public void goToChannelBannerScene() {
        initIfNeeded();
        Channel channel = mMainActivity.getCurrentChannel();
        if (channel != null && channel.isPassthrough()) {
            if (mCurrentScene != mInputBannerScene) {
                // Show the input banner instead.
                LayoutParams lp = (LayoutParams) mInputBannerView.getLayoutParams();
                lp.width =
                        mCurrentScene == mSelectInputScene
                                ? mSelectInputView.getWidth()
                                : FrameLayout.LayoutParams.WRAP_CONTENT;
                mInputBannerView.setLayoutParams(lp);
                mInputBannerView.updateLabel();
                transitionTo(mInputBannerScene);
            }
        } else if (mCurrentScene != mChannelBannerScene) {
            transitionTo(mChannelBannerScene);
        }
    }

    public void goToKeypadChannelSwitchScene() {
        initIfNeeded();
        if (mCurrentScene != mKeypadChannelSwitchScene) {
            transitionTo(mKeypadChannelSwitchScene);
        }
    }

    public void goToSelectInputScene() {
        initIfNeeded();
        if (mCurrentScene != mSelectInputScene) {
            mSelectInputView.setCurrentChannel(mMainActivity.getCurrentChannel());
            transitionTo(mSelectInputScene);
        }
    }

    public boolean isSceneActive() {
        return mCurrentScene != mEmptyScene;
    }

    public boolean isKeypadChannelSwitchActive() {
        return mCurrentScene != null && mCurrentScene == mKeypadChannelSwitchScene;
    }

    public boolean isSelectInputActive() {
        return mCurrentScene != null && mCurrentScene == mSelectInputScene;
    }

    public boolean isInputBannerActive() {
        return mCurrentScene != null && mCurrentScene == mInputBannerScene;
    }

    public void setListener(Listener listener) {
        mListener = listener;
    }

    public void initIfNeeded() {
        if (mInitialized) {
            return;
        }
        mEnterAnimator =
                AnimatorInflater.loadAnimator(mMainActivity, R.animator.channel_banner_enter);
        mExitAnimator =
                AnimatorInflater.loadAnimator(mMainActivity, R.animator.channel_banner_exit);

        mEmptyScene = new Scene(mSceneContainer, (View) mEmptyView);
        mEmptyScene.setEnterAction(
                () -> {
                    FrameLayout.LayoutParams emptySceneLayoutParams =
                            (FrameLayout.LayoutParams) mEmptyView.getLayoutParams();
                    ViewGroup.MarginLayoutParams lp =
                            (ViewGroup.MarginLayoutParams) mCurrentSceneView.getLayoutParams();
                    emptySceneLayoutParams.topMargin = mCurrentSceneView.getTop();
                    emptySceneLayoutParams.setMarginStart(lp.getMarginStart());
                    emptySceneLayoutParams.height = mCurrentSceneView.getHeight();
                    emptySceneLayoutParams.width = mCurrentSceneView.getWidth();
                    mEmptyView.setLayoutParams(emptySceneLayoutParams);
                    setCurrentScene(mEmptyScene, mEmptyView);
                });
        mEmptyScene.setExitAction(this::removeAllViewsFromOverlay);

        mChannelBannerScene = buildScene(mSceneContainer, mChannelBannerView);
        mInputBannerScene = buildScene(mSceneContainer, mInputBannerView);
        mKeypadChannelSwitchScene = buildScene(mSceneContainer, mKeypadChannelSwitchView);
        mSelectInputScene = buildScene(mSceneContainer, mSelectInputView);
        mCurrentScene = mEmptyScene;

        // Enter transitions
        TransitionSet enter =
                new TransitionSet()
                        .addTransition(new SceneTransition(SceneTransition.ENTER))
                        .addTransition(new Fade(Fade.IN));
        setTransition(mEmptyScene, mChannelBannerScene, enter);
        setTransition(mEmptyScene, mInputBannerScene, enter);
        setTransition(mEmptyScene, mKeypadChannelSwitchScene, enter);
        setTransition(mEmptyScene, mSelectInputScene, enter);

        // Exit transitions
        TransitionSet exit =
                new TransitionSet()
                        .addTransition(new SceneTransition(SceneTransition.EXIT))
                        .addTransition(new Fade(Fade.OUT));
        setTransition(mChannelBannerScene, mEmptyScene, exit);
        setTransition(mInputBannerScene, mEmptyScene, exit);
        setTransition(mKeypadChannelSwitchScene, mEmptyScene, exit);
        setTransition(mSelectInputScene, mEmptyScene, exit);

        // All other possible transitions between scenes
        TransitionInflater ti = TransitionInflater.from(mMainActivity);
        Transition transition = ti.inflateTransition(R.transition.transition_between_scenes);
        setTransition(mChannelBannerScene, mKeypadChannelSwitchScene, transition);
        setTransition(mChannelBannerScene, mSelectInputScene, transition);
        setTransition(mInputBannerScene, mSelectInputScene, transition);
        setTransition(mKeypadChannelSwitchScene, mChannelBannerScene, transition);
        setTransition(mKeypadChannelSwitchScene, mSelectInputScene, transition);
        setTransition(mSelectInputScene, mChannelBannerScene, transition);
        setTransition(mSelectInputScene, mInputBannerScene, transition);

        mInitialized = true;
    }

    /** Returns the type of the given scene. */
    @SceneType
    public int getSceneType(Scene scene) {
        if (scene == mChannelBannerScene) {
            return SCENE_TYPE_CHANNEL_BANNER;
        } else if (scene == mInputBannerScene) {
            return SCENE_TYPE_INPUT_BANNER;
        } else if (scene == mKeypadChannelSwitchScene) {
            return SCENE_TYPE_KEYPAD_CHANNEL_SWITCH;
        } else if (scene == mSelectInputScene) {
            return SCENE_TYPE_SELECT_INPUT;
        }
        return SCENE_TYPE_EMPTY;
    }

    private void setCurrentScene(Scene scene, ViewGroup sceneView) {
        if (mListener != null) {
            mListener.onSceneChanged(getSceneType(mCurrentScene), getSceneType(scene));
        }
        mCurrentScene = scene;
        mCurrentSceneView = sceneView;
        // TODO: Is this a still valid call?
        mMainActivity.updateKeyInputFocus();
    }

    public interface TransitionLayout {
        // TODO: remove the parameter fromEmptyScene once a bug regarding transition alpha
        // is fixed. The bug is that the transition alpha is not reset after the transition is
        // canceled.
        void onEnterAction(boolean fromEmptyScene);

        void onExitAction();
    }

    private Scene buildScene(ViewGroup sceneRoot, final TransitionLayout layout) {
        final Scene scene = new Scene(sceneRoot, (View) layout);
        scene.setEnterAction(
                () -> {
                    boolean wasEmptyScene = (mCurrentScene == mEmptyScene);
                    setCurrentScene(scene, (ViewGroup) layout);
                    layout.onEnterAction(wasEmptyScene);
                });
        scene.setExitAction(
                () -> {
                    removeAllViewsFromOverlay();
                    layout.onExitAction();
                });
        return scene;
    }

    private void removeAllViewsFromOverlay() {
        // Clean up all the animations which can be still running.
        mSceneContainer.getOverlay().remove(mChannelBannerView);
        mSceneContainer.getOverlay().remove(mInputBannerView);
        mSceneContainer.getOverlay().remove(mKeypadChannelSwitchView);
        mSceneContainer.getOverlay().remove(mSelectInputView);
    }

    private class SceneTransition extends Transition {
        static final int ENTER = 0;
        static final int EXIT = 1;

        private final Animator mAnimator;

        SceneTransition(int mode) {
            mAnimator = mode == ENTER ? mEnterAnimator : mExitAnimator;
        }

        @Override
        public void captureStartValues(TransitionValues transitionValues) {}

        @Override
        public void captureEndValues(TransitionValues transitionValues) {}

        @Override
        public Animator createAnimator(
                ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues) {
            Animator animator = mAnimator.clone();
            animator.setTarget(sceneRoot);
            animator.addListener(new HardwareLayerAnimatorListenerAdapter(sceneRoot));
            return animator;
        }
    }

    /** An interface for notification of the scene transition. */
    public interface Listener {
        /**
         * Called when the scene changes. This method is called just before the scene transition.
         */
        void onSceneChanged(@SceneType int fromSceneType, @SceneType int toSceneType);
    }
}
