/*
 * Copyright (C) 2017-2018 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
 * 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.
 */

#include "config.h"
#include "AnimationEffectReadOnly.h"

#include "AnimationEffectTimingReadOnly.h"
#include "FillMode.h"
#include "JSComputedTimingProperties.h"
#include "WebAnimationUtilities.h"

namespace WebCore {

AnimationEffectReadOnly::AnimationEffectReadOnly(ClassType classType, Ref<AnimationEffectTimingReadOnly>&& timing)
    : m_classType(classType)
    , m_timing(WTFMove(timing))
{
    m_timing->setEffect(this);
}

AnimationEffectReadOnly::~AnimationEffectReadOnly()
{
    m_timing->setEffect(nullptr);
}

void AnimationEffectReadOnly::timingDidChange()
{
    if (m_animation)
        m_animation->timingModelDidChange();
}

std::optional<Seconds> AnimationEffectReadOnly::localTime() const
{
    if (m_animation)
        return m_animation->currentTime();
    return std::nullopt;
}

auto AnimationEffectReadOnly::phase() const -> Phase
{
    // 3.5.5. Animation effect phases and states
    // https://drafts.csswg.org/web-animations-1/#animation-effect-phases-and-states

    bool animationIsBackwards = m_animation && m_animation->playbackRate() < 0;
    auto beforeActiveBoundaryTime = std::max(std::min(m_timing->delay(), m_timing->endTime()), 0_s);
    auto activeAfterBoundaryTime = std::max(std::min(m_timing->delay() + m_timing->activeDuration(), m_timing->endTime()), 0_s);

    // (This should be the last statement, but it's more efficient to cache the local time and return right away if it's not resolved.)
    // Furthermore, it is often convenient to refer to the case when an animation effect is in none of the above phases
    // as being in the idle phase.
    auto effectLocalTime = localTime();
    if (!effectLocalTime)
        return Phase::Idle;

    auto localTimeValue = effectLocalTime.value();

    // An animation effect is in the before phase if the animation effect’s local time is not unresolved and
    // either of the following conditions are met:
    //     1. the local time is less than the before-active boundary time, or
    //     2. the animation direction is ‘backwards’ and the local time is equal to the before-active boundary time.
    if ((localTimeValue + timeEpsilon) < beforeActiveBoundaryTime || (animationIsBackwards && std::abs(localTimeValue.microseconds() - beforeActiveBoundaryTime.microseconds()) < timeEpsilon.microseconds()))
        return Phase::Before;

    // An animation effect is in the after phase if the animation effect’s local time is not unresolved and
    // either of the following conditions are met:
    //     1. the local time is greater than the active-after boundary time, or
    //     2. the animation direction is ‘forwards’ and the local time is equal to the active-after boundary time.
    if ((localTimeValue - timeEpsilon) > activeAfterBoundaryTime || (!animationIsBackwards && std::abs(localTimeValue.microseconds() - activeAfterBoundaryTime.microseconds()) < timeEpsilon.microseconds()))
        return Phase::After;

    // An animation effect is in the active phase if the animation effect’s local time is not unresolved and it is not
    // in either the before phase nor the after phase.
    // (No need to check, we've already established that local time was resolved).
    return Phase::Active;
}

std::optional<Seconds> AnimationEffectReadOnly::activeTime() const
{
    // 3.8.3.1. Calculating the active time
    // https://drafts.csswg.org/web-animations-1/#calculating-the-active-time

    // The active time is based on the local time and start delay. However, it is only defined
    // when the animation effect should produce an output and hence depends on its fill mode
    // and phase as follows,

    auto effectPhase = phase();

    // If the animation effect is in the before phase, the result depends on the first matching
    // condition from the following,
    if (effectPhase == Phase::Before) {
        // If the fill mode is backwards or both, return the result of evaluating
        // max(local time - start delay, 0).
        if (m_timing->fill() == FillMode::Backwards || m_timing->fill() == FillMode::Both)
            return std::max(localTime().value() - m_timing->delay(), 0_s);
        // Otherwise, return an unresolved time value.
        return std::nullopt;
    }

    // If the animation effect is in the active phase, return the result of evaluating local time - start delay.
    if (effectPhase == Phase::Active)
        return localTime().value() - m_timing->delay();

    // If the animation effect is in the after phase, the result depends on the first matching
    // condition from the following,
    if (effectPhase == Phase::After) {
        // If the fill mode is forwards or both, return the result of evaluating
        // max(min(local time - start delay, active duration), 0).
        if (m_timing->fill() == FillMode::Forwards || m_timing->fill() == FillMode::Both)
            return std::max(std::min(localTime().value() - m_timing->delay(), m_timing->activeDuration()), 0_s);
        // Otherwise, return an unresolved time value.
        return std::nullopt;
    }

    // Otherwise (the local time is unresolved), return an unresolved time value.
    return std::nullopt;
}

std::optional<double> AnimationEffectReadOnly::overallProgress() const
{
    // 3.8.3.2. Calculating the overall progress
    // https://drafts.csswg.org/web-animations-1/#calculating-the-overall-progress

    // The overall progress describes the number of iterations that have completed (including partial iterations) and is defined as follows:

    // 1. If the active time is unresolved, return unresolved.
    auto effectActiveTime = activeTime();
    if (!effectActiveTime)
        return std::nullopt;

    // 2. Calculate an initial value for overall progress based on the first matching condition from below,
    double overallProgress;

    if (!m_timing->iterationDuration()) {
        // If the iteration duration is zero, if the animation effect is in the before phase, let overall progress be zero,
        // otherwise, let it be equal to the iteration count.
        overallProgress = phase() == Phase::Before ? 0 : m_timing->iterations();
    } else {
        // Otherwise, let overall progress be the result of calculating active time / iteration duration.
        overallProgress = secondsToWebAnimationsAPITime(effectActiveTime.value()) / secondsToWebAnimationsAPITime(m_timing->iterationDuration());
    }

    // 3. Return the result of calculating overall progress + iteration start.
    overallProgress += m_timing->iterationStart();
    return std::abs(overallProgress);
}

std::optional<double> AnimationEffectReadOnly::simpleIterationProgress() const
{
    // 3.8.3.3. Calculating the simple iteration progress
    // https://drafts.csswg.org/web-animations-1/#calculating-the-simple-iteration-progress

    // The simple iteration progress is a fraction of the progress through the current iteration that
    // ignores transformations to the time introduced by the playback direction or timing functions
    // applied to the effect, and is calculated as follows:

    // 1. If the overall progress is unresolved, return unresolved.
    auto effectOverallProgress = overallProgress();
    if (!effectOverallProgress)
        return std::nullopt;

    // 2. If overall progress is infinity, let the simple iteration progress be iteration start % 1.0,
    // otherwise, let the simple iteration progress be overall progress % 1.0.
    double overallProgressValue = effectOverallProgress.value();
    double simpleIterationProgress = std::isinf(overallProgressValue) ? fmod(m_timing->iterationStart(), 1) : fmod(overallProgressValue, 1);

    // 3. If all of the following conditions are true,
    //
    // the simple iteration progress calculated above is zero, and
    // the animation effect is in the active phase or the after phase, and
    // the active time is equal to the active duration, and
    // the iteration count is not equal to zero.
    // let the simple iteration progress be 1.0.
    auto effectPhase = phase();
    if (!simpleIterationProgress && (effectPhase == Phase::Active || effectPhase == Phase::After) && std::abs(activeTime().value().microseconds() - m_timing->activeDuration().microseconds()) < timeEpsilon.microseconds() && m_timing->iterations())
        return 1;

    return simpleIterationProgress;
}

std::optional<double> AnimationEffectReadOnly::currentIteration() const
{
    // 3.8.4. Calculating the current iteration
    // https://drafts.csswg.org/web-animations-1/#calculating-the-current-iteration

    // The current iteration can be calculated using the following steps:

    // 1. If the active time is unresolved, return unresolved.
    if (!activeTime())
        return std::nullopt;

    // 2. If the animation effect is in the after phase and the iteration count is infinity, return infinity.
    if (phase() == Phase::After && std::isinf(m_timing->iterations()))
        return std::numeric_limits<double>::infinity();

    // 3. If the simple iteration progress is 1.0, return floor(overall progress) - 1.
    if (simpleIterationProgress().value() == 1)
        return floor(overallProgress().value()) - 1;

    // 4. Otherwise, return floor(overall progress).
    return floor(overallProgress().value());
}

AnimationEffectReadOnly::ComputedDirection AnimationEffectReadOnly::currentDirection() const
{
    // 3.9.1. Calculating the directed progress
    // https://drafts.csswg.org/web-animations-1/#calculating-the-directed-progress

    // If playback direction is normal, let the current direction be forwards.
    if (m_timing->direction() == PlaybackDirection::Normal)
        return AnimationEffectReadOnly::ComputedDirection::Forwards;
    
    // If playback direction is reverse, let the current direction be reverse.
    if (m_timing->direction() == PlaybackDirection::Reverse)
        return AnimationEffectReadOnly::ComputedDirection::Reverse;
    
    // Otherwise, let d be the current iteration.
    auto d = currentIteration().value();
    // If playback direction is alternate-reverse increment d by 1.
    if (m_timing->direction() == PlaybackDirection::AlternateReverse)
        d++;
    // If d % 2 == 0, let the current direction be forwards, otherwise let the current direction be reverse.
    // If d is infinity, let the current direction be forwards.
    if (std::isinf(d) || !fmod(d, 2))
        return AnimationEffectReadOnly::ComputedDirection::Forwards;
    return AnimationEffectReadOnly::ComputedDirection::Reverse;
}

std::optional<double> AnimationEffectReadOnly::directedProgress() const
{
    // 3.9.1. Calculating the directed progress
    // https://drafts.csswg.org/web-animations-1/#calculating-the-directed-progress

    // The directed progress is calculated from the simple iteration progress using the following steps:

    // 1. If the simple iteration progress is unresolved, return unresolved.
    auto effectSimpleIterationProgress = simpleIterationProgress();
    if (!effectSimpleIterationProgress)
        return std::nullopt;

    // 2. Calculate the current direction (we implement this as a separate method).

    // 3. If the current direction is forwards then return the simple iteration progress.
    if (currentDirection() == AnimationEffectReadOnly::ComputedDirection::Forwards)
        return effectSimpleIterationProgress.value();

    // Otherwise, return 1.0 - simple iteration progress.
    return 1 - effectSimpleIterationProgress.value();
}

std::optional<double> AnimationEffectReadOnly::transformedProgress() const
{
    // 3.10.1. Calculating the transformed progress
    // https://drafts.csswg.org/web-animations-1/#calculating-the-transformed-progress

    // The transformed progress is calculated from the directed progress using the following steps:
    //
    // 1. If the directed progress is unresolved, return unresolved.
    auto effectDirectedProgress = directedProgress();
    if (!effectDirectedProgress)
        return std::nullopt;

    auto effectDirectedProgressValue = effectDirectedProgress.value();

    if (auto iterationDuration = m_timing->iterationDuration().seconds()) {
        bool before = false;
        auto* timingFunction = m_timing->timingFunction();
        // 2. Calculate the value of the before flag as follows:
        if (is<StepsTimingFunction>(timingFunction)) {
            // 1. Determine the current direction using the procedure defined in §3.9.1 Calculating the directed progress.
            // 2. If the current direction is forwards, let going forwards be true, otherwise it is false.
            bool goingForwards = currentDirection() == AnimationEffectReadOnly::ComputedDirection::Forwards;
            // 3. The before flag is set if the animation effect is in the before phase and going forwards is true;
            //    or if the animation effect is in the after phase and going forwards is false.
            auto effectPhase = phase();
            before = (effectPhase == Phase::Before && goingForwards) || (effectPhase == Phase::After && !goingForwards);
        }

        // 3. Return the result of evaluating the animation effect’s timing function passing directed progress as the
        //    input progress value and before flag as the before flag.
        return timingFunction->transformTime(effectDirectedProgressValue, iterationDuration, before);
    }

    return effectDirectedProgressValue;
}

std::optional<double> AnimationEffectReadOnly::iterationProgress() const
{
    return transformedProgress();
}

ComputedTimingProperties AnimationEffectReadOnly::getComputedTiming()
{
    ComputedTimingProperties computedTiming;
    computedTiming.delay = m_timing->bindingsDelay();
    computedTiming.endDelay = m_timing->bindingsEndDelay();
    auto fillMode = m_timing->fill();
    computedTiming.fill = fillMode == FillMode::Auto ? FillMode::None : fillMode;
    computedTiming.iterationStart = m_timing->iterationStart();
    computedTiming.iterations = m_timing->iterations();
    computedTiming.duration = secondsToWebAnimationsAPITime(m_timing->iterationDuration());
    computedTiming.direction = m_timing->direction();
    computedTiming.easing = m_timing->easing();
    computedTiming.endTime = secondsToWebAnimationsAPITime(m_timing->endTime());
    computedTiming.activeDuration = secondsToWebAnimationsAPITime(m_timing->activeDuration());
    if (auto effectLocalTime = localTime())
        computedTiming.localTime = secondsToWebAnimationsAPITime(effectLocalTime.value());
    computedTiming.progress = iterationProgress();
    computedTiming.currentIteration = currentIteration();
    return computedTiming;
}

} // namespace WebCore
