package com.yc.cn.ycgallery.animations;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.app.Activity;
import android.graphics.Matrix;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.widget.ImageView;



public class ExitScreenAnimations extends ScreenAnimation{

    private static final String TAG = ExitScreenAnimations.class.getSimpleName();


    private final ImageView mAnimatedImage;
    private final View mImageTo;
    private final View mMainContainer;

    /**
     * These values represent the final position of a Image that is translated
     */
    private int mToTop;
    private int mToLeft;
    private int mToWidth;
    private int mToHeight;

    private AnimatorSet mExitingAnimation;

    private float[] mToThumbnailMatrixValues;

    public ExitScreenAnimations(ImageView animatedImage, View imageTo, View mainContainer) {
        super(animatedImage.getContext());
        mAnimatedImage = animatedImage;
        mImageTo = imageTo;
        mMainContainer = mainContainer;
    }

    public void playExitAnimations(int toTop, int toLeft, int toWidth, int toHeight, float[] toThumbnailMatrixValues) {
        mToTop = toTop;
        mToLeft = toLeft;
        mToWidth = toWidth;
        mToHeight = toHeight;

        mToThumbnailMatrixValues = toThumbnailMatrixValues;

        Log.v(TAG, "playExitAnimations, mExitingAnimation " + mExitingAnimation);
        if (mExitingAnimation == null) {
            playExitingAnimation();
        }
    }

    private void playExitingAnimation() {
        Log.v(TAG, "playExitingAnimation");

        mAnimatedImage.setVisibility(View.VISIBLE);
        mImageTo.setVisibility(View.INVISIBLE);

        AnimatorSet imageAnimatorSet = createExitingImageAnimation();

        Animator mainContainerFadeAnimator = createExitingFadeAnimator();

        mExitingAnimation = new AnimatorSet();
        mExitingAnimation.setDuration(IMAGE_TRANSLATION_DURATION);
        mExitingAnimation.setInterpolator(new AccelerateInterpolator());
        mExitingAnimation.addListener(new SimpleAnimationListener() {

            @Override
            public void onAnimationEnd(Animator animation) {


                Log.v(TAG, "onAnimationEnd, mExitingAnimation " + mExitingAnimation);
                mExitingAnimation = null;

                // finish the activity when animation is finished
                Activity activity = (Activity) mAnimatedImage.getContext();
                activity.finish();
                activity.overridePendingTransition(0, 0);
            }
        });

        mExitingAnimation.playTogether(
                imageAnimatorSet,
                mainContainerFadeAnimator
        );

        mExitingAnimation.start();
    }

    /**
     * This method creates an animator set of 2 animations:
     * 1. ImageView position animation when screen is closed
     * 2. ImageView image matrix animation when screen is closed
     */
    private AnimatorSet createExitingImageAnimation() {
        Log.v(TAG, ">> createExitingImageAnimation");

        ObjectAnimator positionAnimator = createExitingImagePositionAnimator();
        ObjectAnimator matrixAnimator = createExitingImageMatrixAnimator();

        AnimatorSet exitingImageAnimation = new AnimatorSet();
        exitingImageAnimation.playTogether(positionAnimator, matrixAnimator);

        Log.v(TAG, "<< createExitingImageAnimation");
        return exitingImageAnimation;
    }

    /**
     * This method creates an animator that changes ImageView position on the screen.
     * It will look like view is translated from its position on this screen to its position on previous screen
     */
    @NonNull
    private ObjectAnimator createExitingImagePositionAnimator() {

        // get initial location on the screen and start animation from there
        int[] locationOnScreen = new int[2];
        mAnimatedImage.getLocationOnScreen(locationOnScreen);

        PropertyValuesHolder propertyLeft = PropertyValuesHolder.ofInt("left",
                locationOnScreen[0],
                mToLeft);

        PropertyValuesHolder propertyTop = PropertyValuesHolder.ofInt("top",
                locationOnScreen[1] - getStatusBarHeight(),
                mToTop - getStatusBarHeight());

        PropertyValuesHolder propertyRight = PropertyValuesHolder.ofInt("right",
                locationOnScreen[0] + mAnimatedImage.getWidth(),
                mToLeft + mToWidth);


        PropertyValuesHolder propertyBottom = PropertyValuesHolder.ofInt("bottom",
                mAnimatedImage.getBottom(),
                mToTop + mToHeight - getStatusBarHeight());

        return ObjectAnimator.ofPropertyValuesHolder(mAnimatedImage, propertyLeft, propertyTop, propertyRight, propertyBottom);
    }


    /**
     * This method creates animator that animates Matrix of ImageView.
     * It is needed in order to show the effect when scaling of one view is smoothly changed to the scale of the second view.
     * <p>
     * For example: first view can have scaleType: centerCrop, and the other one fitCenter.
     * The image inside ImageView will smoothly change from one to another
     */
    private ObjectAnimator createExitingImageMatrixAnimator() {

        Matrix initialMatrix = MatrixUtils.getImageMatrix(mAnimatedImage);

        Matrix endMatrix = new Matrix();
        endMatrix.setValues(mToThumbnailMatrixValues);

        Log.v(TAG, "createExitingImageMatrixAnimator, initialMatrix " + initialMatrix);
        Log.v(TAG, "createExitingImageMatrixAnimator,     endMatrix " + endMatrix);

        mAnimatedImage.setScaleType(ImageView.ScaleType.MATRIX);

        return ObjectAnimator.ofObject(mAnimatedImage, MatrixEvaluator.ANIMATED_TRANSFORM_PROPERTY,
                new MatrixEvaluator(), initialMatrix, endMatrix);
    }

    private ObjectAnimator createExitingFadeAnimator() {
        ObjectAnimator fadeInAnimator = ObjectAnimator.ofFloat(mMainContainer,
                "alpha", 1.0f, 0.0f);
        fadeInAnimator.getPropertyName();
        return fadeInAnimator;
    }

}