#pragma once

#include "../InputMap.hpp"

#include "../../core/data/glm.hpp"
#include "../../core/world/position.h"

/// Player controller moving entity
struct Controllable {
public:
    struct options {
        float speed = 5.0f;
        int sensibility = 50;
        bool collide = true;
    };

    Controllable(GLFWwindow*, const InputMap&, const options&);
    ~Controllable();

    void capture(bool captureMouse, bool captureKeys, float deltaTime);
    void setOptions(const options &options) {
        o = options;
    }

    std::pair<float, float> getAngles() const { return std::make_pair(HorizontalAngle, VerticalAngle); }
    glm::vec3 getDirection() const { return glm::vec3(cos(VerticalAngle) * sin(HorizontalAngle), sin(VerticalAngle), cos(VerticalAngle) * cos(HorizontalAngle)); }
    struct axis {
        glm::vec3 direction;
        glm::vec3 up;
        glm::vec3 right;
    };
    axis getAxis() const;

    camera_pos position;
    glm::vec3 velocity;

private:
    GLFWwindow *window;
    const InputMap &inputs;

    float HorizontalAngle = 3.14f / 2;
    float VerticalAngle = 0.0f;

    bool capturingMouse = false;
    options o;
};
