#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);
}
