#include "rive/animation/blend_accumulator.hpp"
#include "rive/generated/core_registry.hpp"

using namespace rive;

static uint32_t slotOf(const Core* object, int propertyKey)
{
  // Fibonacci hashing of the pointer, with the key folded in.
  uint64_t h = ((uint64_t)(uintptr_t)object ^
                ((uint64_t)(uint32_t)propertyKey << 48)) *
               UINT64_C(0x9E3779B97F4A7C15);
  return (uint32_t)(h >> 32);
}

uint32_t BlendAccumulator::find(Core* object, int propertyKey) const
{
  if (m_index.empty())
  {
    return 0;
  }
  const uint32_t mask = (uint32_t)m_index.size() - 1;
  for (uint32_t i = slotOf(object, propertyKey) & mask;; i = (i + 1) & mask)
  {
    uint32_t entry = m_index[i];
    if (entry == 0)
    {
      return 0;
    }
    const Value& value = m_values[entry - 1];
    if (value.object == object && value.propertyKey == propertyKey)
    {
      return entry;
    }
  }
}

void BlendAccumulator::index(uint32_t valueIndex)
{
  const uint32_t mask = (uint32_t)m_index.size() - 1;
  const Value& value = m_values[valueIndex];
  uint32_t i = slotOf(value.object, value.propertyKey) & mask;
  while (m_index[i] != 0)
  {
    i = (i + 1) & mask;
  }
  m_index[i] = valueIndex + 1;
}

BlendAccumulator::Value& BlendAccumulator::value(
    Core* object,
    int propertyKey,
    bool isColor,
    bool seeding)
{
  uint32_t entry = find(object, propertyKey);
  if (entry == 0)
  {
    m_values.push_back({object, propertyKey, isColor, 0, 0.0f, 0});
    if (m_values.size() * 2 > m_index.size())
    {
      m_index.assign(m_index.empty() ? 16 : m_index.size() * 2, 0);
      for (uint32_t i = 0; i < (uint32_t)m_values.size(); i++)
      {
        index(i);
      }
    }
    else
    {
      index((uint32_t)m_values.size() - 1);
    }
    entry = (uint32_t)m_values.size();
  }
  Value& value = m_values[entry - 1];
  if (value.frame != m_frame)
  {
    value.frame = m_frame;
    m_written.push_back(entry - 1);
    if (!seeding)
    {
      if (isColor)
      {
        value.colorValue = CoreRegistry::getColor(object, propertyKey);
      }
      else
      {
        value.doubleValue = CoreRegistry::getDouble(object, propertyKey);
      }
    }
  }
  return value;
}

void BlendAccumulator::seedDouble(Core* object, int propertyKey, float value)
{
  this->value(object, propertyKey, false, true).doubleValue = value;
}

void BlendAccumulator::seedColor(Core* object, int propertyKey, ColorInt value)
{
  this->value(object, propertyKey, true, true).colorValue = value;
}

void BlendAccumulator::applyDouble(
    Core* object,
    int propertyKey,
    float mix,
    float value)
{
  Value& current = this->value(object, propertyKey, false, false);
  if (mix == 1.0f)
  {
    current.doubleValue = value;
  }
  else
  {
    float mixi = 1.0f - mix;
    current.doubleValue = current.doubleValue * mixi + value * mix;
  }
}

void BlendAccumulator::applyColor(
    Core* object,
    int propertyKey,
    float mix,
    ColorInt value)
{
  Value& current = this->value(object, propertyKey, true, false);
  current.colorValue = mix == 1.0f ? value
                                   : colorLerp(current.colorValue, value, mix);
}

void BlendAccumulator::flush()
{
  for (uint32_t written : m_written)
  {
    const Value& value = m_values[written];
    if (value.isColor)
    {
      CoreRegistry::setColor(value.object, value.propertyKey, value.colorValue);
    }
    else
    {
      CoreRegistry::setDouble(
          value.object,
          value.propertyKey,
          value.doubleValue);
    }
  }
  m_written.clear();
  // Wrapping back to a frame some value still carries would skip loading
  // it, so start the count over with every value marked unwritten.
  if (++m_frame == 0)
  {
    for (Value& value : m_values)
    {
      value.frame = 0;
    }
    m_frame = 1;
  }
}
