#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/shapes/shape_paint_path.hpp"
#include "rive/advancing_component.hpp"
#include "rive/layout/layout_enums.hpp"
#include <memory>

namespace rive
{
class AABB;
class KeyFrameInterpolator;
class LayoutData;
class LayoutComponentStyle;
class LayoutConstraint;
class ComponentOrigin;

// Containers transparent to layout provide no layout node and no sizing of
// their own, so the layout above descends through them. A plain group exposes
// all its children; a Solo exposes only its active one. Anything else
// (n-slicers, nested artboards, shapes) is opaque.
bool isTransparentLayoutContainer(Component* component);

// Whether a provider reached *through* a transparent container still joins the
// layout. An ArtboardComponentList provides a layout node unconditionally — it
// never opted in the way a participant does — so a group between one and its
// layout is how a file asks for free-form items placed by x/y or a follow-path
// constraint. It joins only when explicitly flagged.
bool joinsLayoutThroughContainer(Component* component);

// Boolean state of a LayoutComponent, packed into one word instead of a dozen
// separate bytes. Gains the bitwise operators + rive::enums helpers for free by
// having a None == 0 member (see rive/enums.hpp).
enum class LayoutComponentFlags : uint16_t
{
    None = 0,
    ParentIsRow = 1 << 0,   // default ON
    ParentIsStack = 1 << 1, //
    WidthIntrinsicallySizeOverride = 1 << 2,
    HeightIntrinsicallySizeOverride = 1 << 3,
    ForceUpdateLayoutBounds = 1 << 4,
    PositionLeftChanged = 1 << 5, // default ON
    PositionTopChanged = 1 << 6,  // default ON
    HasForegroundDrawable = 1 << 7,
    HasComponentOrigin = 1 << 8,
    ComposeTransform = 1 << 9, // default ON
    IsSmoothingAnimation = 1 << 10,
    JustAddedToHost = 1 << 11,
    // Forces a DrawableProxy into the draw order even when the layout's current
    // paint/clip state wouldn't require one, so the proxy can draw or (more
    // often) be sorted as a hit target. Set for any of: a clip a keyframe/data
    // bind can toggle on at runtime, a scroll/drag interaction target, or a
    // state-machine pointer listener target. See the mark* helpers below.
    ForceDrawableProxy = 1 << 12,
    // Transient per-draw flag: drawProxy() issued a renderer->save() for
    // clipping, so draw() owes the matching restore(). Guards against restoring
    // when drawProxy() never ran (e.g. a pure container whose proxy isn't in
    // the draw order but whose clip() turned on at runtime).
    ClipSaved = 1 << 13,
};

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);
};

// The render-path buffers a LayoutComponent needs only when it actually paints,
// clips, has a foreground drawable, or is an Artboard. These are ~240 bytes
// together; heap-allocating them on first use keeps a plain container layout
// (which never paints) from carrying them inline. `background` is scratch for
// building the rounded-rect; `local`/`world` match the old member defaults
// (both default-constructed local, world switched at rewind time).
struct LayoutRenderPaths
{
    RawPath background;
    ShapePaintPath local;
    ShapePaintPath world;
};

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;
    KeyFrameInterpolator* m_inheritedInterpolator;
    // The two 1-byte enums and the 2-byte flags word are kept adjacent so they
    // pack into a single 4-byte slot with no padding.
    LayoutStyleInterpolation m_inheritedInterpolation =
        LayoutStyleInterpolation::hold;
    LayoutDirection m_inheritedDirection = LayoutDirection::inherit;
    LayoutComponentFlags m_layoutFlags =
        LayoutComponentFlags::ParentIsRow |
        LayoutComponentFlags::PositionLeftChanged |
        LayoutComponentFlags::PositionTopChanged |
        LayoutComponentFlags::ComposeTransform;
    float m_inheritedInterpolationTime = 0;
    // Null until this layout first paints/clips/has a foreground drawable, or
    // (for Artboard) builds its background/clip path. See LayoutRenderPaths.
    std::unique_ptr<LayoutRenderPaths> m_renderPaths;
    // Lazily created: only layouts that actually paint, clip, or can gain a
    // clip at runtime (see needsDrawableProxy) — or that are referenced as a
    // scroll/listener target — ever allocate a proxy. A pure container layout
    // never pays for one. See DrawableProxy for why the object is needed at
    // all.
    std::unique_ptr<DrawableProxy> m_proxy;

    bool hasLayoutFlag(LayoutComponentFlags f) const
    {
        return (m_layoutFlags & f) != LayoutComponentFlags::None;
    }
    void setLayoutFlag(LayoutComponentFlags f, bool on)
    {
        if (on)
        {
            m_layoutFlags |= f;
        }
        else
        {
            m_layoutFlags &= ~f;
        }
    }

    // Allocates the render-path buffers on first use. Callers that build or
    // hand out a path go through this; the ShapePaintContainer accessors
    // (worldPath/localPath/localClockwisePath) instead return null while unset,
    // which is a valid contract and keeps plain containers allocation-free.
    LayoutRenderPaths& mutableRenderPaths()
    {
        if (m_renderPaths == nullptr)
        {
            m_renderPaths = std::make_unique<LayoutRenderPaths>();
        }
        return *m_renderPaths;
    }

    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 computedOriginLocal().x; };
    float computedLocalY() override { return computedOriginLocal().y; };
    float computedWorldX() override
    {
        return (worldTransform() * localAnchor()).x;
    };
    float computedWorldY() override
    {
        return (worldTransform() * localAnchor()).y;
    };
    float computedRootX() override;
    float computedRootY() override;
    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;
    float m_heightOverride = NAN;
    float m_forcedWidth = NAN;
    float m_forcedHeight = NAN;
    // Yoga YGUnit values (0..3) plus a -1 sentinel; int8_t is ample.
    int8_t m_widthUnitValueOverride = -1;
    int8_t m_heightUnitValueOverride = -1;
    // Remaining boolean state now lives in m_layoutFlags. Two flags carry the
    // notable defaults documented here:
    // - ComposeTransform (default ON): files exported before 7.3 never composed
    //   a layout's own rotation/scale, so any stored value was ignored. Import
    //   clears it for those files; the default keeps current behavior so a
    //   layout built outside of import isn't stuck on the legacy path. See
    //   File::minorVersion.

    /// Where the layout engine placed us, in the parent's transform frame.
    Vec2D layoutTranslation() const;
    /// The stored x/y offset plus rotation/scale about the pivot.
    Mat2D buildOwnTransform() const;
    /// The origin's position in the parent's frame.
    Vec2D computedOriginLocal() const
    {
        return layoutTranslation() + m_Transform * localAnchor();
    }

#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();
    }

    StatusCode import(ImportStack& importStack) override;
    Core* clone() const override;

    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()
    {
        if (m_proxy == nullptr)
        {
            m_proxy = std::make_unique<DrawableProxy>(this);
        }
        return m_proxy.get();
    };
    // True if this layout has (or can gain) something for its proxy to draw or
    // hit-test: a background/stroke, an active clip, or one of the deferred
    // reasons stamped as ForceDrawableProxy (runtime-toggleable clip, scroll
    // interaction target, or pointer-listener target). When true the artboard
    // injects the proxy into the draw order so it can be sorted for both
    // drawing and hit-testing.
    bool needsDrawableProxy() const
    {
        return clip() || !shapePaints().empty() ||
               hasLayoutFlag(LayoutComponentFlags::ForceDrawableProxy);
    }
    // The mark* helpers below are the distinct call sites that all set the one
    // ForceDrawableProxy bit; they differ only in why the proxy is needed.

    // Called when a keyframe or data bind that targets this layout's `clip`
    // resolves, guaranteeing a proxy before the artboard's first sort.
    void markClipMayBeDynamic()
    {
        setLayoutFlag(LayoutComponentFlags::ForceDrawableProxy, true);
    }
    // Called from a scroll/scrollbar constraint's buildDependencies() (which
    // runs before the artboard's one-time proxy injection, on every instance)
    // when this layout is its viewport/thumb/track. Without the proxy in the
    // draw order, the drag hit target can't be sorted and opaque content on top
    // would swallow the gesture before the drag ever starts.
    void markInteractionTarget()
    {
        setLayoutFlag(LayoutComponentFlags::ForceDrawableProxy, true);
    }
    // Called from StateMachineListener::onAddedClean (which runs on the source
    // artboard before its one-time proxy injection) when a pointer listener
    // targets this layout. Carried to instances by clone(), since the listener
    // hook only runs on the source. Without the proxy in the draw order the hit
    // target can't be sorted and overlapping opaque content would swallow it.
    void markListenerTarget()
    {
        setLayoutFlag(LayoutComponentFlags::ForceDrawableProxy, true);
    }
    virtual void updateRenderPath();
    void update(ComponentDirt value) override;
    void updateTransform() override;
    void composeWorldTransform() override;
    /// Only our stored x/y — where the layout put us is not something we
    /// offset by. Files too old to compose x/y keep reporting their solved
    /// position.
    Vec2D composedTranslation() const override
    {
        return composesLayoutOffset() ? Vec2D(x(), y()) : layoutTranslation();
    }
    /// Our box starts at local zero, so the origin is the anchor. Zero for
    /// artboards, which already draw about theirs. In the .cpp: is<Artboard>
    /// needs the complete type.
    Vec2D localAnchor() const override;
    bool composesLayoutOffset() const;
    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; }
#ifdef WITH_RIVE_TOOLS
    /// Whether the collection walk reaches [child] and takes its node. Not the
    /// same as [child] finding us by walking up, which passes through anything.
    bool collectsForLayout(Component* child);
#endif
    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 layoutX() const { return m_layout.left(); }
    float layoutY() const { return m_layout.top(); }
    /// The origin as a fraction of our size, from the optional
    /// ComponentOrigin child; 0 when absent. Named apart from Artboard's
    /// inline originX/originY so the two never shadow; Artboard overrides.
    virtual float pivotOriginX() const;
    virtual float pivotOriginY() const;
    void markHasComponentOrigin()
    {
        setLayoutFlag(LayoutComponentFlags::HasComponentOrigin, true);
    }
    Vec2D originOffset() 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 parentIsStack(bool isStack);
    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
    // The scale type this layout is actually sized by: the host's override
    // when it has one (a hosted artboard's own style is not what the user set
    // on the NestedArtboardLayout), else its own style's.
    LayoutScaleType effectiveWidthScaleType();
    LayoutScaleType effectiveHeightScaleType();
    void applyBaseStyle(YGStyle& style,
                        const LayoutSyncContext& context) override;
    void applyContainerStyle(YGStyle& style,
                             const LayoutSyncContext& context) override;
#endif
    bool mainAxisIsRow();
    bool mainAxisIsColumn();
    // Whether this layout stacks its children, for hosts that push the
    // container's state into a hosted artboard.
    bool isStackContainer();
    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()
    {
        setLayoutFlag(LayoutComponentFlags::PositionLeftChanged, true);
    }
    void markPositionTopChanged()
    {
        setLayoutFlag(LayoutComponentFlags::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()
    {
        setLayoutFlag(LayoutComponentFlags::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;
};

// The two upward walks a component can ask about its layout, mirroring the two
// downward ones. contentSizingLayout mirrors propagateSizeToChildren: for
// content, and a group stops it. owningLayout mirrors forEachLayoutProvider:
// for anything in the layout tree, and nothing stops it.
//
// Both end at the artboard, which is a LayoutComponent whose own parent is
// null. So a component directly in the artboard resolves to it, and neither
// walk can escape an ArtboardInstance into the artboard hosting it.
LayoutComponent* contentSizingLayout(Component* parent);
LayoutComponent* owningLayout(Component* component);
} // namespace rive

#endif