#include "rive/constraints/constraint.hpp"
#include "rive/container_component.hpp"
#include "rive/transform_component.hpp"
#include "rive/core_context.hpp"
#include "rive/math/mat2d.hpp"

using namespace rive;

StatusCode Constraint::onAddedDirty(CoreContext* context)
{
  StatusCode result = Super::onAddedDirty(context);
#ifndef WITH_RIVE_EDITOR
  // Runtime-only path; editor build registers via
  // `editorParentChanged` (dispatcher Pass 4.5).
  if (!parent()->is<TransformComponent>())
  {
    return StatusCode::InvalidObject;
  }

  parent()->as<TransformComponent>()->addConstraint(this);
#endif

  return result;
}

void Constraint::markConstraintDirty()
{
  parent()->as<TransformComponent>()->markTransformDirty();
}

void Constraint::strengthChanged() { markConstraintDirty(); }

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

void Constraint::onDirty(ComponentDirt dirt)
{
  // Whenever the constraint gets dirt that can move something, make sure to
  // mark the constrained component dirty. Render opacity alone can't. A fade
  // reaches every constraint through the component it constrains, and
  // re-constraining for it re-dirtied that component and everything under
  // it on every frame. Collapsed is a state this dirt keeps while we are
  // hidden, not work: we only collapse along with the component we
  // constrain, which doesn't update while collapsed either.
  if ((dirt & ~ComponentDirt::Collapsed) == ComponentDirt::RenderOpacity)
  {
    return;
  }
  markConstraintDirty();
}

static Mat2D identity;
const Mat2D& rive::getParentWorld(const TransformComponent& component)
{
  auto parent = component.parent();
  if (parent->is<WorldTransformComponent>())
  {
    return parent->as<WorldTransformComponent>()->worldTransform();
  }
  return identity;
}

void Constraint::composeKeepingAnchor(
    TransformComponent* component,
    const TransformComponents& composed)
{
  Mat2D& world = component->mutableWorldTransform();
  const Vec2D anchor = component->localAnchor();
  if (anchor.x == 0.0f && anchor.y == 0.0f)
  {
    world = Mat2D::compose(composed);
    return;
  }
  const Vec2D before = world * anchor;
  Mat2D result = Mat2D::compose(composed);
  const Vec2D after = result * anchor;
  result[4] += before.x - after.x;
  result[5] += before.y - after.y;
  world = result;
}

void Constraint::landAnchor(TransformComponent* component, float strength)
{
  const Vec2D anchor = component->localAnchor();
  if (anchor.x == 0.0f && anchor.y == 0.0f)
  {
    return;
  }
  Mat2D& world = component->mutableWorldTransform();
  world[4] -= (world[0] * anchor.x + world[2] * anchor.y) * strength;
  world[5] -= (world[1] * anchor.x + world[3] * anchor.y) * strength;
}

void Constraint::composeLandingAnchor(
    TransformComponent* component,
    const TransformComponents& composed,
    float strength)
{
  component->mutableWorldTransform() = Mat2D::compose(composed);
  landAnchor(component, strength);
}

Mat2D Constraint::offsetInParentFrame(
    TransformComponent* component,
    const Mat2D& offset)
{
  const Mat2D& parentWorld = getParentWorld(*component);
  const Vec2D delta = (parentWorld * offset).translation() -
                      parentWorld.translation();
  Mat2D result = component->worldTransform();
  result[4] += delta.x;
  result[5] += delta.y;
  return result;
}
