/*
 * 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 android.app;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.ResultReceiver;
import android.transition.Transition;
import android.transition.TransitionManager;
import android.util.ArrayMap;
import android.util.Pair;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroupOverlay;
import android.view.ViewTreeObserver;
import android.widget.ImageView;

import java.util.ArrayList;

/**
 * This ActivityTransitionCoordinator is created by the Activity to manage
 * the enter scene and shared element transfer into the Scene, either during
 * launch of an Activity or returning from a launched Activity.
 */
class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
    private static final String TAG = "EnterTransitionCoordinator";

    private static final long MAX_WAIT_MS = 1000;

    private boolean mSharedElementTransitionStarted;
    private Activity mActivity;
    private boolean mHasStopped;
    private Handler mHandler;
    private boolean mIsCanceled;
    private ObjectAnimator mBackgroundAnimator;
    private boolean mIsExitTransitionComplete;

    public EnterTransitionCoordinator(Activity activity, ResultReceiver resultReceiver,
            ArrayList<String> sharedElementNames,
            ArrayList<String> acceptedNames, ArrayList<String> mappedNames) {
        super(activity.getWindow(), sharedElementNames, acceptedNames, mappedNames,
                getListener(activity, acceptedNames), acceptedNames != null);
        mActivity = activity;
        setResultReceiver(resultReceiver);
        prepareEnter();
        Bundle resultReceiverBundle = new Bundle();
        resultReceiverBundle.putParcelable(KEY_REMOTE_RECEIVER, this);
        mResultReceiver.send(MSG_SET_REMOTE_RECEIVER, resultReceiverBundle);
        if (mIsReturning) {
            mHandler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    cancel();
                }
            };
            mHandler.sendEmptyMessageDelayed(MSG_CANCEL, MAX_WAIT_MS);
            send(MSG_SEND_SHARED_ELEMENT_DESTINATION, null);
        }
    }

    private void sendSharedElementDestination() {
        ViewGroup decor = getDecor();
        if (!decor.isLayoutRequested()) {
            Bundle state = captureSharedElementState();
            mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state);
        } else {
            getDecor().getViewTreeObserver()
                    .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                        @Override
                        public boolean onPreDraw() {
                            getDecor().getViewTreeObserver().removeOnPreDrawListener(this);
                            return true;
                        }
                    });
        }
    }

    private static SharedElementListener getListener(Activity activity,
            ArrayList<String> acceptedNames) {
        boolean isReturning = acceptedNames != null;
        return isReturning ? activity.mExitTransitionListener : activity.mEnterTransitionListener;
    }

    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        switch (resultCode) {
            case MSG_TAKE_SHARED_ELEMENTS:
                if (!mIsCanceled) {
                    if (mHandler != null) {
                        mHandler.removeMessages(MSG_CANCEL);
                    }
                    onTakeSharedElements(resultData);
                }
                break;
            case MSG_EXIT_TRANSITION_COMPLETE:
                if (!mIsCanceled) {
                    mIsExitTransitionComplete = true;
                    if (mSharedElementTransitionStarted) {
                        onRemoteExitTransitionComplete();
                    }
                }
                break;
            case MSG_CANCEL:
                cancel();
                break;
            case MSG_SEND_SHARED_ELEMENT_DESTINATION:
                sendSharedElementDestination();
                break;
        }
    }

    private void cancel() {
        if (!mIsCanceled) {
            mIsCanceled = true;
            if (getViewsTransition() == null) {
                setViewVisibility(mSharedElements, View.VISIBLE);
            } else {
                mTransitioningViews.addAll(mSharedElements);
            }
            mSharedElementNames.clear();
            mSharedElements.clear();
            mAllSharedElementNames.clear();
            onTakeSharedElements(null);
            onRemoteExitTransitionComplete();
        }
    }

    public boolean isReturning() {
        return mIsReturning;
    }

    protected void prepareEnter() {
        setViewVisibility(mSharedElements, View.INVISIBLE);
        if (getViewsTransition() != null) {
            setViewVisibility(mTransitioningViews, View.INVISIBLE);
        }
        mActivity.overridePendingTransition(0, 0);
        if (!mIsReturning) {
            mActivity.convertToTranslucent(null, null);
            Drawable background = getDecor().getBackground();
            if (background != null) {
                getWindow().setBackgroundDrawable(null);
                background = background.mutate();
                background.setAlpha(0);
                getWindow().setBackgroundDrawable(background);
            }
        } else {
            mActivity = null; // all done with it now.
        }
    }

    @Override
    protected Transition getViewsTransition() {
        if (mIsReturning) {
            return getWindow().getExitTransition();
        } else {
            return getWindow().getEnterTransition();
        }
    }

    protected Transition getSharedElementTransition() {
        if (mIsReturning) {
            return getWindow().getSharedElementExitTransition();
        } else {
            return getWindow().getSharedElementEnterTransition();
        }
    }

    protected void onTakeSharedElements(Bundle sharedElementState) {
        setEpicenter();
        // Remove rejected shared elements
        ArrayList<String> rejectedNames = new ArrayList<String>(mAllSharedElementNames);
        rejectedNames.removeAll(mSharedElementNames);
        ArrayList<View> rejectedSnapshots = createSnapshots(sharedElementState, rejectedNames);
        mListener.handleRejectedSharedElements(rejectedSnapshots);
        startRejectedAnimations(rejectedSnapshots);

        // Now start shared element transition
        ArrayList<View> sharedElementSnapshots = createSnapshots(sharedElementState,
                mSharedElementNames);
        setViewVisibility(mSharedElements, View.VISIBLE);
        ArrayMap<ImageView, Pair<ImageView.ScaleType, Matrix>> originalImageViewState =
                setSharedElementState(sharedElementState, sharedElementSnapshots);
        requestLayoutForSharedElements();

        boolean startEnterTransition = allowOverlappingTransitions();
        boolean startSharedElementTransition = true;
        Transition transition = beginTransition(startEnterTransition, startSharedElementTransition);

        if (startEnterTransition) {
            startEnterTransition(transition);
        }

        setOriginalImageViewState(originalImageViewState);

        if (mResultReceiver != null) {
            mResultReceiver.send(MSG_HIDE_SHARED_ELEMENTS, null);
        }
        mResultReceiver = null; // all done sending messages.
    }

    private void requestLayoutForSharedElements() {
        int numSharedElements = mSharedElements.size();
        for (int i = 0; i < numSharedElements; i++) {
            mSharedElements.get(i).requestLayout();
        }
    }

    private Transition beginTransition(boolean startEnterTransition,
            boolean startSharedElementTransition) {
        Transition sharedElementTransition = null;
        if (startSharedElementTransition && !mSharedElementNames.isEmpty()) {
            sharedElementTransition = configureTransition(getSharedElementTransition());
        }
        Transition viewsTransition = null;
        if (startEnterTransition && !mTransitioningViews.isEmpty()) {
            viewsTransition = configureTransition(getViewsTransition());
            viewsTransition = addTargets(viewsTransition, mTransitioningViews);
        }

        Transition transition = mergeTransitions(sharedElementTransition, viewsTransition);
        if (startSharedElementTransition) {
            if (transition == null) {
                sharedElementTransitionStarted();
            } else {
                transition.addListener(new Transition.TransitionListenerAdapter() {
                    @Override
                    public void onTransitionStart(Transition transition) {
                        transition.removeListener(this);
                        sharedElementTransitionStarted();
                    }
                });
            }
        }
        if (transition != null) {
            TransitionManager.beginDelayedTransition(getDecor(), transition);
            if (startSharedElementTransition && !mSharedElementNames.isEmpty()) {
                mSharedElements.get(0).invalidate();
            } else if (startEnterTransition && !mTransitioningViews.isEmpty()) {
                mTransitioningViews.get(0).invalidate();
            }
        }
        return transition;
    }

    private void sharedElementTransitionStarted() {
        mSharedElementTransitionStarted = true;
        if (mIsExitTransitionComplete) {
            send(MSG_EXIT_TRANSITION_COMPLETE, null);
        }
    }

    private void startEnterTransition(Transition transition) {
        setViewVisibility(mTransitioningViews, View.VISIBLE);
        if (!mIsReturning) {
            Drawable background = getDecor().getBackground();
            if (background != null) {
                background = background.mutate();
                mBackgroundAnimator = ObjectAnimator.ofInt(background, "alpha", 255);
                mBackgroundAnimator.setDuration(FADE_BACKGROUND_DURATION_MS);
                mBackgroundAnimator.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        makeOpaque();
                    }
                });
                mBackgroundAnimator.start();
            } else if (transition != null) {
                transition.addListener(new Transition.TransitionListenerAdapter() {
                    @Override
                    public void onTransitionEnd(Transition transition) {
                        transition.removeListener(this);
                        makeOpaque();
                    }
                });
            } else {
                makeOpaque();
            }
        }
    }

    public void stop() {
        mHasStopped = true;
        mActivity = null;
        mIsCanceled = true;
        mResultReceiver = null;
        if (mBackgroundAnimator != null) {
            mBackgroundAnimator.cancel();
            mBackgroundAnimator = null;
        }
    }

    private void makeOpaque() {
        if (!mHasStopped) {
            mActivity.convertFromTranslucent();
            mActivity = null;
        }
    }

    private boolean allowOverlappingTransitions() {
        return mIsReturning ? getWindow().getAllowExitTransitionOverlap()
                : getWindow().getAllowEnterTransitionOverlap();
    }

    private void startRejectedAnimations(final ArrayList<View> rejectedSnapshots) {
        if (rejectedSnapshots == null || rejectedSnapshots.isEmpty()) {
            return;
        }
        ViewGroupOverlay overlay = getDecor().getOverlay();
        ObjectAnimator animator = null;
        int numRejected = rejectedSnapshots.size();
        for (int i = 0; i < numRejected; i++) {
            View snapshot = rejectedSnapshots.get(i);
            overlay.add(snapshot);
            animator = ObjectAnimator.ofFloat(snapshot, View.ALPHA, 1, 0);
            animator.start();
        }
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                ViewGroupOverlay overlay = getDecor().getOverlay();
                int numRejected = rejectedSnapshots.size();
                for (int i = 0; i < numRejected; i++) {
                    overlay.remove(rejectedSnapshots.get(i));
                }
            }
        });
    }

    protected void onRemoteExitTransitionComplete() {
        if (!allowOverlappingTransitions()) {
            boolean startEnterTransition = true;
            boolean startSharedElementTransition = false;
            Transition transition = beginTransition(startEnterTransition,
                    startSharedElementTransition);
            startEnterTransition(transition);
        }
    }
}
