#include "rive/animation/keyframe_double.hpp"
#include "rive/generated/core_registry.hpp"
#include "rive/animation/linear_animation_instance.hpp"
#include "rive/animation/blend_accumulator.hpp"
#include "rive/data_bind/bindable_property_number.hpp"

using namespace rive;

// This whole class is intentionally misnamed to match our editor code. The
// editor uses doubles (float64) for numeric values but at runtime 32 bit
// floating point numbers suffice. So even though this is a "double keyframe" to
// match editor names, the actual values are stored and applied in 32 bits.

static void applyDouble(Core* object, int propertyKey, float mix, float value)
{
    // Single setter — mirrors the Dart editor where the call site
    // doesn't choose between animation-mode and design-mode paths.
    // Generated `<name>(value)` setters internally consult
    // `Core::isAnimationContextActive()`: when EditorFile has the
    // animation context active they route the write to the
    // per-property override overlay; otherwise to the persistent
    // static field. Runtime builds compile out the overlay branch
    // entirely.
    if (mix == 1.0f)
    {
        CoreRegistry::setDouble(object, propertyKey, value);
    }
    else
    {
        float mixi = 1.0f - mix;
        CoreRegistry::setDouble(
            object,
            propertyKey,
            CoreRegistry::getDouble(object, propertyKey) * mixi + value * mix);
    }
}

float KeyFrameDouble::effectiveValue(
    const LinearAnimationInstance* context) const
{
    if (context != nullptr)
    {
        if (auto* holder = context->keyFrameValueHolder(this))
        {
            return holder->as<BindablePropertyNumber>()->propertyValue();
        }
    }
    return value();
}

void KeyFrameDouble::apply(Core* object,
                           int propertyKey,
                           float mix,
                           const LinearAnimationInstance* context)
{
    if (context != nullptr && context->blendAccumulator() != nullptr)
    {
        context->blendAccumulator()->applyDouble(object,
                                                 propertyKey,
                                                 mix,
                                                 effectiveValue(context));
        return;
    }
    applyDouble(object, propertyKey, mix, effectiveValue(context));
}

void KeyFrameDouble::applyInterpolation(Core* object,
                                        int propertyKey,
                                        float currentTime,
                                        const KeyFrame* nextFrame,
                                        float mix,
                                        const LinearAnimationInstance* context)
{
    auto kfd = nextFrame->as<KeyFrameDouble>();
    const KeyFrameDouble& nextDouble = *kfd;
    float fromValue = effectiveValue(context);
    float toValue = nextDouble.effectiveValue(context);
    float f = (currentTime - seconds()) / (nextDouble.seconds() - seconds());

    float frameValue;
    if (KeyFrameInterpolator* keyframeInterpolator =
            effectiveInterpolator(context))
    {
        frameValue =
            keyframeInterpolator->transformValue(fromValue, toValue, f);
    }
    else
    {
        frameValue = fromValue + (toValue - fromValue) * f;
    }

    if (context != nullptr && context->blendAccumulator() != nullptr)
    {
        context->blendAccumulator()->applyDouble(object,
                                                 propertyKey,
                                                 mix,
                                                 frameValue);
        return;
    }
    applyDouble(object, propertyKey, mix, frameValue);
}
