/*
 * Copyright (C) 2015 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.animation;

import android.annotation.Nullable;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.util.ArrayMap;
import android.util.Log;
import android.view.Choreographer;

import java.lang.ref.WeakReference;
import java.util.ArrayList;

/**
 * This custom, static handler handles the timing pulse that is shared by all active
 * ValueAnimators. This approach ensures that the setting of animation values will happen on the
 * same thread that animations start on, and that all animations will share the same times for
 * calculating their values, which makes synchronizing animations possible.
 *
 * The handler uses the Choreographer by default for doing periodic callbacks. A custom
 * AnimationFrameCallbackProvider can be set on the handler to provide timing pulse that
 * may be independent of UI frame update. This could be useful in testing.
 *
 * @hide
 */
public class AnimationHandler {

    private static final String TAG = "AnimationHandler";
    private static final boolean LOCAL_LOGV = false;

    /**
     * Internal per-thread collections used to avoid set collisions as animations start and end
     * while being processed.
     */
    private final ArrayMap<AnimationFrameCallback, Long> mDelayedCallbackStartTime =
            new ArrayMap<>();
    private final ArrayList<AnimationFrameCallback> mAnimationCallbacks =
            new ArrayList<>();
    private final ArrayList<AnimationFrameCallback> mCommitCallbacks =
            new ArrayList<>();
    private AnimationFrameCallbackProvider mProvider;

    // Static flag which allows the pausing behavior to be globally disabled/enabled.
    private static boolean sAnimatorPausingEnabled = isPauseBgAnimationsEnabledInSystemProperties();

    // Static flag which prevents the system property from overriding sAnimatorPausingEnabled field.
    private static boolean sOverrideAnimatorPausingSystemProperty = false;

    /**
     * This paused list is used to store animators forcibly paused when the activity
     * went into the background (to avoid unnecessary background processing work).
     * These animators should be resume()'d when the activity returns to the foreground.
     */
    private final ArrayList<Animator> mPausedAnimators = new ArrayList<>();

    /**
     * This structure is used to store the currently active objects (ViewRootImpls or
     * WallpaperService.Engines) in the process. Each of these objects sends a request to
     * AnimationHandler when it goes into the background (request to pause) or foreground
     * (request to resume). Because all animators are managed by AnimationHandler on the same
     * thread, it should only ever pause animators when *all* requestors are in the background.
     * This list tracks the background/foreground state of all requestors and only ever
     * pauses animators when all items are in the background (false). To simplify, we only ever
     * store visible (foreground) requestors; if the set size reaches zero, there are no
     * objects in the foreground and it is time to pause animators.
     */
    private final ArrayList<WeakReference<Object>> mAnimatorRequestors = new ArrayList<>();

    private final Choreographer.FrameCallback mFrameCallback = new Choreographer.FrameCallback() {
        @Override
        public void doFrame(long frameTimeNanos) {
            doAnimationFrame(getProvider().getFrameTime());
            if (mAnimationCallbacks.size() > 0) {
                getProvider().postFrameCallback(this);
            }
        }
    };

    public final static ThreadLocal<AnimationHandler> sAnimatorHandler = new ThreadLocal<>();
    private static AnimationHandler sTestHandler = null;
    private boolean mListDirty = false;

    public static AnimationHandler getInstance() {
        if (sTestHandler != null) {
            return sTestHandler;
        }
        if (sAnimatorHandler.get() == null) {
            sAnimatorHandler.set(new AnimationHandler());
        }
        return sAnimatorHandler.get();
    }

    /**
     * Sets an instance that will be returned by {@link #getInstance()} on every thread.
     * @return  the previously active test handler, if any.
     * @hide
     */
    public static @Nullable AnimationHandler setTestHandler(@Nullable AnimationHandler handler) {
        AnimationHandler oldHandler = sTestHandler;
        sTestHandler = handler;
        return oldHandler;
    }

    /**
     * System property that controls the behavior of pausing infinite animators when an app
     * is moved to the background.
     *
     * @return the value of 'framework.pause_bg_animations.enabled' system property
     */
    private static boolean isPauseBgAnimationsEnabledInSystemProperties() {
        if (sOverrideAnimatorPausingSystemProperty) return sAnimatorPausingEnabled;
        return SystemProperties
                .getBoolean("framework.pause_bg_animations.enabled", true);
    }

    /**
     * Disable the default behavior of pausing infinite animators when
     * apps go into the background.
     *
     * @param enable Enable (default behavior) or disable background pausing behavior.
     */
    public static void setAnimatorPausingEnabled(boolean enable) {
        sAnimatorPausingEnabled = enable;
    }

    /**
     * Prevents the setAnimatorPausingEnabled behavior from being overridden
     * by the 'framework.pause_bg_animations.enabled' system property value.
     *
     * This is for testing purposes only.
     *
     * @param enable Enable or disable (default behavior) overriding the system
     *               property.
     */
    public static void setOverrideAnimatorPausingSystemProperty(boolean enable) {
        sOverrideAnimatorPausingSystemProperty = enable;
    }

    /**
     * This is called when a window goes away. We should remove
     * it from the requestors list to ensure that we are counting requests correctly and not
     * tracking obsolete+enabled requestors.
     */
    public static void removeRequestor(Object requestor) {
        getInstance().requestAnimatorsEnabledImpl(false, requestor);
        if (LOCAL_LOGV) {
            Log.v(TAG, "removeRequestor for " + requestor);
        }
    }

    /**
     * This method is called from ViewRootImpl or WallpaperService when either a window is no
     * longer visible (enable == false) or when a window becomes visible (enable == true).
     * If animators are not properly disabled when activities are backgrounded, it can lead to
     * unnecessary processing, particularly for infinite animators, as the system will continue
     * to pulse timing events even though the results are not visible. As a workaround, we
     * pause all un-paused infinite animators, and resume them when any window in the process
     * becomes visible.
     */
    public static void requestAnimatorsEnabled(boolean enable, Object requestor) {
        getInstance().requestAnimatorsEnabledImpl(enable, requestor);
    }

    private void requestAnimatorsEnabledImpl(boolean enable, Object requestor) {
        boolean wasEmpty = mAnimatorRequestors.isEmpty();
        setAnimatorPausingEnabled(isPauseBgAnimationsEnabledInSystemProperties());
        synchronized (mAnimatorRequestors) {
            // Only store WeakRef objects to avoid leaks
            if (enable) {
                // First, check whether such a reference is already on the list
                WeakReference<Object> weakRef = null;
                for (int i = mAnimatorRequestors.size() - 1; i >= 0; --i) {
                    WeakReference<Object> ref = mAnimatorRequestors.get(i);
                    Object referent = ref.get();
                    if (referent == requestor) {
                        weakRef = ref;
                    } else if (referent == null) {
                        // Remove any reference that has been cleared
                        mAnimatorRequestors.remove(i);
                    }
                }
                if (weakRef == null) {
                    weakRef = new WeakReference<>(requestor);
                    mAnimatorRequestors.add(weakRef);
                }
            } else {
                for (int i = mAnimatorRequestors.size() - 1; i >= 0; --i) {
                    WeakReference<Object> ref = mAnimatorRequestors.get(i);
                    Object referent = ref.get();
                    if (referent == requestor || referent == null) {
                        // remove requested item or item that has been cleared
                        mAnimatorRequestors.remove(i);
                    }
                }
                // If a reference to the requestor wasn't in the list, nothing to remove
            }
        }
        if (!sAnimatorPausingEnabled) {
            // Resume any animators that have been paused in the meantime, otherwise noop
            // Leave logic above so that if pausing gets re-enabled, the state of the requestors
            // list is valid
            resumeAnimators();
            return;
        }
        boolean isEmpty = mAnimatorRequestors.isEmpty();
        if (wasEmpty != isEmpty) {
            // only paused/resume animators if there was a visibility change
            if (!isEmpty) {
                // If any requestors are enabled, resume currently paused animators
                resumeAnimators();
            } else {
                // Wait before pausing to avoid thrashing animator state for temporary backgrounding
                Choreographer.getInstance().postFrameCallbackDelayed(mPauser,
                        Animator.getBackgroundPauseDelay());
            }
        }
        if (LOCAL_LOGV) {
            Log.v(TAG, (enable ? "enable" : "disable") + " animators for " + requestor
                    + " with pauseDelay of " + Animator.getBackgroundPauseDelay());
            for (int i = 0; i < mAnimatorRequestors.size(); ++i) {
                Log.v(TAG, "animatorRequestors " + i + " = "
                        + mAnimatorRequestors.get(i) + " with referent "
                        + mAnimatorRequestors.get(i).get());
            }
        }
    }

    private void resumeAnimators() {
        Choreographer.getInstance().removeFrameCallback(mPauser);
        for (int i = mPausedAnimators.size() - 1; i >= 0; --i) {
            mPausedAnimators.get(i).resume();
        }
        mPausedAnimators.clear();
    }

    private Choreographer.FrameCallback mPauser = frameTimeNanos -> {
        if (mAnimatorRequestors.size() > 0) {
            // something enabled animators since this callback was scheduled - bail
            return;
        }
        for (int i = 0; i < mAnimationCallbacks.size(); ++i) {
            AnimationFrameCallback callback = mAnimationCallbacks.get(i);
            if (callback instanceof Animator) {
                Animator animator = ((Animator) callback);
                if (animator.getTotalDuration() == Animator.DURATION_INFINITE
                        && !animator.isPaused()) {
                    mPausedAnimators.add(animator);
                    animator.pause();
                }
            }
        }
    };

    /**
     * By default, the Choreographer is used to provide timing for frame callbacks. A custom
     * provider can be used here to provide different timing pulse.
     */
    public void setProvider(AnimationFrameCallbackProvider provider) {
        if (provider == null) {
            mProvider = new MyFrameCallbackProvider();
        } else {
            mProvider = provider;
        }
    }

    private AnimationFrameCallbackProvider getProvider() {
        if (mProvider == null) {
            mProvider = new MyFrameCallbackProvider();
        }
        return mProvider;
    }

    /**
     * Register to get a callback on the next frame after the delay.
     */
    public void addAnimationFrameCallback(final AnimationFrameCallback callback, long delay) {
        if (mAnimationCallbacks.size() == 0) {
            getProvider().postFrameCallback(mFrameCallback);
        }
        if (!mAnimationCallbacks.contains(callback)) {
            mAnimationCallbacks.add(callback);
        }

        if (delay > 0) {
            mDelayedCallbackStartTime.put(callback, (SystemClock.uptimeMillis() + delay));
        }
    }

    /**
     * Register to get a one shot callback for frame commit timing. Frame commit timing is the
     * time *after* traversals are done, as opposed to the animation frame timing, which is
     * before any traversals. This timing can be used to adjust the start time of an animation
     * when expensive traversals create big delta between the animation frame timing and the time
     * that animation is first shown on screen.
     *
     * Note this should only be called when the animation has already registered to receive
     * animation frame callbacks. This callback will be guaranteed to happen *after* the next
     * animation frame callback.
     */
    public void addOneShotCommitCallback(final AnimationFrameCallback callback) {
        if (!mCommitCallbacks.contains(callback)) {
            mCommitCallbacks.add(callback);
        }
    }

    /**
     * Removes the given callback from the list, so it will no longer be called for frame related
     * timing.
     */
    public void removeCallback(AnimationFrameCallback callback) {
        mCommitCallbacks.remove(callback);
        mDelayedCallbackStartTime.remove(callback);
        int id = mAnimationCallbacks.indexOf(callback);
        if (id >= 0) {
            mAnimationCallbacks.set(id, null);
            mListDirty = true;
        }
    }

    private void doAnimationFrame(long frameTime) {
        long currentTime = SystemClock.uptimeMillis();
        final int size = mAnimationCallbacks.size();
        for (int i = 0; i < size; i++) {
            final AnimationFrameCallback callback = mAnimationCallbacks.get(i);
            if (callback == null) {
                continue;
            }
            if (isCallbackDue(callback, currentTime)) {
                callback.doAnimationFrame(frameTime);
                if (mCommitCallbacks.contains(callback)) {
                    getProvider().postCommitCallback(new Runnable() {
                        @Override
                        public void run() {
                            commitAnimationFrame(callback, getProvider().getFrameTime());
                        }
                    });
                }
            }
        }
        cleanUpList();
    }

    private void commitAnimationFrame(AnimationFrameCallback callback, long frameTime) {
        if (!mDelayedCallbackStartTime.containsKey(callback) &&
                mCommitCallbacks.contains(callback)) {
            callback.commitAnimationFrame(frameTime);
            mCommitCallbacks.remove(callback);
        }
    }

    /**
     * Remove the callbacks from mDelayedCallbackStartTime once they have passed the initial delay
     * so that they can start getting frame callbacks.
     *
     * @return true if they have passed the initial delay or have no delay, false otherwise.
     */
    private boolean isCallbackDue(AnimationFrameCallback callback, long currentTime) {
        Long startTime = mDelayedCallbackStartTime.get(callback);
        if (startTime == null) {
            return true;
        }
        if (startTime < currentTime) {
            mDelayedCallbackStartTime.remove(callback);
            return true;
        }
        return false;
    }

    /**
     * Return the number of callbacks that have registered for frame callbacks.
     */
    public static int getAnimationCount() {
        AnimationHandler handler = sTestHandler;
        if (handler == null) {
            handler = sAnimatorHandler.get();
        }
        if (handler == null) {
            return 0;
        }
        return handler.getCallbackSize();
    }

    public static void setFrameDelay(long delay) {
        getInstance().getProvider().setFrameDelay(delay);
    }

    public static long getFrameDelay() {
        return getInstance().getProvider().getFrameDelay();
    }

    void autoCancelBasedOn(ObjectAnimator objectAnimator) {
        for (int i = mAnimationCallbacks.size() - 1; i >= 0; i--) {
            AnimationFrameCallback cb = mAnimationCallbacks.get(i);
            if (cb == null) {
                continue;
            }
            if (objectAnimator.shouldAutoCancel(cb)) {
                ((Animator) mAnimationCallbacks.get(i)).cancel();
            }
        }
    }

    private void cleanUpList() {
        if (mListDirty) {
            for (int i = mAnimationCallbacks.size() - 1; i >= 0; i--) {
                if (mAnimationCallbacks.get(i) == null) {
                    mAnimationCallbacks.remove(i);
                }
            }
            mListDirty = false;
        }
    }

    private int getCallbackSize() {
        int count = 0;
        int size = mAnimationCallbacks.size();
        for (int i = size - 1; i >= 0; i--) {
            if (mAnimationCallbacks.get(i) != null) {
                count++;
            }
        }
        return count;
    }

    /**
     * Default provider of timing pulse that uses Choreographer for frame callbacks.
     */
    private class MyFrameCallbackProvider implements AnimationFrameCallbackProvider {

        final Choreographer mChoreographer = Choreographer.getInstance();

        @Override
        public void postFrameCallback(Choreographer.FrameCallback callback) {
            mChoreographer.postFrameCallback(callback);
        }

        @Override
        public void postCommitCallback(Runnable runnable) {
            mChoreographer.postCallback(Choreographer.CALLBACK_COMMIT, runnable, null);
        }

        @Override
        public long getFrameTime() {
            return mChoreographer.getFrameTime();
        }

        @Override
        public long getFrameDelay() {
            return Choreographer.getFrameDelay();
        }

        @Override
        public void setFrameDelay(long delay) {
            Choreographer.setFrameDelay(delay);
        }
    }

    /**
     * Callbacks that receives notifications for animation timing and frame commit timing.
     * @hide
     */
    public interface AnimationFrameCallback {
        /**
         * Run animation based on the frame time.
         * @param frameTime The frame start time, in the {@link SystemClock#uptimeMillis()} time
         *                  base.
         * @return if the animation has finished.
         */
        boolean doAnimationFrame(long frameTime);

        /**
         * This notifies the callback of frame commit time. Frame commit time is the time after
         * traversals happen, as opposed to the normal animation frame time that is before
         * traversals. This is used to compensate expensive traversals that happen as the
         * animation starts. When traversals take a long time to complete, the rendering of the
         * initial frame will be delayed (by a long time). But since the startTime of the
         * animation is set before the traversal, by the time of next frame, a lot of time would
         * have passed since startTime was set, the animation will consequently skip a few frames
         * to respect the new frameTime. By having the commit time, we can adjust the start time to
         * when the first frame was drawn (after any expensive traversals) so that no frames
         * will be skipped.
         *
         * @param frameTime The frame time after traversals happen, if any, in the
         *                  {@link SystemClock#uptimeMillis()} time base.
         */
        void commitAnimationFrame(long frameTime);
    }

    /**
     * The intention for having this interface is to increase the testability of ValueAnimator.
     * Specifically, we can have a custom implementation of the interface below and provide
     * timing pulse without using Choreographer. That way we could use any arbitrary interval for
     * our timing pulse in the tests.
     *
     * @hide
     */
    public interface AnimationFrameCallbackProvider {
        void postFrameCallback(Choreographer.FrameCallback callback);
        void postCommitCallback(Runnable runnable);
        long getFrameTime();
        long getFrameDelay();
        void setFrameDelay(long delay);
    }
}
