#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;
}
