#include "rive/transform_component.hpp"
#include "rive/world_transform_component.hpp"
#include "rive/shapes/clipping_shape.hpp"
#include "rive/math/vec2d.hpp"
#include "rive/constraints/constraint.hpp"

using namespace rive;

StatusCode TransformComponent::onAddedClean(CoreContext* context)
{
    m_ParentTransformComponent =
        parent() != nullptr && parent()->is<WorldTransformComponent>()
            ? parent()->as<WorldTransformComponent>()
            : nullptr;
    return StatusCode::Ok;
}

bool TransformComponent::collapse(bool value)
{
    if (!Super::collapse(value))
    {
        return false;
    }
    for (auto d : dependents())
    {
        if (d->is<TransformComponent>())
        {
            auto dependent = d->as<TransformComponent>();
            dependent->markDirtyIfConstrained();
        }
    }
    return true;
}

// If the component has any constraints applied we mark it as dirty
// because one of its constraining targets has changed its collapse
// status.
void TransformComponent::markDirtyIfConstrained()
{
    if (!m_Constraints.empty())
    {
        addDirt(ComponentDirt::WorldTransform, true);
    }
}

void TransformComponent::buildDependencies()
{
    if (parent() != nullptr)
    {
        parent()->addDependent(this);
    }
}

void TransformComponent::markTransformDirty()
{
    if (!addDirt(ComponentDirt::Transform))
    {
        return;
    }
    markWorldTransformDirty();
}

void TransformComponent::updateTransform()
{
    m_Transform = Mat2D::fromRotation(rotation());
    m_Transform[4] = x();
    m_Transform[5] = y();
    m_Transform.scaleByValues(scaleX(), scaleY());
}

AABB TransformComponent::localBounds() const { return AABB(); }

void TransformComponent::updateWorldTransform()
{
    if (m_ParentTransformComponent != nullptr)
    {
        m_WorldTransform =
            m_ParentTransformComponent->m_WorldTransform * m_Transform;
    }
    else
    {
        m_WorldTransform = m_Transform;
    }
    updateConstraints();
}

void TransformComponent::updateConstraints()
{
    for (auto* constraint : m_Constraints)
    {
        constraint->constrain(this);
    }
}

void TransformComponent::update(ComponentDirt value)
{
    if (hasDirt(value, ComponentDirt::Transform))
    {
        updateTransform();
    }
    if (hasDirt(value, ComponentDirt::WorldTransform))
    {
        updateWorldTransform();
    }
    if (hasDirt(value, ComponentDirt::RenderOpacity))
    {
        m_RenderOpacity = opacity();
        if (m_ParentTransformComponent != nullptr)
        {
            m_RenderOpacity *= m_ParentTransformComponent->childOpacity();
        }
    }
}

const Mat2D& TransformComponent::transform() const { return m_Transform; }

Mat2D& TransformComponent::mutableTransform() { return m_Transform; }

void TransformComponent::rotationChanged() { markTransformDirty(); }
void TransformComponent::scaleXChanged() { markTransformDirty(); }
void TransformComponent::scaleYChanged() { markTransformDirty(); }

void TransformComponent::addConstraint(Constraint* constraint)
{
    m_Constraints.push_back(constraint);
}
