#include "input.h"

#include <GLFW/glfw3.h>

namespace Input {

void keyboard_input_observer(KeyboardInput const& keyboard_input);
template <typename T> void clear_button_input(ButtonInput<T>& state);

InputModule::InputModule(flecs::world& world)
{
    world.component<KeyboardInput>();
    world.component<MouseButtonInput>();
    world.component<MouseMotion>();
    world.component<ButtonInput<KeyCode>>();

    world.system<ButtonInput<KeyCode>>("ClearButtonInput")
        .kind(flecs::PostUpdate)
        .each(clear_button_input<KeyCode>);

    world.observer<KeyboardInput>("KeyboardInputObserver")
        .event(flecs::OnSet)
        .each(keyboard_input_observer);
}

void keyboard_input_observer(KeyboardInput const& keyboard_input)
{
    auto* key_state = keyboard_input.window.get_mut<ButtonInput<KeyCode>>();

    if (keyboard_input.action == static_cast<Input::Action>(GLFW_PRESS)) {
        key_state->press(keyboard_input.key_code);
    } else if (keyboard_input.action == static_cast<Input::Action>(GLFW_RELEASE)) {
        key_state->release(keyboard_input.key_code);
    }
}

template <typename T> void clear_button_input(ButtonInput<T>& state)
{
    state.just_pressed_keys.clear();
    state.just_released_keys.clear();
}

template class ButtonInput<KeyCode>;

} // namespace Input
