#include "rive/animation/linear_animation_instance.hpp"
#include "rive/animation/linear_animation.hpp"
#include "rive/animation/loop.hpp"
#include "rive/animation/keyed_callback_reporter.hpp"
#include <cmath>
#include <cassert>

using namespace rive;

LinearAnimationInstance::LinearAnimationInstance(const LinearAnimation* animation,
                                                 ArtboardInstance* instance,
                                                 float speedMultiplier) :
    Scene(instance),
    m_animation((assert(animation != nullptr), animation)),
    m_time((speedMultiplier >= 0) ? animation->startTime() : animation->endTime()),
    m_speedDirection((speedMultiplier >= 0) ? 1 : -1),
    m_totalTime(0.0f),
    m_lastTotalTime(0.0f),
    m_spilledTime(0.0f),
    m_direction(1)
{}

LinearAnimationInstance::LinearAnimationInstance(LinearAnimationInstance const& lhs) :
    Scene(lhs),
    m_animation(lhs.m_animation),
    m_time(lhs.m_time),
    m_speedDirection(lhs.m_speedDirection),
    m_totalTime(lhs.m_totalTime),
    m_lastTotalTime(lhs.m_lastTotalTime),
    m_spilledTime(lhs.m_spilledTime),
    m_direction(lhs.m_direction),
    m_didLoop(lhs.m_didLoop),
    m_loopValue(lhs.m_loopValue)
{}

LinearAnimationInstance::~LinearAnimationInstance() {}

bool LinearAnimationInstance::advanceAndApply(float seconds)
{
    bool more = this->advance(seconds, this);
    this->apply();
    m_artboardInstance->advance(seconds);
    return more;
}

bool LinearAnimationInstance::advance(float elapsedSeconds, KeyedCallbackReporter* reporter)
{
    const LinearAnimation& animation = *m_animation;
    float deltaSeconds = elapsedSeconds * animation.speed() * m_direction;
    m_spilledTime = 0.0f;
    if (deltaSeconds == 0)
    {
        m_didLoop = false;
        return true;
    }

    m_lastTotalTime = m_totalTime;
    m_totalTime += std::abs(deltaSeconds);

    // NOTE:
    // do not track spilled time, if our one shot loop is already completed.
    // stop gap before we move spilled tracking into state machine logic.
    bool killSpilledTime = !this->keepGoing(elapsedSeconds);

    float lastTime = m_time;
    m_time += deltaSeconds;
    if (reporter != nullptr)
    {
        animation.reportKeyedCallbacks(reporter, lastTime, m_time, m_speedDirection, false);
    }

    int fps = animation.fps();
    float frames = m_time * fps;
    int start = animation.enableWorkArea() ? animation.workStart() : 0;
    int end = animation.enableWorkArea() ? animation.workEnd() : animation.duration();
    int range = end - start;

    bool didLoop = false;

    // this has some issues when deltaSeconds is 0,
    // right now we basically assume we default to going forwards in that case
    //
    int direction = deltaSeconds < 0 ? -1 : 1;
    switch (loop())
    {
        case Loop::oneShot:
            if (direction == 1 && frames > end)
            {
                // Account for the time dilation or contraction applied in the
                // animation local time by its speed to calculate spilled time.
                // Calculate the ratio of the time excess by the total elapsed
                // time in local time (deltaFrames) and multiply the elapsed time
                // by it.
                auto deltaFrames = deltaSeconds * fps;
                auto spilledFramesRatio = (frames - end) / deltaFrames;
                m_spilledTime = spilledFramesRatio * elapsedSeconds;
                frames = (float)end;
                m_time = frames / fps;
                didLoop = true;
            }
            else if (direction == -1 && frames < start)
            {
                auto deltaFrames = std::abs(deltaSeconds * fps);
                auto spilledFramesRatio = (start - frames) / deltaFrames;
                m_spilledTime = spilledFramesRatio * elapsedSeconds;
                frames = (float)start;
                m_time = frames / fps;
                didLoop = true;
            }
            break;
        case Loop::loop:
            if (direction == 1 && frames >= end)
            {
                // How spilled time has to be calculated, given that local time can be scaled
                // to a factor of the regular time:
                // - for convenience, calculate the local elapsed time in frames (deltaFrames)
                // - get the remainder of current frame position (frames) by duration (range)
                // - use that remainder as the ratio of the original time that was not consumed
                // by the loop (spilledFramesRatio)
                // - multiply the original elapsedTime by the ratio to set the spilled time
                auto deltaFrames = deltaSeconds * fps;
                auto remainder = std::fmod(frames - start, (float)range);
                auto spilledFramesRatio = remainder / deltaFrames;
                m_spilledTime = spilledFramesRatio * elapsedSeconds;
                frames = start + remainder;
                m_time = frames / fps;
                didLoop = true;
                if (reporter != nullptr)
                {
                    animation.reportKeyedCallbacks(reporter, 0.0f, m_time, m_speedDirection, false);
                }
            }
            else if (direction == -1 && frames <= start)
            {
                auto deltaFrames = deltaSeconds * fps;
                auto remainder = std::abs(std::fmod(start - frames, (float)range));
                auto spilledFramesRatio = std::abs(remainder / deltaFrames);
                m_spilledTime = spilledFramesRatio * elapsedSeconds;
                frames = end - remainder;
                m_time = frames / fps;
                didLoop = true;
                if (reporter != nullptr)
                {
                    animation.reportKeyedCallbacks(reporter,
                                                   end / (float)fps,
                                                   m_time,
                                                   m_speedDirection,
                                                   false);
                }
            }
            break;
        case Loop::pingPong:
            bool fromPong = true;
            while (true)
            {
                if (direction == 1 && frames >= end)
                {
                    m_spilledTime = (frames - end) / fps;
                    frames = end + (end - frames);
                    lastTime = end / (float)fps;
                }
                else if (direction == -1 && frames < start)
                {
                    m_spilledTime = (start - frames) / fps;
                    frames = start + (start - frames);
                    lastTime = start / (float)fps;
                }
                else
                {
                    // we're within the range, we can stop fixing. We do this in
                    // a loop to fix conditions when time has advanced so far
                    // that we've ping-ponged back and forth a few times in a
                    // single frame. We want to accomodate for this in cases
                    // where animations are not advanced on regular intervals.
                    break;
                }
                m_time = frames / fps;
                m_direction *= -1;
                direction *= -1;
                didLoop = true;
                if (reporter != nullptr)
                {
                    animation.reportKeyedCallbacks(reporter,
                                                   lastTime,
                                                   m_time,
                                                   m_speedDirection,
                                                   fromPong);
                }
                fromPong = !fromPong;
            }
            break;
    }

    if (killSpilledTime)
    {
        m_spilledTime = 0;
    }

    m_didLoop = didLoop;
    return this->keepGoing(elapsedSeconds);
}

void LinearAnimationInstance::time(float value)
{
    if (m_time == value)
    {
        return;
    }
    m_time = value;
    // Make sure to keep last and total in relative lockstep so state machines
    // can track change even when setting time.
    auto diff = m_totalTime - m_lastTotalTime;

    int start = (m_animation->enableWorkArea() ? m_animation->workStart() : 0) * m_animation->fps();
    m_totalTime = value - start;
    m_lastTotalTime = m_totalTime - diff;

    // leaving this RIGHT now. but is this required? it kinda messes up
    // playing things backwards and seeking. what purpose does it solve?
    m_direction = 1;
}

void LinearAnimationInstance::reset(float speedMultiplier = 1.0)
{
    m_time = (speedMultiplier >= 0) ? m_animation->startTime() : m_animation->endTime();
}

uint32_t LinearAnimationInstance::fps() const { return m_animation->fps(); }

uint32_t LinearAnimationInstance::duration() const { return m_animation->duration(); }

float LinearAnimationInstance::speed() const { return m_animation->speed(); }

float LinearAnimationInstance::startTime() const { return m_animation->startTime(); }

std::string LinearAnimationInstance::name() const { return m_animation->name(); }

bool LinearAnimationInstance::isTranslucent() const
{
    return m_artboardInstance->isTranslucent(this);
}

// Returns either the animation's default or overridden loop values
int LinearAnimationInstance::loopValue() const
{
    if (m_loopValue != -1)
    {
        return m_loopValue;
    }
    return m_animation->loopValue();
}

// Override the animation's loop value
void LinearAnimationInstance::loopValue(int value)
{
    if (m_loopValue == value)
    {
        return;
    }
    if (m_loopValue == -1 && m_animation->loopValue() == value)
    {
        return;
    }
    m_loopValue = value;
}

float LinearAnimationInstance::durationSeconds() const { return m_animation->durationSeconds(); }

void LinearAnimationInstance::reportEvent(Event* event, float secondsDelay)
{
    const std::vector<Event*> events{event};
    notifyListeners(events);
}