#include "rive/component_dirt.hpp"
#include "rive/assets/script_asset.hpp"
#include "rive/scripted/scripted_path_effect.hpp"
#include "rive/shapes/paint/stroke.hpp"

using namespace rive;

void ScriptedEffectPath::invalidateEffect() { m_path.rewind(); }

#ifdef WITH_RIVE_SCRIPTING

void ScriptedPathEffect::didHydrateScriptInputs()
{
  m_isAdvanceActive = true;
  addScriptedDirt(ComponentDirt::Paint, true);
#ifdef WITH_RIVE_EDITOR
  if (editorArena())
  {
    // Native hydration (and script reload) can happen after the first path
    // update. Rebuild the paint's effect chain now that the script is
    // ready.
    invalidateEffectFromLocal();
    if (parent())
      parent()->addDirt(ComponentDirt::Path);
  }
#endif
}

void ScriptedPathEffect::updateEffect(
    PathProvider* pathProvider,
    const ShapePaintPath* source,
    const ShapePaint* shapePaint)
{
  if (!updates())
  {
    return;
  }

  auto effectPathIt = m_effectPaths.find(pathProvider);
  if (effectPathIt != m_effectPaths.end())
  {
    auto trimEffectPath = static_cast<ScriptedEffectPath*>(
        effectPathIt->second);
    auto path = trimEffectPath->path();
    if (path->hasRenderPath())
    {
      // Previous result hasn't been invalidated, it's still good.
      return;
    }

    path->rewind(source->isLocal(), source->fillRule());
    if (m_vm == nullptr || !m_vm->valid())
    {
      return;
    }
    setInUpdatePhase(true);
    RawPath effectPath;
    if (!m_vm->callPathEffectUpdate(
            this,
            m_self,
            *source->rawPath(),
            shapePaint,
            &effectPath))
    {
      fprintf(stderr, "update function failed\n");
    }
    else
    {
      // Through ShapePaintPath, which prunes what the script returned.
      path->addPath(effectPath);
    }
    setInUpdatePhase(false);
  }
}
#else
void ScriptedPathEffect::updateEffect(
    PathProvider* pathProvider,
    const ShapePaintPath* source,
    const ShapePaint* shapePaint)
{}
#endif

StatusCode ScriptedPathEffect::onAddedDirty(CoreContext* context)
{
  auto code = Super::onAddedDirty(context);
  if (code != StatusCode::Ok)
  {
    return code;
  }
  artboard()->addScriptedObject(this);
  return StatusCode::Ok;
}

StatusCode ScriptedPathEffect::onAddedClean(CoreContext* context)
{
  auto effectsContainer = EffectsContainer::from(parent());
  if (!effectsContainer)
  {
    return StatusCode::InvalidObject;
  }
  effectsContainer->addStrokeEffect(this);

  return StatusCode::Ok;
}

bool ScriptedPathEffect::advanceComponent(
    float elapsedSeconds,
    AdvanceFlags flags)
{
  if (elapsedSeconds == 0)
  {
    return false;
  }
  if (!m_isAdvanceActive)
  {
    return false;
  }
  m_isAdvanceActive = false;
  if (!enums::is_flag_set(flags, AdvanceFlags::AdvanceNested))
  {
    elapsedSeconds = 0;
  }
  auto advanced = scriptAdvance(elapsedSeconds);
  if (advanced)
  {
    m_isAdvanceActive = true;
  }
  return advanced;
}

bool ScriptedPathEffect::addScriptedDirt(ComponentDirt value, bool recurse)
{
  return Component::addDirt(value, recurse);
}

void ScriptedPathEffect::addProperty(CustomProperty* prop)
{
  auto scriptInput = ScriptInput::from(prop);
  if (scriptInput != nullptr)
  {
    scriptInput->scriptedObject(this);
  }
  CustomPropertyContainer::addProperty(prop);
}

StatusCode ScriptedPathEffect::import(ImportStack& importStack)
{
  auto result = registerReferencer(importStack);
  if (result != StatusCode::Ok)
  {
    return result;
  }
  return Super::import(importStack);
}

Core* ScriptedPathEffect::clone() const
{
  ScriptedPathEffect* twin = ScriptedPathEffectBase::clone()
                                 ->as<ScriptedPathEffect>();
  if (m_fileAsset != nullptr)
  {
    twin->setAsset(m_fileAsset);
  }
  return twin;
}

void ScriptedPathEffect::markNeedsUpdate()
{
  if (inUpdatePhase())
  {
    return;
  }
  addScriptedDirt(ComponentDirt::ScriptUpdate);
}

EffectsContainer* ScriptedPathEffect::parentPaint()
{
  return EffectsContainer::from(parent());
}

EffectPath* ScriptedPathEffect::createEffectPath()
{
  return new ScriptedEffectPath();
}

void ScriptedPathEffect::buildDependencies()
{
  Super::buildDependencies();
  if (parent())
  {
    parent()->addDependent(this);
  }
}

void ScriptedPathEffect::update(ComponentDirt value)
{
  Super::update(value);

  if (hasDirt(value, ComponentDirt::ScriptUpdate))
  {
    invalidateEffectFromLocal();
    m_isAdvanceActive = true;
  }
}