/*
 * Copyright (C) 2013 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.view.transition;

import android.util.ArrayMap;
import android.util.Log;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;

import java.util.ArrayList;

/**
 * This class manages the set of transitions that fire when there is a
 * change of {@link Scene}. To use the manager, add scenes along with
 * transition objects with calls to {@link #setTransition(Scene, Transition)}
 * or {@link #setTransition(Scene, Scene, Transition)}. Setting specific
 * transitions for scene changes is not required; by default, a Scene change
 * will use {@link AutoTransition} to do something reasonable for most
 * situations. Specifying other transitions for particular scene changes is
 * only necessary if the application wants different transition behavior
 * in these situations.
 */
public class TransitionManager {
    // TODO: how to handle enter/exit?

    private static String LOG_TAG = "TransitionManager";

    private static final Transition sDefaultTransition = new AutoTransition();
    private Transition mDefaultTransition = new AutoTransition();

    ArrayMap<Scene, Transition> mSceneTransitions = new ArrayMap<Scene, Transition>();
    ArrayMap<Scene, ArrayMap<Scene, Transition>> mScenePairTransitions =
            new ArrayMap<Scene, ArrayMap<Scene, Transition>>();
    static ArrayMap<ViewGroup, Transition> sRunningTransitions =
            new ArrayMap<ViewGroup, Transition>();
    private static ArrayList<ViewGroup> sPendingTransitions = new ArrayList<ViewGroup>();


    /**
     * Sets the transition to be used for any scene change for which no
     * other transition is explicitly set. The initial value is
     * an {@link AutoTransition} instance.
     *
     * @param transition The default transition to be used for scene changes.
     */
    public void setDefaultTransition(Transition transition) {
        mDefaultTransition = transition;
    }

    /**
     * Gets the current default transition. The initial value is an {@link
     * AutoTransition} instance.
     *
     * @return The current default transition.
     * @see #setDefaultTransition(Transition)
     */
    public Transition getDefaultTransition() {
        return mDefaultTransition;
    }

    /**
     * Sets a specific transition to occur when the given scene is entered.
     *
     * @param scene The scene which, when applied, will cause the given
     * transition to run.
     * @param transition The transition that will play when the given scene is
     * entered. A value of null will result in the default behavior of
     * using {@link AutoTransition}.
     */
    public void setTransition(Scene scene, Transition transition) {
        mSceneTransitions.put(scene, transition);
    }

    /**
     * Sets a specific transition to occur when the given pair of scenes is
     * exited/entered.
     *
     * @param fromScene The scene being exited when the given transition will
     * be run
     * @param toScene The scene being entered when the given transition will
     * be run
     * @param transition The transition that will play when the given scene is
     * entered. A value of null will result in the default behavior of
     * using {@link AutoTransition}.
     */
    public void setTransition(Scene fromScene, Scene toScene, Transition transition) {
        ArrayMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(toScene);
        if (sceneTransitionMap == null) {
            sceneTransitionMap = new ArrayMap<Scene, Transition>();
            mScenePairTransitions.put(toScene, sceneTransitionMap);
        }
        sceneTransitionMap.put(fromScene, transition);
    }

    /**
     * Returns the Transition for the given scene being entered. The result
     * depends not only on the given scene, but also the scene which the
     * {@link Scene#getSceneRoot() sceneRoot} of the Scene is currently in.
     *
     * @param scene The scene being entered
     * @return The Transition to be used for the given scene change. If no
     * Transition was specified for this scene change, {@link AutoTransition}
     * will be used instead.
     */
    private Transition getTransition(Scene scene) {
        Transition transition = null;
        ViewGroup sceneRoot = scene.getSceneRoot();
        if (sceneRoot != null) {
            // TODO: cached in Scene instead? long-term, cache in View itself
            Scene currScene = sceneRoot.getCurrentScene();
            if (currScene != null) {
                ArrayMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(scene);
                if (sceneTransitionMap != null) {
                    transition = sceneTransitionMap.get(currScene);
                    if (transition != null) {
                        return transition;
                    }
                }
            }
        }
        transition = mSceneTransitions.get(scene);
        return (transition != null) ? transition : new AutoTransition();
    }

    /**
     * This is where all of the work of a transition/scene-change is
     * orchestrated. This method captures the start values for the given
     * transition, exits the current Scene, enters the new scene, captures
     * the end values for the transition, and finally plays the
     * resulting values-populated transition.
     *
     * @param scene The scene being entered
     * @param transition The transition to play for this scene change
     */
    private static void changeScene(Scene scene, Transition transition) {

        final ViewGroup sceneRoot = scene.getSceneRoot();

        Transition transitionClone = transition.clone();
        transitionClone.setSceneRoot(sceneRoot);

        sceneChangeSetup(sceneRoot, transitionClone);

        scene.enter();

        sceneChangeRunTransition(sceneRoot, transitionClone);
    }

    private static void sceneChangeRunTransition(final ViewGroup sceneRoot,
            final Transition transition) {
        if (transition != null) {
            final ViewTreeObserver observer = sceneRoot.getViewTreeObserver();
            observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                public boolean onPreDraw() {
                    sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
                    sPendingTransitions.remove(sceneRoot);
                    // Add to running list, handle end to remove it
                    sRunningTransitions.put(sceneRoot, transition);
                    transition.addListener(new Transition.TransitionListenerAdapter() {
                        @Override
                        public void onTransitionEnd(Transition transition) {
                            sRunningTransitions.remove(sceneRoot);
                        }
                    });
                    transition.captureValues(sceneRoot, false);
                    transition.playTransition(sceneRoot);
                    return true;
                }
            });
        }
    }

    private static void sceneChangeSetup(ViewGroup sceneRoot, Transition transition) {

        // Capture current values
        Transition runningTransition = sRunningTransitions.get(sceneRoot);

        if (transition != null) {
            transition.captureValues(sceneRoot, true);
        }

        if (runningTransition != null) {
            runningTransition.cancelTransition();
        }

        // Notify previous scene that it is being exited
        Scene previousScene = sceneRoot.getCurrentScene();
        if (previousScene != null) {
            previousScene.exit();
        }
    }

    /**
     * Change to the given scene, using the
     * appropriate transition for this particular scene change
     * (as specified to the TransitionManager, or the default
     * if no such transition exists).
     *
     * @param scene The Scene to change to
     */
    public void transitionTo(Scene scene) {
        // Auto transition if there is no transition declared for the Scene, but there is
        // a root or parent view
        changeScene(scene, getTransition(scene));

    }

    /**
     * Static utility method to simply change to the given scene using
     * the default transition for TransitionManager.
     *
     * @param scene The Scene to change to
     */
    public static void go(Scene scene) {
        changeScene(scene, sDefaultTransition);
    }

    /**
     * Static utility method to simply change to the given scene using
     * the given transition.
     *
     * <p>Passing in <code>null</code> for the transition parameter will
     * result in the scene changing without any transition running, and is
     * equivalent to calling {@link Scene#exit()} on the scene root's
     * {@link ViewGroup#getCurrentScene() current scene}, followed by
     * {@link Scene#enter()} on the scene specified by the <code>scene</code>
     * parameter.</p>
     *
     * @param scene The Scene to change to
     * @param transition The transition to use for this scene change. A
     * value of null causes the scene change to happen with no transition.
     */
    public static void go(Scene scene, Transition transition) {
        changeScene(scene, transition);
    }

    /**
     * Static utility method to simply change to a scene defined by the
     * code in the given runnable, which will be executed after
     * the current values have been captured for the transition.
     * This is equivalent to creating a Scene and calling {@link
     * Scene#setEnterAction(Runnable)} with the runnable, then calling
     * {@link #go(Scene, Transition)}. The transition used will be the
     * default provided by TransitionManager.
     *
     * @param sceneRoot The root of the View hierarchy used when this scene
     * runs a transition automatically.
     * @param action The runnable whose {@link Runnable#run() run()} method will
     * be called.
     */
    public static void go(ViewGroup sceneRoot, Runnable action) {
        Scene scene = new Scene(sceneRoot);
        scene.setEnterAction(action);
        changeScene(scene, sDefaultTransition);
    }

    /**
     * Static utility method to simply change to a scene defined by the
     * code in the given runnable, which will be executed after
     * the current values have been captured for the transition.
     * This is equivalent to creating a Scene and calling {@link
     * Scene#setEnterAction(Runnable)} with the runnable, then calling
     * {@link #go(Scene, Transition)}. The given transition will be
     * used to animate the changes.
     *
     * <p>Passing in <code>null</code> for the transition parameter will
     * result in the scene changing without any transition running, and is
     * equivalent to calling {@link Scene#exit()} on the scene root's
     * {@link ViewGroup#getCurrentScene() current scene}, followed by
     * {@link Scene#enter()} on a new scene specified by the
     * <code>action</code> parameter.</p>
     *
     * @param sceneRoot The root of the View hierarchy to run the transition on.
     * @param action The runnable whose {@link Runnable#run() run()} method will
     * be called.
     * @param transition The transition to use for this change. A
     * value of null causes the change to happen with no transition.
     */
    public static void go(ViewGroup sceneRoot, Runnable action, Transition transition) {
        Scene scene = new Scene(sceneRoot);
        scene.setEnterAction(action);
        changeScene(scene, transition);
    }

    /**
     * Static utility method to animate to a new scene defined by all changes within
     * the given scene root between calling this method and the next rendering frame.
     * Calling this method causes TransitionManager to capture current values in the
     * scene root and then post a request to run a transition on the next frame.
     * At that time, the new values in the scene root will be captured and changes
     * will be animated. There is no need to create a Scene; it is implied by
     * changes which take place between calling this method and the next frame when
     * the transition begins.
     *
     * <p>Calling this method several times before the next frame (for example, if
     * unrelated code also wants to make dynamic changes and run a transition on
     * the same scene root), only the first call will trigger capturing values
     * and exiting the current scene. Subsequent calls to the method with the
     * same scene root during the same frame will be ignored.</p>
     *
     * <p>Passing in <code>null</code> for the transition parameter will
     * cause the TransitionManager to use its default transition.</p>
     *
     * @param sceneRoot The root of the View hierarchy to run the transition on.
     * @param transition The transition to use for this change. A
     * value of null causes the TransitionManager to use the default transition.
     */
    public static void beginDelayedTransition(final ViewGroup sceneRoot, Transition transition) {
        if (!sPendingTransitions.contains(sceneRoot) && sceneRoot.isLaidOut()) {
            if (Transition.DBG) {
                Log.d(LOG_TAG, "beginDelayedTransition: root, transition = " +
                        sceneRoot + ", " + transition);
            }
            sPendingTransitions.add(sceneRoot);
            if (transition == null) {
                transition = sDefaultTransition;
            }
            final Transition finalTransition = transition.clone();
            sceneChangeSetup(sceneRoot, transition);
            sceneRoot.setCurrentScene(null);
            sceneChangeRunTransition(sceneRoot, finalTransition);
        }
    }
}
