#ifndef _RIVE_ARTBOARD_HPP_
#define _RIVE_ARTBOARD_HPP_

#include "rive/advance_flags.hpp"
#include "rive/resetting_component.hpp"
#include "rive/animation/linear_animation.hpp"
#include "rive/animation/state_machine.hpp"
#include "rive/core_context.hpp"
#include "rive/data_bind/data_context.hpp"
#include "rive/data_bind/data_bind_container.hpp"
#include "rive/viewmodel/viewmodel_instance_value.hpp"
#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp"
#include "rive/generated/artboard_base.hpp"
#include "rive/hit_info.hpp"
#include "rive/math/aabb.hpp"
#include "rive/renderer.hpp"
#include "rive/text/text_value_run.hpp"
#include "rive/event.hpp"
#include "rive/audio/audio_engine.hpp"
#include "rive/math/raw_path.hpp"
#include "rive/typed_children.hpp"
#include "rive/virtualizing_component.hpp"
#include "rive/input/focus_node.hpp"
#include "rive/semantic/semantic_node.hpp"
#include "rive/lua/scripting_vm.hpp"

#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <vector>

namespace rive
{
class KeyFrameInterpolator;
class ArtboardComponentList;
class ArtboardHost;
class File;
class Drawable;
class Factory;
class Node;
class DrawTarget;
class ArtboardImporter;
class NestedArtboard;
class ArtboardInstance;
class LinearAnimationInstance;
class Scene;
class StateMachineInstance;
class Joystick;
class TextValueRun;
class Event;
class SMIBool;
class SMIInput;
class SMINumber;
class SMITrigger;
class DataBind;
class DataBindContainer;
class ScriptedObject;
class FocusManager;
class SemanticManager;
class SemanticNode;

#ifdef WITH_RIVE_TOOLS
typedef void (*ArtboardCallback)(void*);
typedef uint8_t (*TestBoundsCallback)(void*, float, float, bool);
typedef uint8_t (*IsAncestorCallback)(void*, uint16_t);
typedef float (*RootTransformCallback)(void*, float, float, bool);
#endif

class Artboard : public ArtboardBase,
                 public CoreContext,
                 public Virtualizable,
                 public ResettingComponent,
                 public DataBindContainer
{
    friend class File;
    friend class ArtboardImporter;
    friend class Component;

private:
    std::vector<Core*> m_Objects;
    std::vector<Core*> m_invalidObjects;
    std::vector<LinearAnimation*> m_Animations;
    std::vector<StateMachine*> m_StateMachines;
    std::vector<Component*> m_DependencyOrder;
    std::vector<Drawable*> m_Drawables;
    std::vector<ClippingShape*> m_clippingShapes;
    std::vector<DrawTarget*> m_DrawTargets;
    std::vector<NestedArtboard*> m_NestedArtboards;
    std::vector<ArtboardComponentList*> m_ComponentLists;
    std::vector<ArtboardHost*> m_ArtboardHosts;
    std::vector<Joystick*> m_Joysticks;
    std::vector<ResettingComponent*> m_Resettables;
    std::vector<ScriptedObject*> m_ScriptedObjects;
    std::vector<AdvancingComponent*> m_advancingComponents;
    rcp<DataContext> m_DataContext = nullptr;
#ifdef WITH_RIVE_SCRIPTING
    rcp<ScriptingVM> m_scriptingVM = nullptr;
#endif
    bool m_JoysticksApplyBeforeUpdate = true;

    unsigned int m_DirtDepth = 0;
    Factory* m_Factory = nullptr;
    Drawable* m_FirstDrawable = nullptr;
    bool m_IsInstance = false;
    bool m_FrameOrigin = true;
    std::unordered_set<LayoutComponent*> m_dirtyLayout;
    bool m_isCleaningDirtyLayouts = false;
    std::unique_ptr<KeyFrameInterpolator> m_ownedInheritedInterpolator;
    float m_originalWidth = 0;
    float m_originalHeight = 0;
    bool m_updatesOwnLayout = true;
    bool m_hostTransformMarkedDirty = false;
    bool m_didChange = true;
    Artboard* parentArtboard() const;
    ArtboardHost* m_host = nullptr;
    FocusManager* m_activeFocusManager = nullptr;
    SemanticManager* m_activeSemanticManager = nullptr;
    rcp<SemanticNode> m_semanticBoundaryNode;
#ifdef WITH_RIVE_TOOLS
    rcp<FocusNode> m_externalParentFocusNode;
#endif
    static uint64_t sm_frameId;
    bool sharesLayoutWithHost() const;
    void cloneObjectDataBinds(const Core* object,
                              Core* clone,
                              Artboard* artboard) const;
    void initScriptedObjects();

    // Variable that tracks whenever the draw order changes. It is used by the
    // state machine controllers to sort their hittable components when they are
    // out of sync
    uint8_t m_drawOrderChangeCounter = 0;
#ifdef WITH_RIVE_TOOLS
    uint16_t m_artboardId = 0;
#endif
    const Artboard* m_artboardSource = nullptr;

#ifdef EXTERNAL_RIVE_AUDIO_ENGINE
    rcp<AudioEngine> m_audioEngine;
#endif

    void sortDependencies();
    void sortDrawOrder();
    void clearRedundantOperations();
    void updateRenderPath() override;
    void update(ComponentDirt value) override;

public:
    static uint64_t frameId() { return sm_frameId; }
#ifdef TESTING
    static void incFrameId() { sm_frameId++; }
#elif WITH_RIVE_TOOLS
    static void incFrameId() { sm_frameId++; }
#endif
    void updateDataBinds(bool applyTargetToSource = true) override;
    void host(ArtboardHost* artboardHost);
    ArtboardHost* host() const;
    void addedToHost() { m_justAddedToHost = true; }

    /// Set the active FocusManager for this artboard. The FocusManager is
    /// typically owned by a StateMachineInstance.
    void setActiveFocusManager(FocusManager* manager)
    {
        m_activeFocusManager = manager;
    }
    /// Get the active FocusManager for this artboard.
    FocusManager* focusManager() const { return m_activeFocusManager; }

#ifdef WITH_RIVE_TOOLS
    /// Set an external parent FocusNode for this artboard's root-level focus
    /// nodes. This is used when the artboard is nested inside another artboard
    /// that has a FocusData in its hierarchy. The external parent allows focus
    /// nodes in this artboard to be children of a FocusData in the host
    /// artboard.
    void setExternalParentFocusNode(rcp<FocusNode> node);
    /// Get the external parent FocusNode for this artboard.
    rcp<FocusNode> externalParentFocusNode() const;
    // collapseSingle is only used by the editor. Its purpose is to set the
    // collapse value to the immediate artboard but not to its children
    void collapseSingle(bool);
#endif

    /// Build the focus tree for this artboard, registering all FocusData nodes
    /// with the given FocusManager.
    /// @param focusManager The FocusManager to register nodes with
    /// @param parentFocusNode Optional parent node for root-level focus nodes
    ///        (used for nested artboards to connect to parent's focus tree)
    void buildFocusTree(FocusManager* focusManager,
                        rcp<FocusNode> parentFocusNode = nullptr);

    /// Build the focus tree for this artboard using the parent node's manager.
    /// This is a convenience overload for nested artboards - the FocusManager
    /// is derived from the parent node's manager() reference.
    /// @param parentFocusNode The parent node to attach this artboard's focus
    ///        nodes under. Must have a valid manager() or this is a no-op.
    void buildFocusTree(rcp<FocusNode> parentFocusNode);

    /// Clean up the focus tree for this artboard, removing all FocusData nodes
    /// from the FocusManager. This should be called before the artboard is
    /// destroyed or recycled to prevent use-after-free when the FocusManager
    /// still holds references to FocusNodes pointing to deleted FocusData.
    void cleanupFocusTree();

    /// Set the active SemanticManager for this artboard. The SemanticManager is
    /// typically owned by a StateMachineInstance.
    void setActiveSemanticManager(SemanticManager* manager)
    {
        m_activeSemanticManager = manager;
    }
    /// Get the active SemanticManager for this artboard.
    SemanticManager* semanticManager() const { return m_activeSemanticManager; }

    /// Build the semantic tree for this artboard, registering all SemanticData
    /// nodes with the given SemanticManager.
    void buildSemanticTree(SemanticManager* semanticManager,
                           rcp<SemanticNode> parentSemanticNode = nullptr);

    /// Clean up the semantic tree for this artboard, removing all SemanticData
    /// nodes from the SemanticManager.
    void cleanupSemanticTree();

    // Semantic-only collapse for this artboard's semantic nodes.
    // When collapsing, walks the boundary's semantic subtree (O(K) semantic
    // nodes). When uncollapsing, falls back to m_Objects because
    // SemanticData::collapse(false) re-parents nodes outside the boundary.
    void collapseSemanticBoundary(bool value);

    /// Mark bounds dirty for all semantic nodes under this artboard's
    /// boundary node. Called when the host transform changes.
    void markSemanticBoundaryTransformDirty();

    /// Get the semantic boundary node for this artboard (null for root).
    rcp<SemanticNode> semanticBoundaryNode() const
    {
        return m_semanticBoundaryNode;
    }

    // Implemented for ShapePaintContainer.
    const Mat2D& shapeWorldTransform() const override
    {
        return worldTransform();
    }
    Component* virtualizableComponent() override { return this; }
    bool updatesOwnLayout() { return m_updatesOwnLayout; }
    StatusCode onAddedClean(CoreContext* context) override;
    void addDirtyDataBind(DataBind*) override;

private:
#ifdef TESTING
public:
    Artboard(Factory* factory) : m_Factory(factory) { m_Clip = true; }
#endif
    void addObject(Core* object);
    void addAnimation(LinearAnimation* object);
    void addStateMachine(StateMachine* object);
    void buildDataContext(rcp<DataContext> value);

public:
    Artboard();
    ~Artboard() override;
    bool validateObjects();
    StatusCode initialize();
    bool didChange() { return m_didChange; }

    Core* resolve(uint32_t id) const override;
#ifdef WITH_RIVE_TOOLS
    void artboardId(uint16_t id) { m_artboardId = id; }
    uint16_t artboardId() const { return m_artboardId; }
#endif

    void artboardSource(const Artboard* artboard)
    {
        m_artboardSource = artboard;
    }
    const Artboard* artboardSource() const
    {
        return isInstance() ? m_artboardSource : this;
    }
    bool isAncestor(const Artboard* artboard);

    /// Find the id of a component in the artboard the object in the artboard.
    /// The artboard itself has id 0 so we use that as a flag for not found.
    uint32_t idOf(Core* object) const;

    Factory* factory() const { return m_Factory; }

    // EXPERIMENTAL -- for internal testing only for now.
    // DO NOT RELY ON THIS as it may change/disappear in the future.
    Core* hitTest(HitInfo*, const Mat2D&) override;

    bool hitTestPoint(const Vec2D& position,
                      bool skipOnUnclipped,
                      bool isPrimaryHit) override;

    Vec2D rootTransform(const Vec2D&);

    void onComponentDirty(Component* component);

    /// Update components that depend on each other in DAG order.
    bool updateComponents();

    // Update layouts and components. Returns true if it updated something.
    bool updatePass(bool isRoot);

    void onDirty(ComponentDirt dirt) override;

    // Artboards don't update their world transforms in the same way
    // as other TransformComponents so we override this.
    // This is because LayoutComponent extends Drawable, but
    // Artboard is a special type of LayoutComponent
    void updateWorldTransform() override {}

    void markLayoutDirty(LayoutComponent* layoutComponent);
    void markHostTransformDirty();
    void cleanLayout(LayoutComponent* layoutComponent);

    LayoutData* takeLayoutData();
    bool syncStyleChanges() override;
    void syncStyleChangesWithUpdate(bool forceUpdate = false);
    std::unique_ptr<KeyFrameInterpolator>& ownedInheritedInterpolator()
    {
        return m_ownedInheritedInterpolator;
    }
    void calculateLayout();
    bool canHaveOverrides() override { return true; }

    bool advance(float elapsedSeconds,
                 AdvanceFlags flags = AdvanceFlags::AdvanceNested |
                                      AdvanceFlags::Animate |
                                      AdvanceFlags::NewFrame);
    bool advanceInternal(float elapsedSeconds,
                         AdvanceFlags flags = AdvanceFlags::AdvanceNested |
                                              AdvanceFlags::Animate |
                                              AdvanceFlags::NewFrame);
    void reset() override;
    uint8_t drawOrderChangeCounter() { return m_drawOrderChangeCounter; }
    Drawable* firstDrawable() { return m_FirstDrawable; };
    void addScriptedObject(ScriptedObject* object);

    /// Poll async work (image decodes, etc.) so promises resolve before
    /// script callbacks run. Called at the top of advance().
    void pollAsyncWork();

    void drawInternal(Renderer* renderer);
    void draw(Renderer* renderer) override;
    void addToRenderPath(RenderPath* path, const Mat2D& transform);
    void addToRawPath(RawPath& path, const Mat2D* transform);

    void changed();
#ifdef TESTING
    ShapePaintPath* clipPath() { return &m_worldPath; }
    ShapePaintPath* backgroundPath() { return &m_localPath; }
#endif

    const std::vector<Core*>& objects() const { return m_Objects; }
    template <typename T> TypedChildren<T> objects()
    {
        return TypedChildren<T>(
            Span<Core*>(m_Objects.data(), m_Objects.size()));
    }

    const std::vector<NestedArtboard*> nestedArtboards() const
    {
        return m_NestedArtboards;
    }
    const std::vector<ArtboardComponentList*> artboardComponentLists() const
    {
        return m_ComponentLists;
    }
    rcp<DataContext> dataContext() { return m_DataContext; }
#ifdef WITH_RIVE_SCRIPTING
    void scriptingVM(rcp<ScriptingVM> value)
    {
        m_scriptingVM = std::move(value);
    }
#endif
    // Advances detached scripted view model instances (those with no parents),
    // which are not reachable from the bound view model tree. No-op when
    // scripting is disabled. Called at the end of each frame.
    void advanceScriptedViewModels();
    NestedArtboard* nestedArtboard(const std::string& name) const;
    NestedArtboard* nestedArtboardAtPath(const std::string& path) const;

    float originalWidth() const { return m_originalWidth; }
    float originalHeight() const { return m_originalHeight; }
    float layoutWidth() const;
    float layoutHeight() const;
    float layoutX() const;
    float layoutY() const;
    AABB bounds() const;
    AABB worldBounds() const override;
    Vec2D origin() const;
    void xChanged() override;
    void yChanged() override;
    void originXChanged() override;
    void originYChanged() override;

    void resetSize()
    {
        width(m_originalWidth);
        height(m_originalHeight);
    }

    // Can we hide these from the public? (they use playable)
    bool isTranslucent() const;
    bool isTranslucent(const LinearAnimation*) const;
    bool isTranslucent(const LinearAnimationInstance*) const;
    void dataContext(rcp<DataContext> dataContext);
    void internalDataContext(rcp<DataContext> dataContext);
    void clearDataContext();
    void unbind();
    void rebind() override;
    void relinkDataContext() override;
    void bindViewModelInstance(rcp<ViewModelInstance> viewModelInstance,
                               rcp<DataContext> parent);
    void bindViewModelInstance(rcp<ViewModelInstance> viewModelInstance);
    void bindViewModelInstances(
        std::vector<rcp<ViewModelInstance>> viewModelInstances,
        rcp<DataContext> parent);
    // Sets the main (non-global) view model instance in the data context
    // without rebinding. Call bind() to apply. A global instance is routed to
    // setGlobalViewModelInstance.
    void setViewModelInstance(rcp<ViewModelInstance> viewModelInstance);
    // Sets/replaces the global view model instance bound under the given global
    // view model name without rebinding, preserving the main instance and the
    // other globals' order. Returns false if the name does not match the
    // instance's global view model. Call bind() to apply.
    bool setGlobalViewModelInstance(const std::string& name,
                                    rcp<ViewModelInstance> viewModelInstance);
    // Applies the current data context: rebinds the artboard's data binds.
    // No-op if nothing has been set.
    void bind();
    // @returns the global view model instance currently bound under the given
    // name, or nullptr if none has been set. Never creates.
    rcp<ViewModelInstance> globalViewModelInstance(const std::string& name);
    void rebuildDataBind(DataBind*) override;

    bool hasAudio() const;

    template <typename T = Component> T* find(const std::string& name)
    {
        for (auto object : m_Objects)
        {
            if (object != nullptr && object->is<T>() &&
                object->as<T>()->name() == name)
            {
                return static_cast<T*>(object);
            }
        }
        return nullptr;
    }

    template <typename T = Component> size_t count()
    {
        size_t count = 0;
        for (auto object : m_Objects)
        {
            if (object != nullptr && object->is<T>())
            {
                count++;
            }
        }
        return count;
    }

    template <typename T = Component> T* objectAt(size_t index)
    {
        size_t count = 0;
        for (auto object : m_Objects)
        {
            if (object != nullptr && object->is<T>())
            {
                if (count++ == index)
                {
                    return static_cast<T*>(object);
                }
            }
        }
        return nullptr;
    }

    int objectIndex(Core* component) const
    {
        int count = 0;
        for (auto object : m_Objects)
        {
            if (object == component)
            {
                return count;
            }
            count++;
        }
        return -1;
    }

    template <typename T = Component> std::vector<T*> find()
    {
        std::vector<T*> results;
        for (auto object : m_Objects)
        {
            if (object != nullptr && object->is<T>())
            {
                results.push_back(static_cast<T*>(object));
            }
        }
        return results;
    }

    size_t animationCount() const { return m_Animations.size(); }
    std::string animationNameAt(size_t index) const;

    /// Returns the count of FocusData objects that don't have a parent
    /// FocusData within this artboard (i.e., "root" focus nodes from this
    /// artboard's perspective).
    size_t rootFocusDataCount() const;

    /// Returns the FocusData at the given index among root FocusData objects.
    /// Returns nullptr if index is out of bounds.
    class FocusData* rootFocusDataAt(size_t index) const;

    size_t stateMachineCount() const { return m_StateMachines.size(); }
    std::string stateMachineNameAt(size_t index) const;

    LinearAnimation* firstAnimation() const { return animation(0); }
    LinearAnimation* animation(const std::string& name) const;
    LinearAnimation* animation(size_t index) const;

    StateMachine* firstStateMachine() const { return stateMachine(0); }
    StateMachine* stateMachine(const std::string& name) const;
    StateMachine* stateMachine(size_t index) const;

    /// When provided, the designer has specified that this artboard should
    /// always autoplay this StateMachine. Returns -1 if it was not
    // provided.
    int defaultStateMachineIndex() const;

    /// Make an instance of this artboard. A non null factory reroutes the
    /// instance's render resource creation (a deferred session facade);
    /// nested instances inherit it.
    template <typename T = ArtboardInstance>
    std::unique_ptr<T> instance(Factory* factory = nullptr) const
    {
        std::unique_ptr<T> artboardClone(new T);
        artboardClone->copy(*this);

        artboardClone->m_Factory = factory != nullptr ? factory : m_Factory;
        artboardClone->m_FrameOrigin = m_FrameOrigin;
        artboardClone->m_DataContext = m_DataContext;
        artboardClone->m_IsInstance = true;
        artboardClone->m_originalWidth = m_originalWidth;
        artboardClone->m_originalHeight = m_originalHeight;
#ifdef WITH_RIVE_TOOLS
        artboardClone->m_artboardId = m_artboardId;
#endif
        artboardClone->m_artboardSource =
            isInstance() ? m_artboardSource : this;
        cloneObjectDataBinds(this, artboardClone.get(), artboardClone.get());

        std::vector<Core*>& cloneObjects = artboardClone->m_Objects;
        cloneObjects.push_back(artboardClone.get());

        if (!m_Objects.empty())
        {
            // Skip first object (artboard).
            auto itr = m_Objects.begin();
            while (++itr != m_Objects.end())
            {
                auto object = *itr;
                cloneObjects.push_back(object == nullptr ? nullptr
                                                         : object->clone());
                // For each object, clone its data bind objects and target their
                // clones
                cloneObjectDataBinds(object,
                                     cloneObjects.back(),
                                     artboardClone.get());
            }
        }

        for (auto animation : m_Animations)
        {
            artboardClone->m_Animations.push_back(animation);
        }
        for (auto stateMachine : m_StateMachines)
        {
            artboardClone->m_StateMachines.push_back(stateMachine);
        }

        if (factory != nullptr && factory != m_Factory)
        {
            // Nested clones instanced off the file level source during the
            // clone loop; redo them on the override factory before
            // initialize wires animations to them.
            artboardClone->reinstanceNestedArtboards(factory);
        }

        if (artboardClone->initialize() != StatusCode::Ok)
        {
            artboardClone = nullptr;
        }

        assert(artboardClone->isInstance());
        return artboardClone;
    }

    void reinstanceNestedArtboards(Factory* factory);

    /// Returns true if the artboard is an instance of another
    bool isInstance() const { return m_IsInstance; }

    /// Returns true when the artboard will shift the origin from the top
    /// left to the relative width/height of the artboard itself. This is
    /// what the editor does visually when you change the origin value to
    /// give context as to where the origin lies within the framed bounds.
    bool frameOrigin() const { return m_FrameOrigin; }
    /// When composing multiple artboards together in a common world-space,
    /// it may be desireable to have them share the same space regardless of
    /// origin offset from the bounding artboard. Set frameOrigin to false
    /// to move the bounds relative to the origin instead of the origin
    /// relative to the bounds.
    void frameOrigin(bool value);

    bool deserialize(uint16_t propertyKey, BinaryReader& reader) override
    {
        bool result = ArtboardBase::deserialize(propertyKey, reader);
        switch (propertyKey)
        {
            case widthPropertyKey:
                m_originalWidth = width();
                break;
            case heightPropertyKey:
                m_originalHeight = height();
                break;
            default:
                break;
        }
        return result;
    }

    StatusCode import(ImportStack& importStack) override;

    float volume() const;
    void volume(float value);

    // Opacity imposed by a host (e.g. a NestedArtboard) that renders this
    // artboard as an instance. Kept separate from the `opacity` property so the
    // artboard's own opacity remains free to animate / data-bind; the two are
    // multiplied together when propagating opacity to this artboard's contents.
    float hostOpacity() const { return m_hostOpacity; }
    void hostOpacity(float value);

    // Opacity propagated to this artboard's contents: the artboard's own
    // (possibly animated) opacity folded with any host-imposed opacity.
    float childOpacity() override { return renderOpacity() * m_hostOpacity; }

    // True when the artboard has a non-identity rotation/scale of its own.
    bool hasSelfTransform() const
    {
        return rotation() != 0.0f || scaleX() != 1.0f || scaleY() != 1.0f;
    }

    // The artboard's own rotation/scale, pivoted at the content-local origin
    // (0,0). Applied on top of the frame-origin translation by both draw and
    // hit-test so they stay consistent. Identity when hasSelfTransform() is
    // false.
    Mat2D selfTransform() const
    {
        Mat2D m = Mat2D::fromRotation(rotation());
        m.scaleByValues(scaleX(), scaleY());
        return m;
    }

#ifdef EXTERNAL_RIVE_AUDIO_ENGINE
    rcp<AudioEngine> audioEngine() const;
    void audioEngine(rcp<AudioEngine> audioEngine);
#endif

#ifdef WITH_RIVE_LAYOUT
    void propagateSize() override;
#endif
private:
    float m_volume = 1.0f;
    float m_hostOpacity = 1.0f;
#ifdef WITH_RIVE_TOOLS
    ArtboardCallback m_layoutChangedCallback = nullptr;
    ArtboardCallback m_layoutDirtyCallback = nullptr;
    ArtboardCallback m_transformDirtyCallback = nullptr;
    TestBoundsCallback m_testBoundsCallback = nullptr;
    IsAncestorCallback m_isAncestorCallback = nullptr;
    RootTransformCallback m_rootTransformCallback = nullptr;

public:
    void* callbackUserData;
    void onLayoutChanged(ArtboardCallback callback)
    {
        m_layoutChangedCallback = callback;
    }
    void onLayoutDirty(ArtboardCallback callback)
    {
        m_layoutDirtyCallback = callback;
        addDirt(ComponentDirt::Components);
    }
    void onTransformDirty(ArtboardCallback callback)
    {
        m_transformDirtyCallback = callback;
        addDirt(ComponentDirt::Components);
    }
    void onTestBounds(TestBoundsCallback callback)
    {
        m_testBoundsCallback = callback;
    }
    void onIsAncestor(IsAncestorCallback callback)
    {
        m_isAncestorCallback = callback;
    }
    void onRootTransform(RootTransformCallback callback)
    {
        m_rootTransformCallback = callback;
    }
#endif

protected:
    // The File backing this artboard, when it is an instance. Used to lazily
    // create default global view model instances. The base Artboard (e.g. an
    // editor-time artboard) has no backing file.
    virtual rcp<const File> artboardFile() const;
};

class ArtboardInstance : public Artboard
{
public:
    ArtboardInstance();
    ~ArtboardInstance() override;

    /// Holds a reference to the File that vended this instance so the File
    /// outlives the instance.
    void file(rcp<const File> file);
    /// @returns the File that vended this instance, if any. Used to lazily
    /// create default global view model instances on demand.
    rcp<const File> file() const;

    std::unique_ptr<LinearAnimationInstance> animationAt(size_t index);
    std::unique_ptr<LinearAnimationInstance> animationNamed(
        const std::string& name);

    std::unique_ptr<StateMachineInstance> stateMachineAt(size_t index);
    std::unique_ptr<StateMachineInstance> stateMachineNamed(
        const std::string& name);

    /// When provided, the designer has specified that this artboard should
    /// always autoplay this StateMachine instance. If it was not specified,
    /// this returns nullptr.
    std::unique_ptr<StateMachineInstance> defaultStateMachine();

    // This attemps to always return *something*, in this search order:
    // 1. default statemachine instance
    // 2. first statemachine instance
    // 3. first animation instance
    // 4. nullptr
    std::unique_ptr<Scene> defaultScene();

    SMIInput* input(const std::string& name, const std::string& path);
    template <typename InstType>
    InstType* getNamedInput(const std::string& name, const std::string& path);
    SMIBool* getBool(const std::string& name, const std::string& path);
    SMINumber* getNumber(const std::string& name, const std::string& path);
    SMITrigger* getTrigger(const std::string& name, const std::string& path);
    TextValueRun* getTextRun(const std::string& name, const std::string& path);

protected:
    rcp<const File> artboardFile() const override;

private:
    rcp<const File> m_file;
};
} // namespace rive

#endif
