#pragma once

#include <flecs.h>
#include <glm/glm.hpp>
#include <set>

namespace Input {

struct InputModule
{
    InputModule(flecs::world& world);
};

enum class KeyCode : int
{
};

enum class Action : int
{
};

struct KeyboardInput
{
    KeyCode key_code;
    Action action;
    flecs::entity window;
};

struct MouseButtonInput
{
    KeyCode key_code;
    Action action;
    flecs::entity window;
};

struct MouseMotion
{
    glm::vec2 delta{};
};

template <typename T> class ButtonInput
{
public:
    auto pressed(T input) const -> bool { return pressed_keys.contains(input); }
    auto just_pressed(T input) const -> bool { return just_pressed_keys.contains(input); }
    auto just_released(T input) const -> bool { return just_pressed_keys.contains(input); }

    // private:
    void press(T input)
    {
        if (pressed_keys.insert(input).second) {
            just_pressed_keys.insert(input);
        }
    }

    void release(T input)
    {
        if (pressed_keys.erase(input) != 0) {
            just_released_keys.insert(input);
        }
    }

    std::set<T> pressed_keys;
    std::set<T> just_pressed_keys;
    std::set<T> just_released_keys;
};

}; // namespace Input
