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

using namespace rive;

LinearAnimationInstance::LinearAnimationInstance(const LinearAnimation* animation,
                                                 ArtboardInstance* instance) :
    Scene(instance),
    m_Animation(animation),
    m_Time(animation->enableWorkArea() ? (float)animation->workStart() / animation->fps() : 0),
    m_TotalTime(0.0f),
    m_LastTotalTime(0.0f),
    m_SpilledTime(0.0f),
    m_Direction(1)
{
    Counter::update(Counter::kLinearAnimationInstance, +1);
}

LinearAnimationInstance::~LinearAnimationInstance() {
    Counter::update(Counter::kLinearAnimationInstance, -1);
}

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

bool LinearAnimationInstance::advance(float elapsedSeconds) {
    const LinearAnimation& animation = *m_Animation;
    m_Time += elapsedSeconds * animation.speed() * m_Direction;
    m_LastTotalTime = m_TotalTime;
    m_TotalTime += elapsedSeconds;

    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 keepGoing = true;
    bool didLoop = false;
    m_SpilledTime = 0.0f;

    switch (loop()) {
        case Loop::oneShot:
            if (m_Direction == 1 && frames > end) {
                keepGoing = false;
                m_SpilledTime = (frames - end) / fps;
                frames = end;
                m_Time = frames / fps;
                didLoop = true;
            } else if (m_Direction == -1 && frames < start) {
                keepGoing = false;
                m_SpilledTime = (start - frames) / fps;
                frames = start;
                m_Time = frames / fps;
                didLoop = true;
            }
            break;
        case Loop::loop:
            if (m_Direction == 1 && frames >= end) {
                m_SpilledTime = (frames - end) / fps;
                frames = m_Time * fps;
                frames = start + std::fmod(frames - start, (float)range);

                m_Time = frames / fps;
                didLoop = true;
            } else if (m_Direction == -1 && frames <= start) {

                m_SpilledTime = (start - frames) / fps;
                frames = m_Time * fps;
                frames = end - std::abs(std::fmod(start - frames, (float)range));
                m_Time = frames / fps;
                didLoop = true;
            }
            break;
        case Loop::pingPong:
            while (true) {
                if (m_Direction == 1 && frames >= end) {
                    m_SpilledTime = (frames - end) / fps;
                    m_Direction = -1;
                    frames = end + (end - frames);
                    m_Time = frames / fps;
                    didLoop = true;
                } else if (m_Direction == -1 && frames < start) {
                    m_SpilledTime = (start - frames) / fps;
                    m_Direction = 1;
                    frames = start + (start - frames);
                    m_Time = frames / fps;
                    didLoop = true;
                } 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;
                }
            }
            break;
    }

    m_DidLoop = didLoop;
    return keepGoing;
}

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;
}

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::startSeconds() const { return m_Animation->startSeconds(); }

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(); }
