#ifndef _RIVE_SCRIPTED_DRAWABLE_HPP_
#define _RIVE_SCRIPTED_DRAWABLE_HPP_
#include "rive/generated/scripted/scripted_drawable_base.hpp"
#include "rive/animation/state_machine_instance.hpp"
#include "rive/advancing_component.hpp"
#include "rive/assets/script_asset.hpp"
#include "rive/listener_group.hpp"
#include "rive/scripted/scripted_object.hpp"
#include "rive/custom_property_group.hpp"
#include <stdio.h>
namespace rive
{
class Component;
class HitComponent;
class HitScriptedDrawable;

class ScriptedDrawable : public ScriptedDrawableBase,
                         public ScriptedObject,
                         public AdvancingComponent,
                         public ListenerGroupProvider
{
public:
#ifdef WITH_RIVE_SCRIPTING
    void didHydrateScriptInputs() override;
#endif
    void draw(Renderer* renderer) override;
    void update(ComponentDirt value) override;
    Core* hitTest(HitInfo*, const Mat2D&) override;
    uint32_t assetId() override { return scriptAssetId(); }
    StatusCode onAddedDirty(CoreContext* context) override;
    bool advanceComponent(float elapsedSeconds,
                          AdvanceFlags flags = AdvanceFlags::Animate |
                                               AdvanceFlags::NewFrame) override;
    StatusCode import(ImportStack& importStack) override;
    Core* clone() const override;
    const std::vector<Component*>& containerChildren() const override
    {
        return children();
    }
    void addProperty(CustomProperty* prop) override;
    bool addScriptedDirt(ComponentDirt value, bool recurse = false) override;
    rcp<DataContext> dataContext() override
    {
        if (artboard() != nullptr)
        {
            return artboard()->dataContext();
        }
        return nullptr;
    }
    ScriptProtocol scriptProtocol() override { return ScriptProtocol::node; }
    std::vector<ListenerGroupWithTargets*> listenerGroups() override
    {
        return {};
    }
    std::vector<HitComponent*> hitComponents(StateMachineInstance* sm) override;
    bool worldToLocal(Vec2D world, Vec2D* local);
    void markNeedsUpdate() override;
    bool willDraw() override;
    Component* component() override { return this; }
    bool keyInput(Key key,
                  KeyModifiers modifiers,
                  bool isPressed,
                  bool isRepeat);
    bool textInput(const std::string& text);

private:
    bool m_isAdvanceActive = true;
};

class HitScriptedDrawable : public HitComponent
{
private:
    ScriptedDrawable* m_drawable;
    bool handlesEvent(bool canHit, ListenerType hitEvent);
    std::string methodName(bool canHit, ListenerType hitEvent);

public:
    HitScriptedDrawable(ScriptedDrawable* drawable,
                        StateMachineInstance* stateMachineInstance) :
        HitComponent(drawable, stateMachineInstance)
    {
        this->m_drawable = drawable;
    }

    bool hitTest(Vec2D position) const override { return true; }
    void prepareEvent(Vec2D position,
                      ListenerType hitType,
                      int pointerId) override
    {}

    HitResult processEvent(Vec2D position,
                           ListenerType hitType,
                           bool canHit,
                           float timeStamp,
                           int pointerId) override;
};
} // namespace rive

#endif