#include "rive/animation/linear_animation.hpp"
#include "rive/animation/keyed_object.hpp"
#include "rive/artboard.hpp"
#include "rive/importers/artboard_importer.hpp"
#include "rive/importers/import_stack.hpp"
#include <cmath>

using namespace rive;

#ifdef TESTING
int LinearAnimation::deleteCount = 0;
#endif

LinearAnimation::LinearAnimation() {}

LinearAnimation::~LinearAnimation()
{
#ifdef TESTING
    deleteCount++;
#endif
}

StatusCode LinearAnimation::onAddedDirty(CoreContext* context)
{
    StatusCode code;
    for (const auto& object : m_KeyedObjects)
    {
        if ((code = object->onAddedDirty(context)) != StatusCode::Ok)
        {
            return code;
        }
    }
    return StatusCode::Ok;
}

StatusCode LinearAnimation::onAddedClean(CoreContext* context)
{
    StatusCode code;
    for (const auto& object : m_KeyedObjects)
    {
        if ((code = object->onAddedClean(context)) != StatusCode::Ok)
        {
            return code;
        }
    }
    return StatusCode::Ok;
}

void LinearAnimation::addKeyedObject(std::unique_ptr<KeyedObject> object)
{
    m_KeyedObjects.push_back(std::move(object));
}

void LinearAnimation::apply(Artboard* artboard, float time, float mix) const
{
    for (const auto& object : m_KeyedObjects)
    {
        object->apply(artboard, time, mix);
    }
}

StatusCode LinearAnimation::import(ImportStack& importStack)
{
    auto artboardImporter = importStack.latest<ArtboardImporter>(ArtboardBase::typeKey);
    if (artboardImporter == nullptr)
    {
        return StatusCode::MissingObject;
    }
    artboardImporter->addAnimation(this);
    return Super::import(importStack);
}

float LinearAnimation::startSeconds() const
{
    return (enableWorkArea() ? workStart() : 0) / (float)fps();
}
float LinearAnimation::endSeconds() const
{
    return (enableWorkArea() ? workEnd() : duration()) / (float)fps();
}

float LinearAnimation::startTime() const { return (speed() >= 0) ? startSeconds() : endSeconds(); }
float LinearAnimation::endTime() const { return (speed() >= 0) ? endSeconds() : startSeconds(); }
float LinearAnimation::durationSeconds() const { return std::abs(endSeconds() - startSeconds()); }

// Matches Dart modulus: https://api.dart.dev/stable/2.19.0/dart-core/double/operator_modulo.html
static float positiveMod(float value, float range)
{
    assert(range > 0.0f);
    float v = fmodf(value, range);
    if (v < 0.0f)
    {
        v += range;
    }
    return v;
}

float LinearAnimation::globalToLocalSeconds(float seconds) const
{
    switch (loop())
    {
        case Loop::oneShot:
            return seconds + startTime();
        case Loop::loop:
            return positiveMod(seconds, (durationSeconds())) + startTime();
        case Loop::pingPong:
            float localTime = positiveMod(seconds, (durationSeconds()));
            int direction = ((int)(seconds / (durationSeconds()))) % 2;
            return direction == 0 ? localTime + startTime() : endTime() - localTime;
    }
    RIVE_UNREACHABLE();
}