/*
 * 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.
 */
#ifndef ANIMATOR_H
#define ANIMATOR_H

#include <cutils/compiler.h>
#include <utils/RefBase.h>
#include <utils/StrongPointer.h>
#include <utils/Timers.h>
#include <memory>

#include "utils/Macros.h"

#include <vector>

namespace android {
namespace uirenderer {

class AnimationContext;
class BaseRenderNodeAnimator;
class CanvasPropertyPrimitive;
class CanvasPropertyPaint;
class Interpolator;
class RenderNode;
class RenderProperties;

class AnimationListener : public VirtualLightRefBase {
public:
    ANDROID_API virtual void onAnimationFinished(BaseRenderNodeAnimator*) = 0;

protected:
    ANDROID_API virtual ~AnimationListener() {}
};

enum class RepeatMode {
    // These are the same values as the RESTART and REVERSE in ValueAnimator.java.
    Restart = 1,
    Reverse = 2
};

class BaseRenderNodeAnimator : public VirtualLightRefBase {
    PREVENT_COPY_AND_ASSIGN(BaseRenderNodeAnimator);

public:
    ANDROID_API void setStartValue(float value);
    ANDROID_API void setInterpolator(Interpolator* interpolator);
    ANDROID_API void setDuration(nsecs_t durationInMs);
    ANDROID_API nsecs_t duration() { return mDuration; }
    ANDROID_API void setStartDelay(nsecs_t startDelayInMs);
    ANDROID_API nsecs_t startDelay() { return mStartDelay; }
    ANDROID_API void setListener(AnimationListener* listener) { mListener = listener; }
    AnimationListener* listener() { return mListener.get(); }
    ANDROID_API void setAllowRunningAsync(bool mayRunAsync) { mMayRunAsync = mayRunAsync; }
    bool mayRunAsync() { return mMayRunAsync; }
    ANDROID_API void start();
    ANDROID_API virtual void reset();
    ANDROID_API void reverse();
    // Terminates the animation at its current progress.
    ANDROID_API void cancel();

    // Terminates the animation and skip to the end of the animation.
    ANDROID_API virtual void end();

    void attach(RenderNode* target);
    virtual void onAttached() {}
    void detach() { mTarget = nullptr; }
    ANDROID_API void pushStaging(AnimationContext& context);
    ANDROID_API bool animate(AnimationContext& context);

    // Returns the remaining time in ms for the animation. Note this should only be called during
    // an animation on RenderThread.
    ANDROID_API nsecs_t getRemainingPlayTime();

    bool isRunning() {
        return mPlayState == PlayState::Running || mPlayState == PlayState::Reversing;
    }
    bool isFinished() { return mPlayState == PlayState::Finished; }
    float finalValue() { return mFinalValue; }

    ANDROID_API virtual uint32_t dirtyMask() = 0;

    void forceEndNow(AnimationContext& context);
    RenderNode* target() { return mTarget; }
    RenderNode* stagingTarget() { return mStagingTarget; }

protected:
    // PlayState is used by mStagingPlayState and mPlayState to track the state initiated from UI
    // thread and Render Thread animation state, respectively.
    // From the UI thread, mStagingPlayState transition looks like
    // NotStarted -> Running/Reversing -> Finished
    //                ^                     |
    //                |                     |
    //                ----------------------
    // Note: For mStagingState, the Finished state (optional) is only set when the animation is
    // terminated by user.
    //
    // On Render Thread, mPlayState transition:
    // NotStart -> Running/Reversing-> Finished
    //                ^                 |
    //                |                 |
    //                ------------------
    // Note that if the animation is in Running/Reversing state, calling start or reverse again
    // would do nothing if the animation has the same play direction as the request; otherwise,
    // the animation would start from where it is and change direction (i.e. Reversing <-> Running)

    enum class PlayState {
        NotStarted,
        Running,
        Reversing,
        Finished,
    };

    explicit BaseRenderNodeAnimator(float finalValue);
    virtual ~BaseRenderNodeAnimator();

    virtual float getValue(RenderNode* target) const = 0;
    virtual void setValue(RenderNode* target, float value) = 0;

    void callOnFinishedListener(AnimationContext& context);

    virtual void onStagingPlayStateChanged() {}
    virtual void onPlayTimeChanged(nsecs_t playTime) {}
    virtual void onPushStaging() {}

    RenderNode* mTarget;
    RenderNode* mStagingTarget;

    float mFinalValue;
    float mDeltaValue;
    float mFromValue;

    std::unique_ptr<Interpolator> mInterpolator;
    PlayState mStagingPlayState;
    PlayState mPlayState;
    bool mHasStartValue;
    nsecs_t mStartTime;
    nsecs_t mDuration;
    nsecs_t mStartDelay;
    bool mMayRunAsync;
    // Play Time tracks the progress of animation, it should always be [0, mDuration], 0 being
    // the beginning of the animation, will reach mDuration at the end of an animation.
    nsecs_t mPlayTime;

    sp<AnimationListener> mListener;

private:
    enum class Request { Start, Reverse, Reset, Cancel, End };

    // Defines different actions upon finish.
    enum class Action {
        // For animations that got canceled or finished normally. no more action needs to be done.
        None,
        // For animations that get reset, the reset will happen in the next animation pulse.
        Reset,
        // For animations being ended, in the next animation pulse the animation will skip to end.
        End
    };

    inline void checkMutable();
    virtual void transitionToRunning(AnimationContext& context);
    void doSetStartValue(float value);
    bool updatePlayTime(nsecs_t playTime);
    void resolveStagingRequest(Request request);

    std::vector<Request> mStagingRequests;
    Action mPendingActionUponFinish = Action::None;
};

class RenderPropertyAnimator : public BaseRenderNodeAnimator {
public:
    enum RenderProperty {
        TRANSLATION_X = 0,
        TRANSLATION_Y,
        TRANSLATION_Z,
        SCALE_X,
        SCALE_Y,
        ROTATION,
        ROTATION_X,
        ROTATION_Y,
        X,
        Y,
        Z,
        ALPHA,
    };

    ANDROID_API RenderPropertyAnimator(RenderProperty property, float finalValue);

    ANDROID_API virtual uint32_t dirtyMask();

protected:
    virtual float getValue(RenderNode* target) const override;
    virtual void setValue(RenderNode* target, float value) override;
    virtual void onAttached() override;
    virtual void onStagingPlayStateChanged() override;
    virtual void onPushStaging() override;

private:
    typedef bool (RenderProperties::*SetFloatProperty)(float value);
    typedef float (RenderProperties::*GetFloatProperty)() const;

    struct PropertyAccessors;
    const PropertyAccessors* mPropertyAccess;

    static const PropertyAccessors PROPERTY_ACCESSOR_LUT[];
    bool mShouldSyncPropertyFields = false;
    bool mShouldUpdateStagingProperties = false;
};

class CanvasPropertyPrimitiveAnimator : public BaseRenderNodeAnimator {
public:
    ANDROID_API CanvasPropertyPrimitiveAnimator(CanvasPropertyPrimitive* property,
                                                float finalValue);

    ANDROID_API virtual uint32_t dirtyMask();

protected:
    virtual float getValue(RenderNode* target) const override;
    virtual void setValue(RenderNode* target, float value) override;

private:
    sp<CanvasPropertyPrimitive> mProperty;
};

class CanvasPropertyPaintAnimator : public BaseRenderNodeAnimator {
public:
    enum PaintField {
        STROKE_WIDTH = 0,
        ALPHA,
    };

    ANDROID_API CanvasPropertyPaintAnimator(CanvasPropertyPaint* property, PaintField field,
                                            float finalValue);

    ANDROID_API virtual uint32_t dirtyMask();

protected:
    virtual float getValue(RenderNode* target) const override;
    virtual void setValue(RenderNode* target, float value) override;

private:
    sp<CanvasPropertyPaint> mProperty;
    PaintField mField;
};

class RevealAnimator : public BaseRenderNodeAnimator {
public:
    ANDROID_API RevealAnimator(int centerX, int centerY, float startValue, float finalValue);

    ANDROID_API virtual uint32_t dirtyMask();

protected:
    virtual float getValue(RenderNode* target) const override;
    virtual void setValue(RenderNode* target, float value) override;

private:
    int mCenterX, mCenterY;
};

} /* namespace uirenderer */
} /* namespace android */

#endif /* ANIMATOR_H */
