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

import android.os.Looper;
import android.util.AndroidRuntimeException;
import android.view.View;

/**
 * SpringAnimation is an animation that is driven by a {@link SpringForce}. The spring force defines
 * the spring's stiffness, damping ratio, as well as the rest position. Once the SpringAnimation is
 * started, on each frame the spring force will update the animation's value and velocity.
 * The animation will continue to run until the spring force reaches equilibrium. If the spring used
 * in the animation is undamped, the animation will never reach equilibrium. Instead, it will
 * oscillate forever.
 *
 * <div class="special reference">
 * <h3>Developer Guides</h3>
 * </div>
 *
 * <p>To create a simple {@link SpringAnimation} that uses the default {@link SpringForce}:</p>
 * <pre class="prettyprint">
 * // Create an animation to animate view's X property, set the rest position of the
 * // default spring to 0, and start the animation with a starting velocity of 5000 (pixel/s).
 * final SpringAnimation anim = new SpringAnimation(view, DynamicAnimation.X, 0)
 *         .setStartVelocity(5000);
 * anim.start();
 * </pre>
 *
 * <p>Alternatively, a {@link SpringAnimation} can take a pre-configured {@link SpringForce}, and
 * use that to drive the animation. </p>
 * <pre class="prettyprint">
 * // Create a low stiffness, low bounce spring at position 0.
 * SpringForce spring = new SpringForce(0)
 *         .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
 *         .setStiffness(SpringForce.STIFFNESS_LOW);
 * // Create an animation to animate view's scaleY property, and start the animation using
 * // the spring above and a starting value of 0.5. Additionally, constrain the range of value for
 * // the animation to be non-negative, effectively preventing any spring overshoot.
 * final SpringAnimation anim = new SpringAnimation(view, DynamicAnimation.SCALE_Y)
 *         .setMinValue(0).setSpring(spring).setStartValue(1);
 * anim.start();
 * </pre>
 */
public final class SpringAnimation extends DynamicAnimation<SpringAnimation> {

    private SpringForce mSpring = null;
    private float mPendingPosition = UNSET;
    private static final float UNSET = Float.MAX_VALUE;
    private boolean mEndRequested = false;

    /**
     * <p>This creates a SpringAnimation that animates a {@link FloatValueHolder} instance. During
     * the animation, the {@link FloatValueHolder} instance will be updated via
     * {@link FloatValueHolder#setValue(float)} each frame. The caller can obtain the up-to-date
     * animation value via {@link FloatValueHolder#getValue()}.
     *
     * <p><strong>Note:</strong> changing the value in the {@link FloatValueHolder} via
     * {@link FloatValueHolder#setValue(float)} outside of the animation during an
     * animation run will not have any effect on the on-going animation.
     *
     * @param floatValueHolder the property to be animated
     */
    public SpringAnimation(FloatValueHolder floatValueHolder) {
        super(floatValueHolder);
    }

    /**
     * This creates a SpringAnimation that animates the property of the given object.
     * Note, a spring will need to setup through {@link #setSpring(SpringForce)} before
     * the animation starts.
     *
     * @param object the Object whose property will be animated
     * @param property the property to be animated
     * @param <K> the class on which the Property is declared
     */
    public <K> SpringAnimation(K object, FloatPropertyCompat<K> property) {
        super(object, property);
    }

    /**
     * This creates a SpringAnimation that animates the property of the given object. A Spring will
     * be created with the given final position and default stiffness and damping ratio.
     * This spring can be accessed and reconfigured through {@link #setSpring(SpringForce)}.
     *
     * @param object the Object whose property will be animated
     * @param property the property to be animated
     * @param finalPosition the final position of the spring to be created.
     * @param <K> the class on which the Property is declared
     */
    public <K> SpringAnimation(K object, FloatPropertyCompat<K> property,
            float finalPosition) {
        super(object, property);
        mSpring = new SpringForce(finalPosition);
    }

    /**
     * @deprecated This API is being replaced with
     * {@link #SpringAnimation(Object, FloatPropertyCompat)}.
     *
     * <p><b>Note: </b> Migration to the new API should require no modification to callers of this
     * deprecated API.  The new API's parameters are the base class of the original's parameters and
     * therefore is compatible to calls to this deprecated method.
     */
    @Deprecated
    public SpringAnimation(View v, ViewProperty property) {
        super(v, property);
    }

    /**
     * @deprecated This API is being replaced with
     * {@link #SpringAnimation(Object, FloatPropertyCompat, float)}.
     *
     * <p><b>Note: </b> Migration to the new API should require no modification to callers of this
     * deprecated API.  The new API's parameters are the base class of the original's parameters and
     * therefore is compatible to calls to this deprecated method.
     */
    @Deprecated
    public SpringAnimation(View v, ViewProperty property, float finalPosition) {
        super(v, property);
        mSpring = new SpringForce(finalPosition);
    }

    /**
     * Returns the spring that the animation uses for animations.
     *
     * @return the spring that the animation uses for animations
     */
    public SpringForce getSpring() {
        return mSpring;
    }

    /**
     * Uses the given spring as the force that drives this animation. If this spring force has its
     * parameters re-configured during the animation, the new configuration will be reflected in the
     * animation immediately.
     *
     * @param force a pre-defined spring force that drives the animation
     * @return the animation that the spring force is set on
     */
    public SpringAnimation setSpring(SpringForce force) {
        mSpring = force;
        return this;
    }

    @Override
    public void start() {
        sanityCheck();
        mSpring.setValueThreshold(getValueThreshold());
        super.start();
    }

    /**
     * Updates the final position of the spring.
     * <p/>
     * When the animation is running, calling this method would assume the position change of the
     * spring as a continuous movement since last frame, which yields more accurate results than
     * changing the spring position directly through {@link SpringForce#setFinalPosition(float)}.
     * <p/>
     * If the animation hasn't started, calling this method will change the spring position, and
     * immediately start the animation.
     *
     * @param finalPosition rest position of the spring
     */
    public void animateToFinalPosition(float finalPosition) {
        if (isRunning()) {
            mPendingPosition = finalPosition;
        } else {
            if (mSpring == null) {
                mSpring = new SpringForce(finalPosition);
            }
            mSpring.setFinalPosition(finalPosition);
            start();
        }
    }

    /**
     * Skips to the end of the animation. If the spring is undamped, an
     * {@link IllegalStateException} will be thrown, as the animation would never reach to an end.
     * It is recommended to check {@link #canSkipToEnd()} before calling this method. This method
     * should only be called on main thread. If animation is not running, no-op.
     *
     * @throws IllegalStateException if the spring is undamped (i.e. damping ratio = 0)
     * @throws AndroidRuntimeException if this method is not called on the main thread
     */
    public void skipToEnd() {
        if (!canSkipToEnd()) {
            throw new UnsupportedOperationException("Spring animations can only come to an end"
                    + " when there is damping");
        }
        if (Looper.myLooper() != Looper.getMainLooper()) {
            throw new AndroidRuntimeException("Animations may only be started on the main thread");
        }
        if (mRunning) {
            mEndRequested = true;
        }
    }

    /**
     * Queries whether the spring can eventually come to the rest position.
     *
     * @return {@code true} if the spring is damped, otherwise {@code false}
     */
    public boolean canSkipToEnd() {
        return mSpring.mDampingRatio > 0;
    }

    /************************ Below are private APIs *************************/

    private void sanityCheck() {
        if (mSpring == null) {
            throw new UnsupportedOperationException("Incomplete SpringAnimation: Either final"
                    + " position or a spring force needs to be set.");
        }
        double finalPosition = mSpring.getFinalPosition();
        if (finalPosition > mMaxValue) {
            throw new UnsupportedOperationException("Final position of the spring cannot be greater"
                    + " than the max value.");
        } else if (finalPosition < mMinValue) {
            throw new UnsupportedOperationException("Final position of the spring cannot be less"
                    + " than the min value.");
        }
    }

    @Override
    boolean updateValueAndVelocity(long deltaT) {
        // If user had requested end, then update the value and velocity to end state and consider
        // animation done.
        if (mEndRequested) {
            if (mPendingPosition != UNSET) {
                mSpring.setFinalPosition(mPendingPosition);
                mPendingPosition = UNSET;
            }
            mValue = mSpring.getFinalPosition();
            mVelocity = 0;
            mEndRequested = false;
            return true;
        }

        if (mPendingPosition != UNSET) {
            double lastPosition = mSpring.getFinalPosition();
            // Approximate by considering half of the time spring position stayed at the old
            // position, half of the time it's at the new position.
            MassState massState = mSpring.updateValues(mValue, mVelocity, deltaT / 2);
            mSpring.setFinalPosition(mPendingPosition);
            mPendingPosition = UNSET;

            massState = mSpring.updateValues(massState.mValue, massState.mVelocity, deltaT / 2);
            mValue = massState.mValue;
            mVelocity = massState.mVelocity;

        } else {
            MassState massState = mSpring.updateValues(mValue, mVelocity, deltaT);
            mValue = massState.mValue;
            mVelocity = massState.mVelocity;
        }

        mValue = Math.max(mValue, mMinValue);
        mValue = Math.min(mValue, mMaxValue);

        if (isAtEquilibrium(mValue, mVelocity)) {
            mValue = mSpring.getFinalPosition();
            mVelocity = 0f;
            return true;
        }
        return false;
    }

    @Override
    float getAcceleration(float value, float velocity) {
        return mSpring.getAcceleration(value, velocity);
    }

    @Override
    boolean isAtEquilibrium(float value, float velocity) {
        return mSpring.isAtEquilibrium(value, velocity);
    }

    @Override
    void setValueThreshold(float threshold) {
    }
}
