#ifndef _RIVE_LAYOUT_COMPONENT_HPP_
#define _RIVE_LAYOUT_COMPONENT_HPP_
#include "rive/advance_flags.hpp"
#include "rive/animation/keyframe_interpolator.hpp"
#include "rive/drawable.hpp"
#include "rive/generated/layout_component_base.hpp"
#include "rive/layout/layout_measure_mode.hpp"
#include "rive/layout/layout_node_provider.hpp"
#include "rive/layout/layout_style_applier.hpp"
#include "rive/math/raw_path.hpp"
#include "rive/shapes/shape_paint_container.hpp"
#include "rive/advancing_component.hpp"
#include "rive/layout/layout_enums.hpp"

namespace rive
{
class AABB;
class KeyFrameInterpolator;
class LayoutData;
class LayoutComponentStyle;
class LayoutConstraint;
class Layout
{
public:
    Layout() : m_left(0.0f), m_top(0.0f), m_width(0.0f), m_height(0.0f) {}
    Layout(float left, float top, float width, float height) :
        m_left(left), m_top(top), m_width(width), m_height(height)
    {}

    bool operator==(const Layout& o) const
    {
        return m_left == o.m_left && m_top == o.m_top && m_width == o.m_width &&
               m_height == o.m_height;
    }
    bool operator!=(const Layout& o) const { return !(*this == o); }

    static Layout lerp(const Layout& from, const Layout& to, float f)
    {
        float fi = 1.0f - f;
        return Layout(to.m_left * f + from.m_left * fi,
                      to.m_top * f + from.m_top * fi,
                      to.m_width * f + from.m_width * fi,
                      to.m_height * f + from.m_height * fi);
    }

    float left() const { return m_left; }
    float top() const { return m_top; }
    float width() const { return m_width; }
    float height() const { return m_height; }

private:
    float m_left;
    float m_top;
    float m_width;
    float m_height;
};

class LayoutPadding
{
public:
    LayoutPadding() : m_left(0.0f), m_top(0.0f), m_right(0.0f), m_bottom(0.0f)
    {}
    LayoutPadding(float left, float top, float right, float bottom) :
        m_left(left), m_top(top), m_right(right), m_bottom(bottom)
    {}

    bool operator==(const LayoutPadding& o) const
    {
        return m_left == o.m_left && m_top == o.m_top && m_right == o.m_right &&
               m_bottom == o.m_bottom;
    }
    bool operator!=(const LayoutPadding& o) const { return !(*this == o); }

    float left() const { return m_left; }
    float top() const { return m_top; }
    float right() const { return m_right; }
    float bottom() const { return m_bottom; }

private:
    float m_left;
    float m_top;
    float m_right;
    float m_bottom;
};

struct LayoutAnimationData
{
    float elapsedSeconds = 0.0f;
    Layout from;
    Layout to;
    Layout interpolate(float f) const { return Layout::lerp(from, to, f); }
    void copy(const LayoutAnimationData& from);
};

class LayoutComponent : public LayoutComponentBase,
                        public ProxyDrawing,
                        public ShapePaintContainer,
                        public AdvancingComponent,
                        public InterpolatorHost,
                        public LayoutNodeProvider,
                        public LayoutStyleApplier
{
protected:
    LayoutComponentStyle* m_style = nullptr;
    LayoutData* m_layoutData;

    Layout m_layout;
    LayoutPadding m_layoutPadding;

    LayoutAnimationData m_animationDataA;
    LayoutAnimationData m_animationDataB;
    bool m_isSmoothingAnimation = false;
    KeyFrameInterpolator* m_inheritedInterpolator;
    LayoutStyleInterpolation m_inheritedInterpolation =
        LayoutStyleInterpolation::hold;
    float m_inheritedInterpolationTime = 0;
    LayoutDirection m_inheritedDirection = LayoutDirection::inherit;
    RawPath m_backgroundRawPath;
    ShapePaintPath m_localPath;
    ShapePaintPath m_worldPath;
    DrawableProxy m_proxy;
    bool m_justAddedToHost = false;

    Artboard* getArtboard() override { return artboard(); }
    LayoutAnimationData* currentAnimationData();

    LayoutComponent* layoutParent()
    {
        auto p = parent();
        while (p != nullptr)
        {
            if (p->is<LayoutComponent>())
            {
                return p->as<LayoutComponent>();
            }
            p = p->parent();
        }
        return nullptr;
    }
    bool isCollapsed() const override;
    void propagateCollapse(bool collapse);
    bool collapse(bool value) override;
    float computedLocalX() override { return m_layout.left(); };
    float computedLocalY() override { return m_layout.top(); };
    float computedWidth() override { return m_layout.width(); };
    float computedHeight() override { return m_layout.height(); };
    void calculateLayoutInternal(float availableWidth, float availableHeight);

private:
    float m_widthOverride = NAN;
    int m_widthUnitValueOverride = -1;
    float m_heightOverride = NAN;
    int m_heightUnitValueOverride = -1;
    bool m_parentIsRow = true;
    bool m_widthIntrinsicallySizeOverride = false;
    bool m_heightIntrinsicallySizeOverride = false;
    float m_forcedWidth = NAN;
    float m_forcedHeight = NAN;
    bool m_forceUpdateLayoutBounds = false;
    bool m_positionLeftChanged = true;
    bool m_positionTopChanged = true;
    bool m_hasForegroundDrawable = false;

#ifdef WITH_RIVE_LAYOUT
protected:
    void propagateSizeToChildren(ContainerComponent* component);
    bool applyInterpolation(float elapsedSeconds, bool animate = true);
    bool styleDisplayHidden() const;
#endif

public:
    // Implemented for ShapePaintContainer.
    const Mat2D& shapeWorldTransform() const override
    {
        return worldTransform();
    }

    LayoutComponentStyle* style() { return m_style; }
    void style(LayoutComponentStyle* style) { m_style = style; }

    void draw(Renderer* renderer) override;
    void drawProxy(Renderer* renderer) override;
    bool isProxyHidden() override { return isHidden(); }
    Core* hitTest(HitInfo*, const Mat2D&) override;
    bool hitTestPoint(const Vec2D& position,
                      bool skipOnUnclipped,
                      bool isPrimaryHit) override;
    DrawableProxy* proxy() { return &m_proxy; };
    virtual void updateRenderPath();
    void update(ComponentDirt value) override;
    void onDirty(ComponentDirt value) override;
    AABB layoutBounds() override
    {
        return AABB::fromLTWH(m_layout.left(),
                              m_layout.top(),
                              m_layout.width(),
                              m_layout.height());
    }
    size_t numLayoutNodes() override { return 1; }
    AABB constraintBounds() const override { return localBounds(); }
    AABB localBounds() const override
    {
        return AABB::fromLTWH(0.0f, 0.0f, m_layout.width(), m_layout.height());
    }
    virtual AABB worldBounds() const
    {
        auto transform = worldTransform();
        return AABB::fromLTWH(transform[4],
                              transform[5],
                              m_layout.width(),
                              m_layout.height());
    }

    float x() const override { return layoutX(); }
    float y() const override { return layoutY(); }
    float layoutX() const { return m_layout.left(); }
    float layoutY() const { return m_layout.top(); }
    /// The pivot that rotation and scale compose about, from the optional
    /// ComponentOrigin child; 0 when absent, which is the common case. Named
    /// apart from Artboard's inline originX/originY so the two never shadow.
    float pivotOriginX() const;
    float pivotOriginY() const;
    float layoutWidth() { return m_layout.width(); }
    float layoutHeight() { return m_layout.height(); }
    float innerWidth()
    {
        return m_layout.width() - m_layoutPadding.left() -
               m_layoutPadding.right();
    }
    float innerHeight()
    {
        return m_layout.height() - m_layoutPadding.top() -
               m_layoutPadding.bottom();
    }
    float paddingLeft() { return m_layoutPadding.left(); }
    float paddingRight() { return m_layoutPadding.right(); }
    float paddingTop() { return m_layoutPadding.top(); }
    float paddingBottom() { return m_layoutPadding.bottom(); }

    float gapHorizontal();
    float gapVertical();

    // We provide a way for nested artboards (or other objects) to override this
    // layout's width/height and unit values.
    void widthOverride(float width, int unitValue = 1, bool isRow = true);
    void heightOverride(float height, int unitValue = 1, bool isRow = true);
    void parentIsRow(bool isRow);
    void widthIntrinsicallySizeOverride(bool intrinsic);
    void heightIntrinsicallySizeOverride(bool intrinsic);
    virtual bool canHaveOverrides() { return false; }
    // Honours the NestedArtboardLayout override; shared via LayoutSyncContext.
    bool effectiveParentIsRow();
#ifdef WITH_RIVE_LAYOUT
    void applyBaseStyle(YGStyle& style,
                        const LayoutSyncContext& context) override;
    void applyContainerStyle(YGStyle& style,
                             const LayoutSyncContext& context) override;
#endif
    bool mainAxisIsRow();
    bool mainAxisIsColumn();
    bool overridesKeyedInterpolation(int propertyKey) override;
    bool hasShapePaints() const { return m_ShapePaints.size() > 0; }
    bool advanceComponent(float elapsedSeconds,
                          AdvanceFlags flags = AdvanceFlags::Animate |
                                               AdvanceFlags::NewFrame) override;
    bool isHidden() const override;
    float forcedWidth() { return m_forcedWidth; }
    float forcedHeight() { return m_forcedHeight; }
    void forcedWidth(float width);
    void forcedHeight(float height);
    void updateConstraints() override;
    TransformComponent* transformComponent() override
    {
        return this->as<TransformComponent>();
    }

    LayoutComponent();
    ~LayoutComponent();
#ifdef WITH_RIVE_LAYOUT

    void* layoutNode(int index) override;
    void syncStyle();
    void syncLayoutChildren();
    void clearLayoutChildren();
    virtual void propagateSize();
    void updateLayoutBounds(bool animate = true) override;
    StatusCode onAddedDirty(CoreContext* context) override;
    StatusCode onAddedClean(CoreContext* context) override;
    bool advance(float elapsedSeconds);
    bool animates();
    LayoutAnimationStyle animationStyle();
    KeyFrameInterpolator* interpolator();
    LayoutStyleInterpolation interpolation();
    float interpolationTime();

    bool cascadeLayoutStyle(LayoutStyleInterpolation inheritedInterpolation,
                            KeyFrameInterpolator* inheritedInterpolator,
                            float inheritedInterpolationTime,
                            LayoutDirection direction) override;
    bool setInheritedInterpolation(
        LayoutStyleInterpolation inheritedInterpolation,
        KeyFrameInterpolator* inheritedInterpolator,
        float inheritedInterpolationTime);
    void clearInheritedInterpolation();
    void interruptAnimation();
    bool isLeaf();
    void positionTypeChanged();
    void scaleTypeChanged();
    void displayChanged();
    void flexDirectionChanged();
    void layoutTypeChanged();
    void directionChanged();
    LayoutDirection actualDirection();
    // Re-run each child provider's style sync: a participant's yoga style
    // (flexGrow vs alignSelf/justifySelf/grid placement) is computed against
    // our grid/flex type + main axis, so switching those must re-sync, not just
    // mark nodes dirty.
    void syncChildProviderStyles();
#endif

    void markPositionLeftChanged() { m_positionLeftChanged = true; }
    void markPositionTopChanged() { m_positionTopChanged = true; }
    void buildDependencies() override;

#ifdef WITH_RIVE_LAYOUT
    void addLayoutStyleApplier(LayoutStyleApplier* applier) override;
#endif
    void markLayoutNodeDirty(
        bool shouldForceUpdateLayoutBounds = false) override;
    void markLayoutStyleDirty();
    void clipChanged() override;
    void registerForegroundDrawable() { m_hasForegroundDrawable = true; }
    void widthChanged() override;
    void heightChanged() override;
    void styleIdChanged() override;
    void fractionalWidthChanged() override;
    void fractionalHeightChanged() override;

    Vec2D measureLayout(float width,
                        LayoutMeasureMode widthMode,
                        float height,
                        LayoutMeasureMode heightMode) override;

    ShapePaintPath* worldPath() override;
    ShapePaintPath* localPath() override;
    ShapePaintPath* localClockwisePath() override;
    Component* pathBuilder() override;
};
} // namespace rive

#endif