#include "rive/animation/keyed_property.hpp"
#include "rive/animation/keyed_object.hpp"
#include "rive/animation/keyframe.hpp"
#include "rive/importers/import_stack.hpp"
#include "rive/importers/keyed_object_importer.hpp"

using namespace rive;

KeyedProperty::~KeyedProperty() {
    for (auto keyframe : m_KeyFrames) {
        delete keyframe;
    }
}

void KeyedProperty::addKeyFrame(KeyFrame* keyframe) {
    m_KeyFrames.push_back(keyframe);
}

void KeyedProperty::apply(Core* object, float seconds, float mix) {
    assert(!m_KeyFrames.empty());

    int idx = 0;
    int mid = 0;
    float closestSeconds = 0.0f;
    int start = 0;
    auto numKeyFrames = static_cast<int>(m_KeyFrames.size());
    int end = numKeyFrames - 1;
    while (start <= end) {
        mid = (start + end) >> 1;
        closestSeconds = m_KeyFrames[mid]->seconds();
        if (closestSeconds < seconds) {
            start = mid + 1;
        } else if (closestSeconds > seconds) {
            end = mid - 1;
        } else {
            idx = start = mid;
            break;
        }
        idx = start;
    }
    int pk = propertyKey();

    if (idx == 0) {
        m_KeyFrames[0]->apply(object, pk, mix);
    } else {
        if (idx < numKeyFrames) {
            KeyFrame* fromFrame = m_KeyFrames[idx - 1];
            KeyFrame* toFrame = m_KeyFrames[idx];
            if (seconds == toFrame->seconds()) {
                toFrame->apply(object, pk, mix);
            } else {
                if (fromFrame->interpolationType() == 0) {
                    fromFrame->apply(object, pk, mix);
                } else {
                    fromFrame->applyInterpolation(
                        object, pk, seconds, toFrame, mix);
                }
            }
        } else {
            m_KeyFrames[idx - 1]->apply(object, pk, mix);
        }
    }
}

StatusCode KeyedProperty::onAddedDirty(CoreContext* context) {
    StatusCode code;
    for (auto keyframe : m_KeyFrames) {
        if ((code = keyframe->onAddedDirty(context)) != StatusCode::Ok) {
            return code;
        }
    }
    return StatusCode::Ok;
}

StatusCode KeyedProperty::onAddedClean(CoreContext* context) {
    StatusCode code;
    for (auto keyframe : m_KeyFrames) {
        if ((code = keyframe->onAddedClean(context)) != StatusCode::Ok) {
            return code;
        }
    }
    return StatusCode::Ok;
}

StatusCode KeyedProperty::import(ImportStack& importStack) {
    auto importer =
        importStack.latest<KeyedObjectImporter>(KeyedObjectBase::typeKey);
    if (importer == nullptr) {
        return StatusCode::MissingObject;
    }
    importer->addKeyedProperty(this);
    return Super::import(importStack);
}
