package com.kaichunlin.transition.animation;

import android.os.Build;
import android.os.Handler;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.UiThread;
import android.view.View;

import com.kaichunlin.transition.AbstractTransition;
import com.kaichunlin.transition.TransitionOperation;

/**
 */
@UiThread
public class TransitionAnimation extends AbstractAnimation {
    private StateController mController;
    private boolean mReverse;
    private int mDuration = 300;

    public TransitionAnimation(@NonNull TransitionOperation transition) {
        super(transition);

        addAnimationListener(new AnimationListener() {
            @Override
            public void onAnimationStart(Animation animationManager) {

            }

            @Override
            public void onAnimationEnd(Animation animationManager) {
                getTransition().stopTransition();
            }

            @Override
            public void onAnimationCancel(Animation animationManager) {
                getTransition().stopTransition();
            }

            @Override
            public void onAnimationReset(Animation animationManager) {
                getTransition().stopTransition();
            }
        });
    }

    @Override
    public void setDuration(@IntRange(from = 0) int duration) {
        mDuration = duration;
    }

    @Override
    public int getDuration() {
        return mDuration;
    }

    @Override
    public void setReverseAnimation(boolean reverse) {
        mReverse = reverse;
    }

    @Override
    public boolean isReverseAnimation() {
        return mReverse;
    }

    @Override
    public void startAnimation() {
        startAnimation(mDuration);
    }

    @Override
    public void startAnimation(@IntRange(from = 0) final int duration) {
        if (getStateControllerType() == CONTROLLER_ANIMATION) {
            View target = ((AbstractTransition) getTransition()).getTarget();
            if (target == null) {
                setStateControllerType(CONTROLLER_ANIMATOR);
                startAnimation(duration);
                return;
            }
            mController = new AnimationController(target, mReverse, getTransition());
        } else if (getStateControllerType() == CONTROLLER_ANIMATOR) {
            mController = new AnimatorController(isReverseAnimation());
        }
        prepareAnimation(mController, duration);
        mController.startController();
    }

    /**
     * Called before {@link StateController#startController()} to configure the animation.
     *
     * @param sharedController A shared {@link StateController} to reduce resource usage.
     * @param duration Duration of the animation, -1 if sharedController's duration should not be overridden.
     */
    protected void prepareAnimation(@NonNull StateController sharedController, @IntRange(from = -1) final int duration) {
        if (isAnimating()) {
            return;
        }
        setAnimating(true);
        getTransition().startTransition(mReverse ? 1 : 0);

        mController = sharedController;
        if (duration != -1) {
            mController.setAnimationDuration(duration);
        }
        mController.addAnimation(this);
    }

    public void startAnimationDelayed(@IntRange(from = 0) int delay) {
        if (mHandler == null) {
            mHandler = new Handler();
        }
        mHandler.postDelayed(mStartAnimation, delay);
    }

    public void startAnimationDelayed(@IntRange(from = 0) final int duration, @IntRange(from = 0) int delay) {
        if (mHandler == null) {
            mHandler = new Handler();
        }
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                startAnimation(duration);
            }
        }, delay);
    }

    @Override
    public void cancelAnimation() {
        if (mController != null) {
            mController.cancelController();
            mController = null;
        }
    }

    @Override
    public void pauseAnimation() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            return;
        }
        if (mController != null) {
            mController.pauseController();
        }
    }

    @Override
    public void resumeAnimation() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            return;
        }
        if (mController != null) {
            mController.resumeController();
        }
    }

    @Override
    public void endAnimation() {
        if (mController != null) {
            mController.endController();
            mController = null;
        }
    }

    @Override
    public void forceEndState() {
        startAnimation();
        endAnimation();
        notifyAnimationEnd();
    }

    @Override
    public void resetAnimation() {
        notifyAnimationReset();
        if (mController != null) {
            mController.resetController();
            mController = null;
        }
        //TODO optimize
        getTransition().startTransition();
        getTransition().updateProgress(mReverse ? 1 : 0);
        getTransition().stopTransition();
    }
}
@@ -5028,26 +5028,50 @@
         
-%7D%0A
+    setAnimating(false);%0A 
         
 //TODO o
@@ -5062,16 +5062,19 @@
         
+   
 //TODO o
@@ -5081,16 +5081,20 @@
 ptimize%0A
+    
         
@@ -5128,32 +5128,36 @@
 tion();%0A        
+    
 getTransition().
@@ -5190,32 +5190,36 @@
 1 : 0);%0A        
+  
+  
 getTransition().
@@ -5232,19 +5232,29 @@
 ansition();%0A
+        %7D%0A
     %7D%0A%7D

Fix TransitionAnimation.resetAnimation crashing when animation was not started