#include "rive/animation/linear_animation.hpp"
#include "rive/animation/keyed_callback_reporter.hpp"
#include "rive/animation/keyed_object.hpp"
#include "rive/artboard.hpp"
#include "rive/importers/artboard_importer.hpp"
#include "rive/importers/import_stack.hpp"
#include "rive/math/math_types.hpp"
#include <cmath>

using namespace rive;

#ifdef TESTING
int LinearAnimation::deleteCount = 0;
#endif

LinearAnimation::LinearAnimation() {}

LinearAnimation::~LinearAnimation() {
#ifdef TESTING
  deleteCount++;
#endif
}

StatusCode LinearAnimation::onAddedDirty(CoreContext *context) {
  StatusCode code;
  for (const auto &object : m_KeyedObjects) {
    if ((code = object->onAddedDirty(context)) != StatusCode::Ok) {
      return code;
    }
  }
  return StatusCode::Ok;
}

StatusCode LinearAnimation::onAddedClean(CoreContext *context) {
  StatusCode code;
  for (const auto &object : m_KeyedObjects) {
    if ((code = object->onAddedClean(context)) != StatusCode::Ok) {
      return code;
    }
  }
  return StatusCode::Ok;
}

void LinearAnimation::addKeyedObject(std::unique_ptr<KeyedObject> object) {
  m_KeyedObjects.push_back(std::move(object));
}

void LinearAnimation::apply(Artboard *artboard, float time, float mix) const {
#ifdef WITH_RECORDER
//   if (Artboard::isDebug) {
//     printf("[RECORDER_LOG] LinearAnimation::apply: %f to %s for artboard: %s\n",
//            time, name().c_str(), artboard->name().c_str());
//   }
#endif
  if (quantize()) {
    float ffps = (float)fps();
    time = std::floor(time * ffps) / ffps;
  }
  for (const auto &object : m_KeyedObjects) {
    object->apply(artboard, time, mix);
  }
}

StatusCode LinearAnimation::import(ImportStack &importStack) {
  auto artboardImporter =
      importStack.latest<ArtboardImporter>(ArtboardBase::typeKey);
  if (artboardImporter == nullptr) {
    return StatusCode::MissingObject;
  }
  artboardImporter->addAnimation(this);
  return Super::import(importStack);
}

float LinearAnimation::startSeconds() const {
  return (enableWorkArea() ? (float)workStart() : 0.0f) / (float)fps();
}
float LinearAnimation::endSeconds() const {
  return (float)(enableWorkArea() ? workEnd() : duration()) / (float)fps();
}

float LinearAnimation::startTime() const {
  return (speed() >= 0) ? startSeconds() : endSeconds();
}
float LinearAnimation::startTime(float multiplier) const {
  return ((speed() * multiplier) >= 0) ? startSeconds() : endSeconds();
}
float LinearAnimation::endTime() const {
  return (speed() >= 0) ? endSeconds() : startSeconds();
}
float LinearAnimation::durationSeconds() const {
  return std::abs(endSeconds() - startSeconds());
}

// Matches Dart modulus:
// https://api.dart.dev/stable/2.19.0/dart-core/double/operator_modulo.html
static float positiveMod(float value, float range) {
  assert(range > 0.0f);
  return math::positive_mod(value, range);
}

float LinearAnimation::globalToLocalSeconds(float seconds) const {
  switch (loop()) {
  case Loop::oneShot:
    return seconds + startTime();
  case Loop::loop:
    return positiveMod(seconds, (durationSeconds())) + startTime();
  case Loop::pingPong:
    float localTime = positiveMod(seconds, (durationSeconds()));
    int direction = ((int)(seconds / (durationSeconds()))) % 2;
    return direction == 0 ? localTime + startTime() : endTime() - localTime;
  }
  RIVE_UNREACHABLE();
}

void LinearAnimation::reportKeyedCallbacks(KeyedCallbackReporter *reporter,
                                           float secondsFrom, float secondsTo,
                                           float speedDirection,
                                           bool fromPong) const {
  float startingTime = startTime(speedDirection);
  bool isAtStartFrame = startingTime == secondsFrom;

  if (!isAtStartFrame || !fromPong) {
    for (const auto &object : m_KeyedObjects) {
      object->reportKeyedCallbacks(reporter, secondsFrom, secondsTo,
                                   isAtStartFrame);
    }
  }
}