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

import android.animation.Animator;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.annotation.UnsupportedAppUsage;
import android.graphics.CanvasProperty;
import android.graphics.Paint;
import android.graphics.RecordingCanvas;
import android.graphics.RenderNode;
import android.os.Build;
import android.os.Handler;
import android.util.SparseIntArray;

import com.android.internal.util.VirtualRefBasePtr;
import com.android.internal.view.animation.FallbackLUTInterpolator;
import com.android.internal.view.animation.HasNativeInterpolator;
import com.android.internal.view.animation.NativeInterpolatorFactory;

import java.util.ArrayList;

/**
 * @hide
 */
public class RenderNodeAnimator extends Animator {
    // Keep in sync with enum RenderProperty in Animator.h
    public static final int TRANSLATION_X = 0;
    public static final int TRANSLATION_Y = 1;
    public static final int TRANSLATION_Z = 2;
    public static final int SCALE_X = 3;
    public static final int SCALE_Y = 4;
    public static final int ROTATION = 5;
    public static final int ROTATION_X = 6;
    public static final int ROTATION_Y = 7;
    public static final int X = 8;
    public static final int Y = 9;
    public static final int Z = 10;
    public static final int ALPHA = 11;
    // The last value in the enum, used for array size initialization
    public static final int LAST_VALUE = ALPHA;

    // Keep in sync with enum PaintFields in Animator.h
    public static final int PAINT_STROKE_WIDTH = 0;

    /**
     * Field for the Paint alpha channel, which should be specified as a value
     * between 0 and 255.
     */
    public static final int PAINT_ALPHA = 1;

    // ViewPropertyAnimator uses a mask for its values, we need to remap them
    // to the enum values here. RenderPropertyAnimator can't use the mask values
    // directly as internally it uses a lookup table so it needs the values to
    // be sequential starting from 0
    private static final SparseIntArray sViewPropertyAnimatorMap = new SparseIntArray(15) {{
        put(ViewPropertyAnimator.TRANSLATION_X, TRANSLATION_X);
        put(ViewPropertyAnimator.TRANSLATION_Y, TRANSLATION_Y);
        put(ViewPropertyAnimator.TRANSLATION_Z, TRANSLATION_Z);
        put(ViewPropertyAnimator.SCALE_X, SCALE_X);
        put(ViewPropertyAnimator.SCALE_Y, SCALE_Y);
        put(ViewPropertyAnimator.ROTATION, ROTATION);
        put(ViewPropertyAnimator.ROTATION_X, ROTATION_X);
        put(ViewPropertyAnimator.ROTATION_Y, ROTATION_Y);
        put(ViewPropertyAnimator.X, X);
        put(ViewPropertyAnimator.Y, Y);
        put(ViewPropertyAnimator.Z, Z);
        put(ViewPropertyAnimator.ALPHA, ALPHA);
    }};

    private VirtualRefBasePtr mNativePtr;

    private Handler mHandler;
    private RenderNode mTarget;
    private View mViewTarget;
    private int mRenderProperty = -1;
    private float mFinalValue;
    private TimeInterpolator mInterpolator;

    private static final int STATE_PREPARE = 0;
    private static final int STATE_DELAYED = 1;
    private static final int STATE_RUNNING = 2;
    private static final int STATE_FINISHED = 3;
    private int mState = STATE_PREPARE;

    private long mUnscaledDuration = 300;
    private long mUnscaledStartDelay = 0;
    // If this is true, we will run any start delays on the UI thread. This is
    // the safe default, and is necessary to ensure start listeners fire at
    // the correct time. Animators created by RippleDrawable (the
    // CanvasProperty<> ones) do not have this expectation, and as such will
    // set this to false so that the renderthread handles the startdelay instead
    private final boolean mUiThreadHandlesDelay;
    private long mStartDelay = 0;
    private long mStartTime;

    @UnsupportedAppUsage
    public static int mapViewPropertyToRenderProperty(int viewProperty) {
        return sViewPropertyAnimatorMap.get(viewProperty);
    }

    @UnsupportedAppUsage
    public RenderNodeAnimator(int property, float finalValue) {
        mRenderProperty = property;
        mFinalValue = finalValue;
        mUiThreadHandlesDelay = true;
        init(nCreateAnimator(property, finalValue));
    }

    @UnsupportedAppUsage
    public RenderNodeAnimator(CanvasProperty<Float> property, float finalValue) {
        init(nCreateCanvasPropertyFloatAnimator(
                property.getNativeContainer(), finalValue));
        mUiThreadHandlesDelay = false;
    }

    /**
     * Creates a new render node animator for a field on a Paint property.
     *
     * @param property The paint property to target
     * @param paintField Paint field to animate, one of {@link #PAINT_ALPHA} or
     *            {@link #PAINT_STROKE_WIDTH}
     * @param finalValue The target value for the property
     */
    @UnsupportedAppUsage
    public RenderNodeAnimator(CanvasProperty<Paint> property, int paintField, float finalValue) {
        init(nCreateCanvasPropertyPaintAnimator(
                property.getNativeContainer(), paintField, finalValue));
        mUiThreadHandlesDelay = false;
    }

    public RenderNodeAnimator(int x, int y, float startRadius, float endRadius) {
        init(nCreateRevealAnimator(x, y, startRadius, endRadius));
        mUiThreadHandlesDelay = true;
    }

    private void init(long ptr) {
        mNativePtr = new VirtualRefBasePtr(ptr);
    }

    private void checkMutable() {
        if (mState != STATE_PREPARE) {
            throw new IllegalStateException("Animator has already started, cannot change it now!");
        }
        if (mNativePtr == null) {
            throw new IllegalStateException("Animator's target has been destroyed "
                    + "(trying to modify an animation after activity destroy?)");
        }
    }

    static boolean isNativeInterpolator(TimeInterpolator interpolator) {
        return interpolator.getClass().isAnnotationPresent(HasNativeInterpolator.class);
    }

    private void applyInterpolator() {
        if (mInterpolator == null || mNativePtr == null) return;

        long ni;
        if (isNativeInterpolator(mInterpolator)) {
            ni = ((NativeInterpolatorFactory)mInterpolator).createNativeInterpolator();
        } else {
            long duration = nGetDuration(mNativePtr.get());
            ni = FallbackLUTInterpolator.createNativeInterpolator(mInterpolator, duration);
        }
        nSetInterpolator(mNativePtr.get(), ni);
    }

    @Override
    public void start() {
        if (mTarget == null) {
            throw new IllegalStateException("Missing target!");
        }

        if (mState != STATE_PREPARE) {
            throw new IllegalStateException("Already started!");
        }

        mState = STATE_DELAYED;
        applyInterpolator();

        if (mNativePtr == null) {
            // It's dead, immediately cancel
            cancel();
        } else if (mStartDelay <= 0 || !mUiThreadHandlesDelay) {
            nSetStartDelay(mNativePtr.get(), mStartDelay);
            doStart();
        } else {
            getHelper().addDelayedAnimation(this);
        }
    }

    private void doStart() {
        // Alpha is a special snowflake that has the canonical value stored
        // in mTransformationInfo instead of in RenderNode, so we need to update
        // it with the final value here.
        if (mRenderProperty == RenderNodeAnimator.ALPHA) {
            mViewTarget.ensureTransformationInfo();
            mViewTarget.mTransformationInfo.mAlpha = mFinalValue;
        }

        moveToRunningState();

        if (mViewTarget != null) {
            // Kick off a frame to start the process
            mViewTarget.invalidateViewProperty(true, false);
        }
    }

    private void moveToRunningState() {
        mState = STATE_RUNNING;
        if (mNativePtr != null) {
            if (mHandler == null) {
                mHandler = new Handler();
            }
            nStart(mNativePtr.get());
        }
        notifyStartListeners();
    }

    private void notifyStartListeners() {
        final ArrayList<AnimatorListener> listeners = cloneListeners();
        final int numListeners = listeners == null ? 0 : listeners.size();
        for (int i = 0; i < numListeners; i++) {
            listeners.get(i).onAnimationStart(this);
        }
    }

    @Override
    public void cancel() {
        if (mState != STATE_PREPARE && mState != STATE_FINISHED) {
            if (mState == STATE_DELAYED) {
                getHelper().removeDelayedAnimation(this);
                moveToRunningState();
            }

            final ArrayList<AnimatorListener> listeners = cloneListeners();
            final int numListeners = listeners == null ? 0 : listeners.size();
            for (int i = 0; i < numListeners; i++) {
                listeners.get(i).onAnimationCancel(this);
            }

            end();
        }
    }

    @Override
    public void end() {
        if (mState != STATE_FINISHED) {
            if (mState < STATE_RUNNING) {
                getHelper().removeDelayedAnimation(this);
                doStart();
            }
            if (mNativePtr != null) {
                nEnd(mNativePtr.get());
                if (mViewTarget != null) {
                    // Kick off a frame to flush the state change
                    mViewTarget.invalidateViewProperty(true, false);
                }
            } else {
                // It's already dead, jump to onFinish
                onFinished();
            }
        }
    }

    @Override
    public void pause() {
        throw new UnsupportedOperationException();
    }

    @Override
    public void resume() {
        throw new UnsupportedOperationException();
    }

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public void setTarget(View view) {
        mViewTarget = view;
        setTarget(mViewTarget.mRenderNode);
    }

    /** Sets the animation target to the owning view of the RecordingCanvas */
    public void setTarget(RecordingCanvas canvas) {
        setTarget(canvas.mNode);
    }

    /** @hide */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
    public void setTarget(DisplayListCanvas canvas) {
        setTarget((RecordingCanvas) canvas);
    }

    private void setTarget(RenderNode node) {
        checkMutable();
        if (mTarget != null) {
            throw new IllegalStateException("Target already set!");
        }
        nSetListener(mNativePtr.get(), this);
        mTarget = node;
        mTarget.addAnimator(this);
    }

    @UnsupportedAppUsage
    public void setStartValue(float startValue) {
        checkMutable();
        nSetStartValue(mNativePtr.get(), startValue);
    }

    @Override
    public void setStartDelay(long startDelay) {
        checkMutable();
        if (startDelay < 0) {
            throw new IllegalArgumentException("startDelay must be positive; " + startDelay);
        }
        mUnscaledStartDelay = startDelay;
        mStartDelay = (long) (ValueAnimator.getDurationScale() * startDelay);
    }

    @Override
    public long getStartDelay() {
        return mUnscaledStartDelay;
    }

    @UnsupportedAppUsage
    @Override
    public RenderNodeAnimator setDuration(long duration) {
        checkMutable();
        if (duration < 0) {
            throw new IllegalArgumentException("duration must be positive; " + duration);
        }
        mUnscaledDuration = duration;
        nSetDuration(mNativePtr.get(), (long) (duration * ValueAnimator.getDurationScale()));
        return this;
    }

    @Override
    public long getDuration() {
        return mUnscaledDuration;
    }

    @Override
    public long getTotalDuration() {
        return mUnscaledDuration + mUnscaledStartDelay;
    }

    @Override
    public boolean isRunning() {
        return mState == STATE_DELAYED || mState == STATE_RUNNING;
    }

    @Override
    public boolean isStarted() {
        return mState != STATE_PREPARE;
    }

    @Override
    public void setInterpolator(TimeInterpolator interpolator) {
        checkMutable();
        mInterpolator = interpolator;
    }

    @Override
    public TimeInterpolator getInterpolator() {
        return mInterpolator;
    }

    protected void onFinished() {
        if (mState == STATE_PREPARE) {
            // Unlikely but possible, the native side has been destroyed
            // before we have started.
            releaseNativePtr();
            return;
        }
        if (mState == STATE_DELAYED) {
            getHelper().removeDelayedAnimation(this);
            notifyStartListeners();
        }
        mState = STATE_FINISHED;

        final ArrayList<AnimatorListener> listeners = cloneListeners();
        final int numListeners = listeners == null ? 0 : listeners.size();
        for (int i = 0; i < numListeners; i++) {
            listeners.get(i).onAnimationEnd(this);
        }

        // Release the native object, as it has a global reference to us. This
        // breaks the cyclic reference chain, and allows this object to be
        // GC'd
        releaseNativePtr();
    }

    private void releaseNativePtr() {
        if (mNativePtr != null) {
            mNativePtr.release();
            mNativePtr = null;
        }
    }

    @SuppressWarnings("unchecked")
    private ArrayList<AnimatorListener> cloneListeners() {
        ArrayList<AnimatorListener> listeners = getListeners();
        if (listeners != null) {
            listeners = (ArrayList<AnimatorListener>) listeners.clone();
        }
        return listeners;
    }

    public long getNativeAnimator() {
        return mNativePtr.get();
    }

    /**
     * @return true if the animator was started, false if still delayed
     */
    private boolean processDelayed(long frameTimeMs) {
        if (mStartTime == 0) {
            mStartTime = frameTimeMs;
        } else if ((frameTimeMs - mStartTime) >= mStartDelay) {
            doStart();
            return true;
        }
        return false;
    }

    private static DelayedAnimationHelper getHelper() {
        DelayedAnimationHelper helper = sAnimationHelper.get();
        if (helper == null) {
            helper = new DelayedAnimationHelper();
            sAnimationHelper.set(helper);
        }
        return helper;
    }

    private static ThreadLocal<DelayedAnimationHelper> sAnimationHelper =
            new ThreadLocal<DelayedAnimationHelper>();

    private static class DelayedAnimationHelper implements Runnable {

        private ArrayList<RenderNodeAnimator> mDelayedAnims = new ArrayList<RenderNodeAnimator>();
        private final Choreographer mChoreographer;
        private boolean mCallbackScheduled;

        public DelayedAnimationHelper() {
            mChoreographer = Choreographer.getInstance();
        }

        public void addDelayedAnimation(RenderNodeAnimator animator) {
            mDelayedAnims.add(animator);
            scheduleCallback();
        }

        public void removeDelayedAnimation(RenderNodeAnimator animator) {
            mDelayedAnims.remove(animator);
        }

        private void scheduleCallback() {
            if (!mCallbackScheduled) {
                mCallbackScheduled = true;
                mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, this, null);
            }
        }

        @Override
        public void run() {
            long frameTimeMs = mChoreographer.getFrameTime();
            mCallbackScheduled = false;

            int end = 0;
            for (int i = 0; i < mDelayedAnims.size(); i++) {
                RenderNodeAnimator animator = mDelayedAnims.get(i);
                if (!animator.processDelayed(frameTimeMs)) {
                    if (end != i) {
                        mDelayedAnims.set(end, animator);
                    }
                    end++;
                }
            }
            while (mDelayedAnims.size() > end) {
                mDelayedAnims.remove(mDelayedAnims.size() - 1);
            }

            if (mDelayedAnims.size() > 0) {
                scheduleCallback();
            }
        }
    }

    // Called by native
    @UnsupportedAppUsage
    private static void callOnFinished(RenderNodeAnimator animator) {
        animator.mHandler.post(animator::onFinished);
    }

    @Override
    public Animator clone() {
        throw new IllegalStateException("Cannot clone this animator");
    }

    @Override
    public void setAllowRunningAsynchronously(boolean mayRunAsync) {
        checkMutable();
        nSetAllowRunningAsync(mNativePtr.get(), mayRunAsync);
    }

    private static native long nCreateAnimator(int property, float finalValue);
    private static native long nCreateCanvasPropertyFloatAnimator(
            long canvasProperty, float finalValue);
    private static native long nCreateCanvasPropertyPaintAnimator(
            long canvasProperty, int paintField, float finalValue);
    private static native long nCreateRevealAnimator(
            int x, int y, float startRadius, float endRadius);

    private static native void nSetStartValue(long nativePtr, float startValue);
    private static native void nSetDuration(long nativePtr, long duration);
    private static native long nGetDuration(long nativePtr);
    private static native void nSetStartDelay(long nativePtr, long startDelay);
    private static native void nSetInterpolator(long animPtr, long interpolatorPtr);
    private static native void nSetAllowRunningAsync(long animPtr, boolean mayRunAsync);
    private static native void nSetListener(long animPtr, RenderNodeAnimator listener);

    private static native void nStart(long animPtr);
    private static native void nEnd(long animPtr);
}
