#include "rive/animation/linear_animation_instance.hpp"
#include "rive/animation/linear_animation.hpp"
#include "rive/animation/loop.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) {}

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