#include "rive/animation/keyed_object.hpp"
#include "rive/animation/keyed_property.hpp"
#include "rive/animation/linear_animation.hpp"
#include "rive/artboard.hpp"
#include "rive/importers/linear_animation_importer.hpp"
#include "rive/generated/core_registry.hpp"

using namespace rive;

KeyedObject::KeyedObject() {}
KeyedObject::~KeyedObject() {}

void KeyedObject::addKeyedProperty(std::unique_ptr<KeyedProperty> property)
{
    m_keyedProperties.push_back(std::move(property));
}

StatusCode KeyedObject::onAddedDirty(CoreContext* context)
{
    // Make sure we're keying a valid object.
    if (context->resolve(objectId()) == nullptr)
    {
        return StatusCode::MissingObject;
    }

    for (auto& property : m_keyedProperties)
    {
        StatusCode code;
        if ((code = property->onAddedDirty(context)) != StatusCode::Ok)
        {
            return code;
        }
    }
    return StatusCode::Ok;
}

StatusCode KeyedObject::onAddedClean(CoreContext* context)
{
    for (auto& property : m_keyedProperties)
    {
        property->onAddedClean(context);
    }
    return StatusCode::Ok;
}

void KeyedObject::reportKeyedCallbacks(KeyedCallbackReporter* reporter,
                                       float secondsFrom,
                                       float secondsTo,
                                       int secondsFromExactOffset) const
{
    for (const std::unique_ptr<KeyedProperty>& property : m_keyedProperties)
    {
        if (!CoreRegistry::isCallback(property->propertyKey()))
        {
            continue;
        }
        property->reportKeyedCallbacks(reporter,
                                       objectId(),
                                       secondsFrom,
                                       secondsTo,
                                       secondsFromExactOffset);
    }
}

void KeyedObject::apply(Artboard* artboard, float time, float mix)
{
    Core* object = artboard->resolve(objectId());
    if (object == nullptr)
    {
        return;
    }
    for (std::unique_ptr<KeyedProperty>& property : m_keyedProperties)
    {
        if (CoreRegistry::isCallback(property->propertyKey()))
        {
            continue;
        }
        property->apply(object, time, mix);
    }
}

StatusCode KeyedObject::import(ImportStack& importStack)
{
    auto importer = importStack.latest<LinearAnimationImporter>(LinearAnimationBase::typeKey);
    if (importer == nullptr)
    {
        return StatusCode::MissingObject;
    }
    // we transfer ownership of ourself to the importer!
    importer->addKeyedObject(std::unique_ptr<KeyedObject>(this));
    return Super::import(importStack);
}