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

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

    /// Send key input to Focusable children in hierarchy order.
    /// Returns true if any Focusable handled the input.
    bool keyInput(uint16_t key,
                  uint8_t modifiers,
                  bool isPressed,
                  bool isRepeat);

    /// Send text input to Focusable children in hierarchy order.
    /// Returns true if any Focusable handled the input.
    bool textInput(const std::string& text);

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

    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; }
    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 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 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.
    template <typename T = ArtboardInstance> std::unique_ptr<T> instance() const
    {
        std::unique_ptr<T> artboardClone(new T);
        artboardClone->copy(*this);

        artboardClone->m_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 (artboardClone->initialize() != StatusCode::Ok)
        {
            artboardClone = nullptr;
        }

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

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

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

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

    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);
};
} // namespace rive

#endif
