#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"

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

float LinearAnimation::globalToLocalSeconds(float seconds) const {
    switch (loop()) {
        case Loop::oneShot:
            return seconds + startSeconds();
        case Loop::loop:
            return std::fmod(seconds, (endSeconds() - startSeconds())) + startSeconds();
        case Loop::pingPong:
            float localTime = std::fmod(seconds, (endSeconds() - startSeconds()));
            int direction = ((int)(seconds / (endSeconds() - startSeconds()))) % 2;
            return direction == 0 ? localTime + startSeconds() : endSeconds() - localTime;
    }
}