#ifndef GOAP_STATE_HPP
#define GOAP_STATE_HPP

#include <godot_cpp/variant/vector3.hpp>
#include <godot_cpp/variant/string_name.hpp>
#include <godot_cpp/classes/node.hpp>
#include <godot_cpp/classes/node3d.hpp>
#include <godot_cpp/classes/resource.hpp>

namespace godot { class CharacterActor; }
namespace godot::goap {
class Planner;

struct State {
    ~State();
    static State new_move_to(Node3D *location);
    static State new_animate(StringName animation);
    static State new_activate(Node *node);
    static State new_invalid();

    bool is_complete(CharacterActor *context) const;

    enum Type {
        STATE_MOVE_TO,
        STATE_ANIMATE,
        STATE_ACTIVATE,
        STATE_TYPE_MAX,
    };
    State::Type type{STATE_TYPE_MAX};
    union {
        Node3D* move_to;
        StringName *animate;
        Node *activate;
    };
};

class StateArgs : public Resource {
    GDCLASS(StateArgs, Resource);
    static void _bind_methods();
public:
    virtual State construct(Planner *context) const;
    void set_argument_property(StringName name);
    StringName get_argument_property() const;
    StringName argument_property;
};

class MoveStateArgs : public StateArgs {
    GDCLASS(MoveStateArgs, StateArgs);
    static void _bind_methods();
    virtual State construct(Planner *context) const override;
};

class AnimateStateArgs : public StateArgs {
    GDCLASS(AnimateStateArgs, StateArgs);
    static void _bind_methods();
public:
    virtual State construct(Planner *context) const override;
};

class ActivateStateArgs : public StateArgs {
    GDCLASS(ActivateStateArgs, StateArgs);
    static void _bind_methods();
public:
    virtual State construct(Planner *context) const override;
};
};

#endif // !GOAP_STATE_HPP
