#include "rive/animation/keyframe_interpolator.hpp"
#include "rive/artboard.hpp"
#include "rive/drawable.hpp"
#include "rive/factory.hpp"
#include "rive/layout_component.hpp"
#include "rive/node.hpp"
#include "rive/math/aabb.hpp"
#include "rive/shapes/paint/fill.hpp"
#include "rive/shapes/paint/shape_paint.hpp"
#include "rive/shapes/paint/stroke.hpp"
#include "rive/shapes/rectangle.hpp"
#include "rive/nested_artboard_layout.hpp"
#ifdef WITH_RIVE_LAYOUT
#include "rive/transform_component.hpp"
#include "yoga/YGEnums.h"
#include "yoga/YGFloatOptional.h"
#endif
#include <vector>

using namespace rive;

void LayoutComponent::buildDependencies()
{
    Super::buildDependencies();
    if (parent() != nullptr)
    {
        parent()->addDependent(this);
    }
    // Set the blend mode on all the shape paints. If we ever animate this
    // property, we'll need to update it in the update cycle/mark dirty when the
    // blend mode changes.
    for (auto paint : m_ShapePaints)
    {
        paint->blendMode(blendMode());
    }
}

void LayoutComponent::drawProxy(Renderer* renderer)
{
    if (clip())
    {
        renderer->save();
        renderer->clipPath(m_clipPath.get());
    }
    renderer->save();
    renderer->transform(worldTransform());
    for (auto shapePaint : m_ShapePaints)
    {
        if (!shapePaint->isVisible())
        {
            continue;
        }
        if (shapePaint->is<Fill>())
        {
            shapePaint->draw(renderer, m_backgroundPath.get(), &m_backgroundRect->rawPath());
        }
    }
    renderer->restore();
}

void LayoutComponent::draw(Renderer* renderer)
{
    // Restore clip before drawing stroke so we don't clip the stroke
    if (clip())
    {
        renderer->restore();
    }
    renderer->save();
    renderer->transform(worldTransform());
    for (auto shapePaint : m_ShapePaints)
    {
        if (!shapePaint->isVisible())
        {
            continue;
        }
        if (shapePaint->is<Stroke>())
        {
            shapePaint->draw(renderer, m_backgroundPath.get(), &m_backgroundRect->rawPath());
        }
    }
    renderer->restore();
}

Core* LayoutComponent::hitTest(HitInfo*, const Mat2D&) { return nullptr; }

void LayoutComponent::updateRenderPath()
{
    m_backgroundRect->width(m_layoutSizeWidth);
    m_backgroundRect->height(m_layoutSizeHeight);
    m_backgroundRect->linkCornerRadius(style()->linkCornerRadius());
    m_backgroundRect->cornerRadiusTL(style()->cornerRadiusTL());
    m_backgroundRect->cornerRadiusTR(style()->cornerRadiusTR());
    m_backgroundRect->cornerRadiusBL(style()->cornerRadiusBL());
    m_backgroundRect->cornerRadiusBR(style()->cornerRadiusBR());
    m_backgroundRect->update(ComponentDirt::Path);

    m_backgroundPath->rewind();
    m_backgroundRect->rawPath().addTo(m_backgroundPath.get());

    RawPath clipPath;
    clipPath.addPath(m_backgroundRect->rawPath(), &m_WorldTransform);
    m_clipPath = artboard()->factory()->makeRenderPath(clipPath, FillRule::nonZero);
}

void LayoutComponent::update(ComponentDirt value)
{
    Super::update(value);
    if (hasDirt(value, ComponentDirt::RenderOpacity))
    {
        propagateOpacity(childOpacity());
    }
    if (parent() != nullptr && hasDirt(value, ComponentDirt::WorldTransform))
    {
        Mat2D parentWorld = parent()->is<WorldTransformComponent>()
                                ? (parent()->as<WorldTransformComponent>())->worldTransform()
                                : Mat2D();
        auto location = Vec2D(m_layoutLocationX, m_layoutLocationY);
        if (parent()->is<Artboard>())
        {
            auto art = parent()->as<Artboard>();
            location -=
                Vec2D(art->layoutWidth() * art->originX(), art->layoutHeight() * art->originY());
        }
        auto transform = Mat2D::fromTranslation(location);
        m_WorldTransform = Mat2D::multiply(parentWorld, transform);
        updateConstraints();
    }
    if (hasDirt(value, ComponentDirt::Path))
    {
        updateRenderPath();
    }
}

#ifdef WITH_RIVE_LAYOUT
StatusCode LayoutComponent::onAddedDirty(CoreContext* context)
{
    auto code = Super::onAddedDirty(context);
    if (code != StatusCode::Ok)
    {
        return code;
    }

    auto coreStyle = context->resolve(styleId());
    if (coreStyle == nullptr || !coreStyle->is<LayoutComponentStyle>())
    {
        return StatusCode::MissingObject;
    }
    m_style = static_cast<LayoutComponentStyle*>(coreStyle);
    addChild(m_style);

    return StatusCode::Ok;
}

StatusCode LayoutComponent::onAddedClean(CoreContext* context)
{
    auto code = Super::onAddedClean(context);
    if (code != StatusCode::Ok)
    {
        return code;
    }
    artboard()->markLayoutDirty(this);
    markLayoutStyleDirty();
    m_backgroundPath = artboard()->factory()->makeEmptyRenderPath();
    m_clipPath = artboard()->factory()->makeEmptyRenderPath();
    m_backgroundRect->originX(0);
    m_backgroundRect->originY(0);
    syncLayoutChildren();
    return StatusCode::Ok;
}

static YGSize measureFunc(YGNode* node,
                          float width,
                          YGMeasureMode widthMode,
                          float height,
                          YGMeasureMode heightMode)
{
    Vec2D size = ((LayoutComponent*)node->getContext())
                     ->measureLayout(width,
                                     (LayoutMeasureMode)widthMode,
                                     height,
                                     (LayoutMeasureMode)heightMode);

    return YGSize{size.x, size.y};
}

Vec2D LayoutComponent::measureLayout(float width,
                                     LayoutMeasureMode widthMode,
                                     float height,
                                     LayoutMeasureMode heightMode)
{
    Vec2D size = Vec2D();
    for (auto child : children())
    {
        if (child->is<LayoutComponent>())
        {
            continue;
        }
        //  && child->is<TransformComponent>()->canMeasure() for nested artboard layout
        if (child->is<TransformComponent>())
        {
            auto transformComponent = child->as<TransformComponent>();
            Vec2D measured =
                transformComponent->measureLayout(width, widthMode, height, heightMode);
            size = Vec2D(std::max(size.x, measured.x), std::max(size.y, measured.y));
        }
    }
    return size;
}

void LayoutComponent::syncStyle()
{
    if (m_style == nullptr)
    {
        return;
    }
    YGNode& ygNode = layoutNode();
    YGStyle& ygStyle = layoutStyle();
    if (m_style->intrinsicallySized())
    {
        ygNode.setContext(this);
        ygNode.setMeasureFunc(measureFunc);
    }
    else
    {
        ygNode.setMeasureFunc(nullptr);
    }
    if (m_style->widthUnits() != YGUnitAuto)
    {
        ygStyle.dimensions()[YGDimensionWidth] = YGValue{width(), m_style->widthUnits()};
    }
    else
    {
        ygStyle.dimensions()[YGDimensionWidth] = YGValueAuto;
    }
    if (m_style->heightUnits() != YGUnitAuto)
    {
        ygStyle.dimensions()[YGDimensionHeight] = YGValue{height(), m_style->heightUnits()};
    }
    else
    {
        ygStyle.dimensions()[YGDimensionHeight] = YGValueAuto;
    }

    if (layoutParent() != nullptr)
    {
        bool isRow = layoutParent()->style()->flexDirection() == YGFlexDirectionRow ||
                     layoutParent()->style()->flexDirection() == YGFlexDirectionRowReverse;
        switch (m_style->widthScaleType())
        {
            case LayoutScaleType::fixed:
                if (isRow)
                {
                    ygStyle.flexGrow() = YGFloatOptional(0);
                }
                break;
            case LayoutScaleType::fill:
                if (isRow)
                {
                    ygStyle.flexGrow() = YGFloatOptional(1);
                }
                else
                {
                    ygStyle.alignSelf() = YGAlignStretch;
                }
                break;
            case LayoutScaleType::hug:
                if (isRow)
                {
                    ygStyle.flexGrow() = YGFloatOptional(0);
                }
                else
                {
                    ygStyle.alignSelf() = YGAlignAuto;
                }
                break;
            default:
                break;
        }
        bool isColumn = !isRow;
        switch (m_style->heightScaleType())
        {
            case LayoutScaleType::fixed:
                if (isColumn)
                {
                    ygStyle.flexGrow() = YGFloatOptional(0);
                }
                break;
            case LayoutScaleType::fill:
                if (isColumn)
                {
                    ygStyle.flexGrow() = YGFloatOptional(1);
                }
                else
                {
                    ygStyle.alignSelf() = YGAlignStretch;
                }
                break;
            case LayoutScaleType::hug:
                if (isColumn)
                {
                    ygStyle.flexGrow() = YGFloatOptional(0);
                }
                else
                {
                    ygStyle.alignSelf() = YGAlignAuto;
                }
                break;
            default:
                break;
        }
    }

    bool isRowForAlignment = m_style->flexDirection() == YGFlexDirectionRow ||
                             m_style->flexDirection() == YGFlexDirectionRowReverse;
    switch (m_style->alignmentType())
    {
        case LayoutAlignmentType::topLeft:
        case LayoutAlignmentType::topCenter:
        case LayoutAlignmentType::topRight:
        case LayoutAlignmentType::spaceBetweenStart:
            if (isRowForAlignment)
            {
                ygStyle.alignItems() = YGAlignFlexStart;
                ygStyle.alignContent() = YGAlignFlexStart;
            }
            else
            {
                ygStyle.justifyContent() = YGJustifyFlexStart;
            }
            break;
        case LayoutAlignmentType::centerLeft:
        case LayoutAlignmentType::center:
        case LayoutAlignmentType::centerRight:
        case LayoutAlignmentType::spaceBetweenCenter:
            if (isRowForAlignment)
            {
                ygStyle.alignItems() = YGAlignCenter;
                ygStyle.alignContent() = YGAlignCenter;
            }
            else
            {
                ygStyle.justifyContent() = YGJustifyCenter;
            }
            break;
        case LayoutAlignmentType::bottomLeft:
        case LayoutAlignmentType::bottomCenter:
        case LayoutAlignmentType::bottomRight:
        case LayoutAlignmentType::spaceBetweenEnd:
            if (isRowForAlignment)
            {
                ygStyle.alignItems() = YGAlignFlexEnd;
                ygStyle.alignContent() = YGAlignFlexEnd;
            }
            else
            {
                ygStyle.justifyContent() = YGJustifyFlexEnd;
            }
            break;
    }
    switch (m_style->alignmentType())
    {
        case LayoutAlignmentType::topLeft:
        case LayoutAlignmentType::centerLeft:
        case LayoutAlignmentType::bottomLeft:
            if (isRowForAlignment)
            {
                ygStyle.justifyContent() = YGJustifyFlexStart;
            }
            else
            {
                ygStyle.alignItems() = YGAlignFlexStart;
                ygStyle.alignContent() = YGAlignFlexStart;
            }
            break;
        case LayoutAlignmentType::topCenter:
        case LayoutAlignmentType::center:
        case LayoutAlignmentType::bottomCenter:
            if (isRowForAlignment)
            {
                ygStyle.justifyContent() = YGJustifyCenter;
            }
            else
            {
                ygStyle.alignItems() = YGAlignCenter;
                ygStyle.alignContent() = YGAlignCenter;
            }
            break;
        case LayoutAlignmentType::topRight:
        case LayoutAlignmentType::centerRight:
        case LayoutAlignmentType::bottomRight:
            if (isRowForAlignment)
            {
                ygStyle.justifyContent() = YGJustifyFlexEnd;
            }
            else
            {
                ygStyle.alignItems() = YGAlignFlexEnd;
                ygStyle.alignContent() = YGAlignFlexEnd;
            }
            break;
        case LayoutAlignmentType::spaceBetweenStart:
        case LayoutAlignmentType::spaceBetweenCenter:
        case LayoutAlignmentType::spaceBetweenEnd:
            ygStyle.justifyContent() = YGJustifySpaceBetween;
            break;
    }

    ygStyle.minDimensions()[YGDimensionWidth] =
        YGValue{m_style->minWidth(), m_style->minWidthUnits()};
    ygStyle.minDimensions()[YGDimensionHeight] =
        YGValue{m_style->minHeight(), m_style->minHeightUnits()};
    ygStyle.maxDimensions()[YGDimensionWidth] =
        YGValue{m_style->maxWidth(), m_style->maxWidthUnits()};
    ygStyle.maxDimensions()[YGDimensionHeight] =
        YGValue{m_style->maxHeight(), m_style->maxHeightUnits()};
    ygStyle.gap()[YGGutterColumn] =
        YGValue{m_style->gapHorizontal(), m_style->gapHorizontalUnits()};
    ygStyle.gap()[YGGutterRow] = YGValue{m_style->gapVertical(), m_style->gapVerticalUnits()};
    ygStyle.border()[YGEdgeLeft] = YGValue{m_style->borderLeft(), m_style->borderLeftUnits()};
    ygStyle.border()[YGEdgeRight] = YGValue{m_style->borderRight(), m_style->borderRightUnits()};
    ygStyle.border()[YGEdgeTop] = YGValue{m_style->borderTop(), m_style->borderTopUnits()};
    ygStyle.border()[YGEdgeBottom] = YGValue{m_style->borderBottom(), m_style->borderBottomUnits()};
    ygStyle.margin()[YGEdgeLeft] = YGValue{m_style->marginLeft(), m_style->marginLeftUnits()};
    ygStyle.margin()[YGEdgeRight] = YGValue{m_style->marginRight(), m_style->marginRightUnits()};
    ygStyle.margin()[YGEdgeTop] = YGValue{m_style->marginTop(), m_style->marginTopUnits()};
    ygStyle.margin()[YGEdgeBottom] = YGValue{m_style->marginBottom(), m_style->marginBottomUnits()};
    ygStyle.padding()[YGEdgeLeft] = YGValue{m_style->paddingLeft(), m_style->paddingLeftUnits()};
    ygStyle.padding()[YGEdgeRight] = YGValue{m_style->paddingRight(), m_style->paddingRightUnits()};
    ygStyle.padding()[YGEdgeTop] = YGValue{m_style->paddingTop(), m_style->paddingTopUnits()};
    ygStyle.padding()[YGEdgeBottom] =
        YGValue{m_style->paddingBottom(), m_style->paddingBottomUnits()};
    ygStyle.position()[YGEdgeLeft] = YGValue{m_style->positionLeft(), m_style->positionLeftUnits()};
    ygStyle.position()[YGEdgeRight] =
        YGValue{m_style->positionRight(), m_style->positionRightUnits()};
    ygStyle.position()[YGEdgeTop] = YGValue{m_style->positionTop(), m_style->positionTopUnits()};
    ygStyle.position()[YGEdgeBottom] =
        YGValue{m_style->positionBottom(), m_style->positionBottomUnits()};

    ygStyle.display() = m_style->display();
    ygStyle.positionType() = m_style->positionType();
    ygStyle.flex() = YGFloatOptional(m_style->flex());
    ygStyle.flexDirection() = m_style->flexDirection();
    ygStyle.flexWrap() = m_style->flexWrap();

    ygNode.setStyle(ygStyle);
}

void LayoutComponent::syncLayoutChildren()
{
    auto ourNode = &layoutNode();
    YGNodeRemoveAllChildren(ourNode);
    int index = 0;
    for (auto child : children())
    {
        YGNode* node = nullptr;
        switch (child->coreType())
        {
            case LayoutComponentBase::typeKey:
                node = &child->as<LayoutComponent>()->layoutNode();
                break;
            case NestedArtboardLayoutBase::typeKey:
                node = static_cast<YGNode*>(child->as<NestedArtboardLayout>()->layoutNode());
                break;
        }
        if (node != nullptr)
        {
            // YGNodeInsertChild(ourNode, node, index++);
            ourNode->insertChild(node, index++);
            node->setOwner(ourNode);
            ourNode->markDirtyAndPropagate();
        }
    }
    markLayoutNodeDirty();
}

void LayoutComponent::propagateSize() { propagateSizeToChildren(this); }

void LayoutComponent::propagateSizeToChildren(ContainerComponent* component)
{
    for (auto child : component->children())
    {
        if (child->is<LayoutComponent>() || child->coreType() == NodeBase::typeKey)
        {
            continue;
        }
        if (child->is<TransformComponent>())
        {
            auto sizableChild = child->as<TransformComponent>();
            sizableChild->controlSize(Vec2D(m_layoutSizeWidth, m_layoutSizeHeight));
        }
        if (child->is<ContainerComponent>())
        {
            propagateSizeToChildren(child->as<ContainerComponent>());
        }
    }
}

void LayoutComponent::calculateLayout()
{
    YGNodeCalculateLayout(&layoutNode(), width(), height(), YGDirection::YGDirectionInherit);
}

void LayoutComponent::onDirty(ComponentDirt value)
{
    Super::onDirty(value);
    if ((value & ComponentDirt::WorldTransform) == ComponentDirt::WorldTransform && clip())
    {
        addDirt(ComponentDirt::Path);
    }
}

void LayoutComponent::updateLayoutBounds()
{
    auto node = &layoutNode();
    auto left = YGNodeLayoutGetLeft(node);
    auto top = YGNodeLayoutGetTop(node);
    auto width = YGNodeLayoutGetWidth(node);
    auto height = YGNodeLayoutGetHeight(node);

#ifdef DEBUG
    // Temporarily here to keep track of an issue.
    if (left != left || top != top || width != width || height != height)
    {
        fprintf(stderr,
                "Layout returned nan: %f %f %f %f | %p %s\n",
                left,
                top,
                width,
                height,
                YGNodeGetParent(node),
                name().c_str());
        return;
    }
#endif
    if (animates())
    {
        auto toBounds = m_animationData.toBounds;
        if (left != toBounds.left() || top != toBounds.top() || width != toBounds.width() ||
            height != toBounds.height())
        {
            m_animationData.fromBounds = AABB(m_layoutLocationX,
                                              m_layoutLocationY,
                                              m_layoutLocationX + this->width(),
                                              m_layoutLocationY + this->height());
            m_animationData.toBounds = AABB(left, top, left + width, top + height);
            if (m_animationData.elapsedSeconds > 0.1)
            {
                m_animationData.elapsedSeconds = 0;
            }
            propagateSize();
            markWorldTransformDirty();
        }
    }
    else

        if (left != m_layoutLocationX || top != m_layoutLocationY || width != m_layoutSizeWidth ||
            height != m_layoutSizeHeight)
    {
        if (m_layoutSizeWidth != width || m_layoutSizeHeight != height)
        {
            // Width changed, we need to rebuild the path.
            addDirt(ComponentDirt::Path);
        }
        m_layoutLocationX = left;
        m_layoutLocationY = top;
        m_layoutSizeWidth = width;
        m_layoutSizeHeight = height;

        propagateSize();
        markWorldTransformDirty();
    }
}

bool LayoutComponent::advance(double elapsedSeconds) { return applyInterpolation(elapsedSeconds); }

bool LayoutComponent::animates()
{
    if (m_style == nullptr)
    {
        return false;
    }
    return m_style->positionType() == YGPositionType::YGPositionTypeRelative &&
           m_style->animationStyle() != LayoutAnimationStyle::none &&
           interpolation() != LayoutStyleInterpolation::hold && interpolationTime() > 0;
}

LayoutAnimationStyle LayoutComponent::animationStyle()
{
    if (m_style == nullptr)
    {
        return LayoutAnimationStyle::none;
    }
    return m_style->animationStyle();
}

KeyFrameInterpolator* LayoutComponent::interpolator()
{
    if (m_style == nullptr)
    {
        return nullptr;
    }
    switch (m_style->animationStyle())
    {
        case LayoutAnimationStyle::inherit:
            return m_inheritedInterpolator != nullptr ? m_inheritedInterpolator
                                                      : m_style->interpolator();
        case LayoutAnimationStyle::custom:
            return m_style->interpolator();
        default:
            return nullptr;
    }
}

LayoutStyleInterpolation LayoutComponent::interpolation()
{
    auto defaultInterpolation = LayoutStyleInterpolation::hold;
    if (m_style == nullptr)
    {
        return defaultInterpolation;
    }
    switch (m_style->animationStyle())
    {
        case LayoutAnimationStyle::inherit:
            return m_inheritedInterpolation;
        case LayoutAnimationStyle::custom:
            return m_style->interpolation();
        default:
            return defaultInterpolation;
    }
}

float LayoutComponent::interpolationTime()
{
    if (m_style == nullptr)
    {
        return 0;
    }
    switch (m_style->animationStyle())
    {
        case LayoutAnimationStyle::inherit:
            return m_inheritedInterpolationTime;
        case LayoutAnimationStyle::custom:
            return m_style->interpolationTime();
        default:
            return 0;
    }
}

void LayoutComponent::cascadeAnimationStyle(LayoutStyleInterpolation inheritedInterpolation,
                                            KeyFrameInterpolator* inheritedInterpolator,
                                            float inheritedInterpolationTime)
{
    if (m_style != nullptr && m_style->animationStyle() == LayoutAnimationStyle::inherit)
    {
        setInheritedInterpolation(inheritedInterpolation,
                                  inheritedInterpolator,
                                  inheritedInterpolationTime);
    }
    else
    {
        clearInheritedInterpolation();
    }
    for (auto child : children())
    {
        if (child->is<LayoutComponent>())
        {
            child->as<LayoutComponent>()->cascadeAnimationStyle(interpolation(),
                                                                interpolator(),
                                                                interpolationTime());
        }
    }
}

void LayoutComponent::setInheritedInterpolation(LayoutStyleInterpolation inheritedInterpolation,
                                                KeyFrameInterpolator* inheritedInterpolator,
                                                float inheritedInterpolationTime)
{
    m_inheritedInterpolation = inheritedInterpolation;
    m_inheritedInterpolator = inheritedInterpolator;
    m_inheritedInterpolationTime = inheritedInterpolationTime;
}

void LayoutComponent::clearInheritedInterpolation()
{
    m_inheritedInterpolation = LayoutStyleInterpolation::hold;
    m_inheritedInterpolator = nullptr;
    m_inheritedInterpolationTime = 0;
}

bool LayoutComponent::applyInterpolation(double elapsedSeconds)
{
    if (!animates() || m_style == nullptr || m_animationData.toBounds == layoutBounds())
    {
        return false;
    }

    if (m_animationData.elapsedSeconds >= interpolationTime())
    {
        m_layoutLocationX = m_animationData.toBounds.left();
        m_layoutLocationY = m_animationData.toBounds.top();

        float width = m_animationData.toBounds.width();
        float height = m_animationData.toBounds.height();
        if (width != m_layoutSizeWidth || height != m_layoutSizeHeight)
        {
            addDirt(ComponentDirt::Path);
        }
        m_layoutSizeWidth = width;
        m_layoutSizeHeight = height;

        m_animationData.elapsedSeconds = 0;
        propagateSize();
        markWorldTransformDirty();

        return false;
    }
    float f = 1;
    if (interpolationTime() > 0)
    {
        f = m_animationData.elapsedSeconds / interpolationTime();
    }
    bool needsAdvance = false;
    auto fromBounds = m_animationData.fromBounds;
    auto toBounds = m_animationData.toBounds;
    auto left = m_layoutLocationX;
    auto top = m_layoutLocationY;
    auto width = m_layoutSizeWidth;
    auto height = m_layoutSizeHeight;
    if (toBounds.left() != left || toBounds.top() != top)
    {
        if (interpolation() == LayoutStyleInterpolation::linear)
        {
            left = fromBounds.left() + f * (toBounds.left() - fromBounds.left());
            top = fromBounds.top() + f * (toBounds.top() - fromBounds.top());
        }
        else
        {
            if (interpolator() != nullptr)
            {
                left = interpolator()->transformValue(fromBounds.left(), toBounds.left(), f);
                top = interpolator()->transformValue(fromBounds.top(), toBounds.top(), f);
            }
        }
        needsAdvance = true;
        m_layoutLocationX = left;
        m_layoutLocationY = top;
    }
    if (toBounds.width() != width || toBounds.height() != height)
    {
        if (interpolation() == LayoutStyleInterpolation::linear)
        {
            width = fromBounds.width() + f * (toBounds.width() - fromBounds.width());
            height = fromBounds.height() + f * (toBounds.height() - fromBounds.height());
        }
        else
        {
            if (interpolator() != nullptr)
            {
                width = interpolator()->transformValue(fromBounds.width(), toBounds.width(), f);
                height = interpolator()->transformValue(fromBounds.height(), toBounds.height(), f);
            }
        }
        needsAdvance = true;
        m_layoutSizeWidth = width;
        m_layoutSizeHeight = height;
        addDirt(ComponentDirt::Path);
    }
    m_animationData.elapsedSeconds = m_animationData.elapsedSeconds + (float)elapsedSeconds;
    if (needsAdvance)
    {
        propagateSize();
        markWorldTransformDirty();
    }
    return needsAdvance;
}

void LayoutComponent::markLayoutNodeDirty()
{
    layoutNode().markDirtyAndPropagate();
    artboard()->markLayoutDirty(this);
}

void LayoutComponent::markLayoutStyleDirty()
{
    clearInheritedInterpolation();
    addDirt(ComponentDirt::LayoutStyle);
    if (artboard() != this)
    {
        artboard()->markLayoutStyleDirty();
    }
}
#else
Vec2D LayoutComponent::measureLayout(float width,
                                     LayoutMeasureMode widthMode,
                                     float height,
                                     LayoutMeasureMode heightMode)
{
    return Vec2D();
}

void LayoutComponent::markLayoutNodeDirty() {}
void LayoutComponent::markLayoutStyleDirty() {}
void LayoutComponent::onDirty(ComponentDirt value) {}
#endif

void LayoutComponent::clipChanged() { markLayoutNodeDirty(); }
void LayoutComponent::widthChanged() { markLayoutNodeDirty(); }
void LayoutComponent::heightChanged() { markLayoutNodeDirty(); }
void LayoutComponent::styleIdChanged() { markLayoutNodeDirty(); }
