#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 any dirt, make sure to mark the constrained
    // component dirty.
    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;
}
