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

// Whether `component` can put a layout provider in front of a layout: it is a
// provider, or a transparent container holding one. Every option of a Solo
// counts, active or not, so the answer doesn't change when a Solo switches.
bool reachesLayoutProvider(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,
  // Whether the style's display is none, kept here because isCollapsed() and
  // isHidden() run for every layout on every advance and draw, and reading
  // it from the style chases a pointer each time. Refreshed wherever the
  // style or its display changes (see refreshStyleDisplayHidden).
  StyleDisplayHidden = 1 << 14,
};

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 state a LayoutComponent needs once it tweens or inherits a non-default
// animation style: two LayoutAnimationData (the second is the smoothing
// buffer, used when a new target arrives mid-flight) plus whatever the parent
// cascaded down. That's ~85 bytes, and a layout that never does either needs
// none of it -- its `from`/`to` are always just `m_layout`, so the accessors
// derive the whole block from m_layout while this is null. The lazy
// allocation mirrors ParticipantAnimation in layout_participant.cpp (itself
// modelled on this class, which predates the pattern); the lifetime below
// does not -- ParticipantAnimation frees its block, this one doesn't.
//
// Lifetime -- allocated by ensureAnimation() from two places:
//   * updateLayoutBounds(), when the layout is about to actually tween;
//   * setInheritedInterpolation(), for any cascade that isn't the all-default
//     (hold / null interpolator / 0s) one an unallocated layout already
//     reports. This path is duration-independent: a zero-duration cascade,
//     or one carrying only an interpolator, still allocates.
// Nothing ever releases it -- there is no reset path, so the block outlives
// the tween that prompted it and lives until the component is destroyed.
//
// So `m_animation != nullptr` means "has tweened or inherited a style at some
// point", NOT "is animating now" and NOT "animates()". Don't add code that
// reads the pointer as either; test the animation state (or animates()) for
// that, and treat a non-null block holding default cascade values as normal.
struct LayoutAnimation
{
  LayoutAnimationData a;
  LayoutAnimationData b;
  KeyFrameInterpolator* inheritedInterpolator = nullptr;
  LayoutStyleInterpolation
      inheritedInterpolation = LayoutStyleInterpolation::hold;
  float inheritedInterpolationTime = 0.0f;
};

// 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;

  // Null until this layout first tweens or inherits a non-default animation
  // style; never released once allocated. See LayoutAnimation.
  std::unique_ptr<LayoutAnimation> m_animation;
  // The 1-byte enum and the 2-byte flags word are kept adjacent so they
  // pack into a single 4-byte slot with no padding.
  LayoutDirection m_inheritedDirection = LayoutDirection::inherit;
  LayoutComponentFlags
      m_layoutFlags = LayoutComponentFlags::ParentIsRow |
                      LayoutComponentFlags::PositionLeftChanged |
                      LayoutComponentFlags::PositionTopChanged |
                      LayoutComponentFlags::ComposeTransform;
  // 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(); }
  // Null only while m_animation is unallocated -- callers either bail or
  // fall back on m_layout. Non-null does not imply a tween is in flight.
  // See LayoutAnimation.
  LayoutAnimationData* currentAnimationData();
  // Realizes m_animation, seeded so that doing so is never observable.
  LayoutAnimation& ensureAnimation();

  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;
  // Virtualized grid state; only allocated when a virtualized grid uses
  // this layout or hosts it as an item.
  struct VirtualGrid;
  VirtualGrid* m_virtualGrid = nullptr;
  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.

  /// This layout's own style interpolator. A scripted one resolves to the
  /// artboard instance's live clone of it, which layouts that inherit it
  /// then borrow through cascadeLayoutStyle.
  KeyFrameInterpolator* styleInterpolator();

  /// 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;
  void refreshStyleDisplayHidden();
#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;
#ifdef WITH_RIVE_LAYOUT
    refreshStyleDisplayHidden();
#endif
  }

  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);
  }
#ifdef WITH_RIVE_EDITOR
  // Editor documents default clip to true (the dev/defs initialValue), the
  // runtime to false, and coop and REV leave clip out when it is true.
  // EditorFile::createObject seeds the editor value on every native
  // creation, and the journal records false explicitly so an undone delete
  // restores it, locally and on peers.
  void applyEditorInitialValues() { m_Clip = true; }
  // Whether setting clip to `value` adds or drops this layout's proxy, so
  // the editor rebuilds its draw order. A layout that paints, or whose clip
  // is animated or bound, keeps its proxy either way.
  bool clipChangesDrawableProxy(bool value) const
  {
    return clip() != value && shapePaints().empty() &&
           !hasLayoutFlag(LayoutComponentFlags::ForceDrawableProxy);
  }
  void captureStateForJournal() override;
#endif
  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());
  }
  BoundsFidelity paintedWorldBounds(AABB* out) override;

  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);
  // Pins this hosted item to its grid cell (0-based) while a virtualized
  // grid realizes it; -1 clears it.
  void virtualGridCell(int column, int row);
  // Content sizes of a virtualized grid's items per row and column; layout
  // sizes every track as if all of them were realized. Both empty clears.
  void virtualGridContributions(
      const std::vector<float>& rows,
      const std::vector<float>& columns);
  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();
  // Flex children flow into lines that stack along the cross axis.
  bool wrapsLines();
  // Our main axis hugs, so wrapped lines break at the space available from
  // our parent and we take the width of the widest.
  bool hugsLines();
  // The alignment we impose on our children, on our own axes.
  LayoutContainerAlignment childAlignment();
  // A grid (not a stack): children auto-place into rows of cells.
  bool isGridContainer();
  // Resolved row or column line positions in local space after layout,
  // empty unless this is a solved grid; returns the gap between their tracks.
  float gridLines(bool rows, std::vector<float>& out);
  // 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;
  QuietState quietState() 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();
  // Older files encode a hug as fixed scales on both axes of an
  // intrinsically sized leaf, so its scale types alone don't say it hugs.
  bool usesLegacyHugEncoding();
  // Whether the layout engine sizes this layout's width to its content: a
  // hug width, or the legacy encoding of one.
  bool hugsContentWidth();
  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 additiveAmountChanged() override;
  void syncShapePaintBlendModes();
  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