/*
 * Copyright (C) 2007 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer. 
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution. 
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "Animation.h"
#include "CSSPropertyBlendingClient.h"
#include "CSSPropertyNames.h"
#include "RenderStyleConstants.h"

namespace WebCore {

class CompositeAnimation;
class Element;
class FloatRect;
class LayoutRect;
class RenderElement;
class RenderStyle;
class TimingFunction;

enum class AnimateChange {
    StyleBlended            = 1 << 0, // Style was changed.
    StateChange             = 1 << 1, // Animation state() changed.
    RunningStateChange      = 1 << 2, // Animation "running or paused" changed.
};

class AnimationBase : public RefCounted<AnimationBase>
    , public CSSPropertyBlendingClient {
    friend class CompositeAnimation;
    friend class CSSPropertyAnimation;
    WTF_MAKE_FAST_ALLOCATED;
public:
    AnimationBase(const Animation& transition, Element&, CompositeAnimation&);
    virtual ~AnimationBase();

    Element* element() const { return m_element.get(); }
    const RenderStyle& currentStyle() const override;
    RenderElement* renderer() const override;
    virtual void clear();

    double duration() const;

    // Animations and Transitions go through the states below. When entering the STARTED state
    // the animation is started. This may or may not require deferred response from the animator.
    // If so, we stay in this state until that response is received (and it returns the start time).
    // Otherwise, we use the current time as the start time and go immediately to AnimationState::Looping
    // or AnimationState::Ending.
    enum class AnimationState : uint8_t {
        New,                        // animation just created, animation not running yet
        StartWaitTimer,             // start timer running, waiting for fire
        StartWaitStyleAvailable,    // waiting for style setup so we can start animations
        StartWaitResponse,          // animation started, waiting for response
        Looping,                    // response received, animation running, loop timer running, waiting for fire
        Ending,                     // received, animation running, end timer running, waiting for fire
        PausedNew,                  // in pause mode when animation was created
        PausedWaitTimer,            // in pause mode when animation started
        PausedWaitStyleAvailable,   // in pause mode when waiting for style setup
        PausedWaitResponse,         // animation paused when in STARTING state
        PausedRun,                  // animation paused when in LOOPING or ENDING state
        Done,                       // end timer fired, animation finished and removed
        FillingForwards             // animation has ended and is retaining its final value
    };

    enum class AnimationStateInput : uint8_t {
        MakeNew,           // reset back to new from any state
        StartAnimation,    // animation requests a start
        RestartAnimation,  // force a restart from any state
        StartTimerFired,   // start timer fired
        StyleAvailable,    // style is setup, ready to start animating
        StartTimeSet,      // m_startTime was set
        LoopTimerFired,    // loop timer fired
        EndTimerFired,     // end timer fired
        PauseOverride,     // pause an animation due to override
        ResumeOverride,    // resume an overridden animation
        PlayStateRunning,  // play state paused -> running
        PlayStatePaused,   // play state running -> paused
        EndAnimation       // force an end from any state
    };

    // Called when animation is in AnimationState::New to start animation
    void updateStateMachine(AnimationStateInput, double param);

    // Animation has actually started, at passed time
    void onAnimationStartResponse(MonotonicTime startTime)
    {
        updateStateMachine(AnimationStateInput::StartTimeSet, startTime.secondsSinceEpoch().seconds());
    }

    // Called to change to or from paused state
    void updatePlayState(AnimationPlayState);
    bool playStatePlaying() const;

    bool waitingToStart() const { return m_animationState == AnimationState::New || m_animationState == AnimationState::StartWaitTimer || m_animationState == AnimationState::PausedNew; }
    bool preActive() const
    {
        return m_animationState == AnimationState::New || m_animationState == AnimationState::StartWaitTimer || m_animationState == AnimationState::StartWaitStyleAvailable || m_animationState == AnimationState::StartWaitResponse;
    }

    bool postActive() const { return m_animationState == AnimationState::Done; }
    bool fillingForwards() const { return m_animationState == AnimationState::FillingForwards; }
    bool active() const { return !postActive() && !preActive(); }
    bool running() const { return !isNew() && !postActive(); }
    bool paused() const { return m_pauseTime || m_animationState == AnimationState::PausedNew; }

    static bool isPausedState(AnimationState state) { return state >= AnimationState::PausedNew && state <= AnimationState::PausedRun; }
    static bool isRunningState(AnimationState state) { return state >= AnimationState::StartWaitStyleAvailable && state < AnimationState::Done; }

    bool inPausedState() const { return isPausedState(m_animationState); }
    bool inRunningState() const { return isRunningState(m_animationState); }

    bool isNew() const { return m_animationState == AnimationState::New || m_animationState == AnimationState::PausedNew; }
    bool waitingForStartTime() const { return m_animationState == AnimationState::StartWaitResponse; }
    bool waitingForStyleAvailable() const { return m_animationState == AnimationState::StartWaitStyleAvailable; }

    bool isAccelerated() const override { return m_isAccelerated; }

    virtual Optional<Seconds> timeToNextService();

    double progress(double scale = 1, double offset = 0, const TimingFunction* = nullptr) const;

    virtual void getAnimatedStyle(std::unique_ptr<RenderStyle>& /*animatedStyle*/) = 0;

    virtual bool computeExtentOfTransformAnimation(LayoutRect&) const = 0;

    virtual bool shouldFireEvents() const { return false; }

    void fireAnimationEventsIfNeeded();

    bool animationsMatch(const Animation&) const;

    const Animation& animation() const { return m_animation; }
    void setAnimation(const Animation& animation) { m_animation = const_cast<Animation&>(animation); }

    // Return true if this animation is overridden. This will only be the case for
    // ImplicitAnimations and is used to determine whether or not we should force
    // set the start time. If an animation is overridden, it will probably not get
    // back the AnimationStateInput::StartTimeSet input.
    virtual bool overridden() const { return false; }

    // Does this animation/transition involve the given property?
    virtual bool affectsProperty(CSSPropertyID /*property*/) const { return false; }

    bool isAnimatingProperty(CSSPropertyID property, bool acceleratedOnly) const
    {
        if (acceleratedOnly && !m_isAccelerated)
            return false;

        if (!affectsProperty(property))
            return false;

        return inRunningState() || inPausedState();
    }

    bool transformFunctionListsMatch() const override { return m_transformFunctionListsMatch; }
    bool filterFunctionListsMatch() const override { return m_filterFunctionListsMatch; }
#if ENABLE(FILTERS_LEVEL_2)
    bool backdropFilterFunctionListsMatch() const override { return m_backdropFilterFunctionListsMatch; }
#endif
    bool colorFilterFunctionListsMatch() const override { return m_colorFilterFunctionListsMatch; }

    // Freeze the animation; used by DumpRenderTree.
    void freezeAtTime(double t);

    // Play and pause API
    void play();
    void pause();
    
    double beginAnimationUpdateTime() const;
    
    double getElapsedTime() const;
    // Setting the elapsed time will adjust the start time and possibly pause time.
    void setElapsedTime(double);
    
    void styleAvailable() 
    {
        ASSERT(waitingForStyleAvailable());
        updateStateMachine(AnimationStateInput::StyleAvailable, -1);
    }

protected:
    virtual void overrideAnimations() { }
    virtual void resumeOverriddenAnimations() { }

    CompositeAnimation* compositeAnimation() { return m_compositeAnimation; }

    // These are called when the corresponding timer fires so subclasses can do any extra work
    virtual void onAnimationStart(double /*elapsedTime*/) { }
    virtual void onAnimationIteration(double /*elapsedTime*/) { }
    virtual void onAnimationEnd(double /*elapsedTime*/) { }
    
    // timeOffset is an offset from the current time when the animation should start. Negative values are OK.
    // Return value indicates whether to expect an asynchronous notifyAnimationStarted() callback.
    virtual bool startAnimation(double /*timeOffset*/) { return false; }
    // timeOffset is the time at which the animation is being paused.
    virtual void pauseAnimation(double /*timeOffset*/) { }
    virtual void endAnimation(bool /*fillingForwards*/ = false) { }

    virtual const RenderStyle& unanimatedStyle() const = 0;

    void goIntoEndingOrLoopingState();

    AnimationState state() const { return m_animationState; }

    static void setNeedsStyleRecalc(Element*);
    
    void getTimeToNextEvent(Seconds& time, bool& isLooping) const;

    double fractionalTime(double scale, double elapsedTime, double offset) const;

    // These return true if we can easily compute a bounding box by applying the style's transform to the bounds rect.
    bool computeTransformedExtentViaTransformList(const FloatRect& rendererBox, const RenderStyle&, LayoutRect& bounds) const;
    bool computeTransformedExtentViaMatrix(const FloatRect& rendererBox, const RenderStyle&, LayoutRect& bounds) const;

protected:
    bool m_isAccelerated { false };
    bool m_transformFunctionListsMatch { false };
    bool m_filterFunctionListsMatch { false };
#if ENABLE(FILTERS_LEVEL_2)
    bool m_backdropFilterFunctionListsMatch { false };
#endif

private:
    RefPtr<Element> m_element;

protected:
    CompositeAnimation* m_compositeAnimation; // Ideally this would be a reference, but it has to be cleared if an animation is destroyed inside an event callback.
    Ref<Animation> m_animation;

    Optional<double> m_startTime;
    Optional<double> m_pauseTime;
    double m_requestedStartTime { 0 };
    Optional<double> m_totalDuration;
    Optional<double> m_nextIterationDuration;

    AnimationState m_animationState { AnimationState::New };
    bool m_colorFilterFunctionListsMatch { false };
};

} // namespace WebCore
