#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;
            }
            else
            {
                ygStyle.justifyContent() = YGJustifyFlexStart;
            }
            break;
        case LayoutAlignmentType::centerLeft:
        case LayoutAlignmentType::center:
        case LayoutAlignmentType::centerRight:
        case LayoutAlignmentType::spaceBetweenCenter:
            if (isRowForAlignment)
            {
                ygStyle.alignItems() = YGAlignCenter;
            }
            else
            {
                ygStyle.justifyContent() = YGJustifyCenter;
            }
            break;
        case LayoutAlignmentType::bottomLeft:
        case LayoutAlignmentType::bottomCenter:
        case LayoutAlignmentType::bottomRight:
        case LayoutAlignmentType::spaceBetweenEnd:
            if (isRowForAlignment)
            {
                ygStyle.alignItems() = 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;
            }
            break;
        case LayoutAlignmentType::topCenter:
        case LayoutAlignmentType::center:
        case LayoutAlignmentType::bottomCenter:
            if (isRowForAlignment)
            {
                ygStyle.justifyContent() = YGJustifyCenter;
            }
            else
            {
                ygStyle.alignItems() = YGAlignCenter;
            }
            break;
        case LayoutAlignmentType::topRight:
        case LayoutAlignmentType::centerRight:
        case LayoutAlignmentType::bottomRight:
            if (isRowForAlignment)
            {
                ygStyle.justifyContent() = YGJustifyFlexEnd;
            }
            else
            {
                ygStyle.alignItems() = 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(); }
