#ifndef _RIVE_ARTBOARD_HPP_
#define _RIVE_ARTBOARD_HPP_

#include "rive/animation/linear_animation.hpp"
#include "rive/animation/state_machine.hpp"
#include "rive/core_context.hpp"
#include "rive/generated/artboard_base.hpp"
#include "rive/hit_info.hpp"
#include "rive/message.hpp"
#include "rive/math/aabb.hpp"
#include "rive/renderer.hpp"
#include "rive/shapes/shape_paint_container.hpp"

#include <queue>
#include <vector>

namespace rive {
    class File;
    class Drawable;
    class Factory;
    class Node;
    class DrawTarget;
    class ArtboardImporter;
    class NestedArtboard;
    class ArtboardInstance;
    class LinearAnimationInstance;
    class StateMachineInstance;

    class Artboard : public ArtboardBase, public CoreContext, public ShapePaintContainer {
        friend class File;
        friend class ArtboardImporter;
        friend class Component;

    private:
        std::vector<Core*> m_Objects;
        std::vector<LinearAnimation*> m_Animations;
        std::vector<StateMachine*> m_StateMachines;
        std::vector<Component*> m_DependencyOrder;
        std::vector<Drawable*> m_Drawables;
        std::vector<DrawTarget*> m_DrawTargets;
        std::vector<NestedArtboard*> m_NestedArtboards;

        unsigned int m_DirtDepth = 0;
        std::unique_ptr<CommandPath> m_BackgroundPath;
        std::unique_ptr<CommandPath> m_ClipPath;
        Factory* m_Factory = nullptr;
        Drawable* m_FirstDrawable = nullptr;
        bool m_IsInstance = false;
        bool m_FrameOrigin = true;

        std::queue<Message> m_MessageQueue;

        void sortDependencies();
        void sortDrawOrder();

        Artboard* getArtboard() override { return this; }

#ifdef TESTING
    public:
        Artboard(Factory* factory) : m_Factory(factory) {}
#endif
        void addObject(Core* object);
        void addAnimation(LinearAnimation* object);
        void addStateMachine(StateMachine* object);
        void addNestedArtboard(NestedArtboard* object);

        void testing_only_enque_message(const Message&);

    public:
        Artboard() {}
        ~Artboard();
        StatusCode initialize();

        Core* resolve(uint32_t id) const override;


        /// 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* = nullptr);

        void onComponentDirty(Component* component);

        /// Update components that depend on each other in DAG order.
        bool updateComponents();
        void update(ComponentDirt value) override;
        void onDirty(ComponentDirt dirt) override;

        bool advance(double elapsedSeconds);

        // Returns true iff calling popMessage() will return true.
        bool hasMessages() const;

        // If there are any queued messages...
        //   copies the first message into msg parameter
        //   removes that message from the queue
        //   returns true
        // else
        //   ignores msg parameter
        //   returns false
        //
        bool nextMessage(Message* msg);

        enum class DrawOption {
            kNormal,
            kHideBG,
            kHideFG,
        };
        void draw(Renderer* renderer, DrawOption = DrawOption::kNormal);

        CommandPath* clipPath() const { return m_ClipPath.get(); }
        CommandPath* backgroundPath() const { return m_BackgroundPath.get(); }

        const std::vector<Core*>& objects() const { return m_Objects; }

        AABB bounds() const;
        bool isTranslucent(const LinearAnimation*) const;
        bool isTranslucent(const LinearAnimationInstance*) const;

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

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

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

        LinearAnimation* firstAnimation() const;
        LinearAnimation* animation(std::string name) const;
        LinearAnimation* animation(size_t index) const;

        StateMachine* firstStateMachine() const;
        StateMachine* stateMachine(std::string name) const;
        StateMachine* stateMachine(size_t index) const;

        /// Make an instance of this artboard, must be explictly deleted when no
        /// longer needed.
        // Deprecated...
        std::unique_ptr<ArtboardInstance> instance() const;

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

        StatusCode import(ImportStack& importStack) override;
    };

    class ArtboardInstance : public Artboard {
    public:
        ArtboardInstance() {}

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

        std::unique_ptr<StateMachineInstance> stateMachineAt(size_t index);
        std::unique_ptr<StateMachineInstance> stateMachineNamed(std::string name);
    };
} // namespace rive

#endif
