#ifndef TUNNELS_PLAYER_HPP
#define TUNNELS_PLAYER_HPP

#include "godot_cpp/variant/transform3d.hpp"
#include "utils/player.hpp"
#include "utils/player_input.hpp"
#include <godot_cpp/classes/camera3d.hpp>
#include <godot_cpp/classes/character_body3d.hpp>
#include <godot_cpp/classes/curve.hpp>
#include <godot_cpp/classes/input_event.hpp>

namespace godot {
class CharacterActor;

class TunnelsPlayer : public Node3D, public IPlayer {
    GDCLASS(TunnelsPlayer, Node3D);
    static void _bind_methods();

    enum State {
        ManualControl = 0x0,
        Tactics = 0x1,
        Overview = 0x2,
    };

public:
    virtual void _enter_tree() override;
    virtual void _ready() override;
    virtual void _exit_tree() override;
    virtual void _process(double delta_time) override;

    void process_mouse_location(double delta_time);
    void process_camera_rotation(double delta_time);

    virtual void setup_player_input(PlayerInput *input) override;
    virtual Node *to_node() override;
    virtual void spawn_at_position(Transform3D const &at) override;

    void horizontal_move_input(Ref<InputEvent> event, float value);
    void vertical_move_input(Ref<InputEvent> event, float value);
    void mode_switch_input(Ref<InputEvent> event, float value);
    void fire_pressed(Ref<InputEvent> event, float value);

    void try_select_marker();
    void initialize_character();

    Vector3 get_world_move_input() const;
    Vector3 get_mouse_world_position(Vector3 axis, float depth) const;

    void set_camera_rotation_ramp(Ref<Curve> curve);
    Ref<Curve> get_camera_rotation_ramp() const;

    CharacterActor *get_character() const;
private:
    Vector2 move_input{0,0};
    Vector2 mouse_location{0,0};
    Vector3 mouse_world_ray_normal{0.f,0.f,0.f};
    TunnelsPlayer::State state{State::ManualControl};

    CharacterActor *character{nullptr};
    Node3D *reticle{nullptr};
    Camera3D *camera{nullptr};

    Ref<Curve> camera_rotation_ramp{};

    static float const ROTATION_SPEED;
    static float const ROTATION_Y_MIN_INFLUENCE;
    static float const ROTATION_MARGIN_TACTICS_MUL;
    static float const ROTATION_MARGIN;
    static float const TACTICS_MOVEMENT_SPEED;
};
}

#endif // !TUNNELS_PLAYER_HPP
