#include "rive/shapes/paint/feather.hpp"
#include "rive/shapes/paint/shape_paint.hpp"
#include "rive/shapes/paint/fill.hpp"
#include "rive/shapes/shape.hpp"
#include "rive/artboard.hpp"

#include "rive/core_context.hpp"

using namespace rive;

bool Feather::validate(CoreContext* context)
{
  if (!Super::validate(context))
  {
    return false;
  }
  auto coreObject = context->resolve(parentId());
  // we know it's not nullptr from Super::validate
  assert(coreObject != nullptr);
  return coreObject->is<ShapePaint>();
}

StatusCode Feather::onAddedDirty(CoreContext* context)
{
  auto code = Super::onAddedDirty(context);

#ifndef WITH_RIVE_EDITOR
  // Runtime-only; editor build registers via editorParentChanged.
  parent()->as<ShapePaint>()->feather(this);
#endif
  return code;
}

bool Feather::isInner() const
{
  return inner() && parent() != nullptr && parent()->is<Fill>();
}

void Feather::update(ComponentDirt value)
{
  auto shapePaint = parent()->as<ShapePaint>();
  if (hasDirt(value, ComponentDirt::Paint))
  {
    auto renderPaint = shapePaint->renderPaint();
#ifdef WITH_RIVE_EDITOR
    // Editor files can carry ShapePaints whose mutator init
    // failed (e.g. a Fill with multiple SolidColor children — only
    // the first wins, the rest leave `m_renderPaint` null). The
    // runtime importer rejects such files; coop hydration accepts
    // them. Skip the apply rather than null-deref the vtable.
    if (renderPaint == nullptr)
      return;
#endif
    renderPaint->feather(strength());
  }

  if (hasDirt(value, ComponentDirt::WorldTransform | ComponentDirt::Path))
  {
    bool offsetInArtboard = space() == TransformSpace::world;
    if (isInner())
    {
      auto shape = ShapePaintContainer::from(shapePaint->parent());

      if (shape != nullptr)
      {
        auto transform = shape->shapeWorldTransform();
        auto path = shapePaint->pickPath(shape);
        if (path == nullptr)
        {
          return;
        }
        rebuildInnerPath(path, transform, offsetInArtboard);
        // Mark dirty so draw() re-applies the effect path override if
        // one is active (update() only has the original shape path).
        m_effectPathDirty = true;
      }
#ifdef TESTING
      renderCount++;
#endif
      return;
    }
  }
}

void Feather::rebuildInnerPath(
    const ShapePaintPath* path,
    const Mat2D& shapeTransform,
    bool offsetInArtboard)
{
  m_effectPathDirty = false;
  auto bounds = path->rawPath()->bounds().pad(strength() * 1.5f);
  Vec2D innerOffset(offsetX(), offsetY());
  if (offsetInArtboard)
  {
    Mat2D inverseTransform = shapeTransform.invertOrIdentity();
    innerOffset = Vec2D::transformDir(innerOffset, inverseTransform);
  }
  m_innerPath.rewind();
  m_innerPath.addRect(bounds);
  Mat2D innerOffsetTransform = Mat2D::fromTranslation(innerOffset);
  m_innerPath.addPathBackwards(*path->rawPath(), &innerOffsetTransform);
}

void Feather::buildDependencies()
{
  auto shape = parent()->as<ShapePaint>()->parent();
  if (shape == nullptr)
  {
    return;
  }
  if (shape->is<Shape>())
  {
    shape->as<Shape>()->pathComposer()->addDependent(this);
  }
  else
  {
    shape->addDependent(this);
  }
}

void Feather::strengthChanged()
{
  addDirt(
      inner() ? (ComponentDirt)(ComponentDirt::Paint |
                                ComponentDirt::WorldTransform)
              : ComponentDirt::Paint);
}
void Feather::offsetXChanged() { strengthChanged(); }
void Feather::offsetYChanged() { strengthChanged(); }

// The inner path is only built while inner, so switching to inner has to
// rebuild it (it's empty, or stale if the shape changed while outer).
void Feather::innerChanged()
{
  addDirt(ComponentDirt::Paint | ComponentDirt::WorldTransform);
}