#include "rive/constraints/transform_constraint.hpp"
#include "rive/transform_component.hpp"
#include "rive/math/mat2d.hpp"
#include "rive/math/math_types.hpp"
#include "rive/math/aabb.hpp"

using namespace rive;

const Mat2D TransformConstraint::targetTransform() const
{
    auto* tgt = target();
    AABB bounds = tgt->constraintBounds();
    Mat2D local =
        Mat2D::fromTranslate(bounds.left() + bounds.width() * originX(),
                             bounds.top() + bounds.height() * originY());
    return tgt->worldTransform() * local;
}

void TransformConstraint::originXChanged() { markConstraintDirty(); }

void TransformConstraint::originYChanged() { markConstraintDirty(); }

void TransformConstraint::constrain(TransformComponent* component)
{
    auto* tgt = target();
    if (tgt == nullptr || tgt->isCollapsed())
    {
        return;
    }

    const Mat2D& transformA = component->worldTransform();
    Mat2D transformB(targetTransform());
    if (sourceSpace() == TransformSpace::local)
    {
        const Mat2D& targetParentWorld = getParentWorld(*tgt);

        Mat2D inverse;
        if (!targetParentWorld.invert(&inverse))
        {
            return;
        }
        transformB = inverse * transformB;
    }
    if (destSpace() == TransformSpace::local)
    {
        const Mat2D& targetParentWorld = getParentWorld(*component);
        transformB = targetParentWorld * transformB;
    }

    TransformConstraint::constrainWorld(component,
                                        transformA,
                                        m_ComponentsA,
                                        transformB,
                                        m_ComponentsB,
                                        strength());
    // Only here: constrainWorld is also the scroll constraints' generic blend,
    // and they target their own transform plus a delta, with no anchor to land.
    landAnchor(component, strength());
}

void TransformConstraint::constrainWorld(TransformComponent* component,
                                         Mat2D from,
                                         TransformComponents componentsFrom,
                                         Mat2D to,
                                         TransformComponents componentsTo,
                                         float strength)
{
    componentsFrom = from.decompose();
    componentsTo = to.decompose();

    float angleA = std::fmod(componentsFrom.rotation(), math::PI * 2);
    float angleB = std::fmod(componentsTo.rotation(), math::PI * 2);
    float diff = angleB - angleA;
    if (diff > math::PI)
    {
        diff -= math::PI * 2;
    }
    else if (diff < -math::PI)
    {
        diff += math::PI * 2;
    }

    float t = strength;
    float ti = 1.0f - t;

    componentsTo.rotation(angleA + diff * t);
    componentsTo.x(componentsFrom.x() * ti + componentsTo.x() * t);
    componentsTo.y(componentsFrom.y() * ti + componentsTo.y() * t);
    componentsTo.scaleX(componentsFrom.scaleX() * ti +
                        componentsTo.scaleX() * t);
    componentsTo.scaleY(componentsFrom.scaleY() * ti +
                        componentsTo.scaleY() * t);
    componentsTo.skew(componentsFrom.skew() * ti + componentsTo.skew() * t);

    component->mutableWorldTransform() = Mat2D::compose(componentsTo);
}