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

import java.util.ArrayList;

/**
 * This class provides compatibility for things like start listeners &
 * start delays for use by ViewPropertyAnimator and ObjectAnimator
 * @hide
 */
public class RenderNodeAnimatorCompat extends RenderNodeAnimator {

    private long mUnscaledStartDelay = 0;
    private long mStartDelay = 0;
    private long mStartTime;
    private boolean mCanceled;
    private boolean mStarted;

    public RenderNodeAnimatorCompat(int property, float finalValue) {
        super(property, finalValue);
    }

    @Override
    public void setStartDelay(long startDelay) {
        mUnscaledStartDelay = startDelay;
        mStartDelay = (long) (ValueAnimator.getDurationScale() * startDelay);
    }

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

    @Override
    public void start() {
        mStarted = true;
        if (mStartDelay <= 0) {
            doStart();
        } else {
            getHelper().addDelayedAnimation(this);
        }
    }

    @Override
    public boolean isStarted() {
        return mStarted;
    }

    private void doStart() {
        if (!mCanceled) {
            super.start();
        }
    }

    @Override
    public void cancel() {
        mCanceled = true;
        super.cancel();
    }

    /**
     * @return true if the animator was started, false if still delayed
     */
    private boolean processDelayed(long frameTimeMs) {
        if (mCanceled) return true;

        if (mStartTime == 0) {
            mStartTime = frameTimeMs;
        } else if ((frameTimeMs - mStartTime) >= mStartDelay) {
            doStart();
            return true;
        }
        return false;
    }

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

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

    private static class AnimationHelper implements Runnable {

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

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

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

        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++) {
                RenderNodeAnimatorCompat 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();
            }
        }
    }
}
