#include "GLFW/glfw3.h"

#include "window/input_system.hpp"

using namespace kuiper;

void input_system::set_key_state(int key, int state) {
    m_key_states[key].state = state;

    // Call any action handlers

    if (state == GLFW_PRESS) {
        for (const auto& f : m_action_listeners[m_action_keymap[key]]) {
            f();
        }
    }

    return;
}

int input_system::get_key_state(int key) const {
    return m_key_states[key].state;
}

bool input_system::is_key_pressed(int key) const {
    return m_key_states[key].state == GLFW_PRESS;
}

bool input_system::is_key_released(int key) const {
    return m_key_states[key].state == GLFW_RELEASE;
}

bool input_system::is_key_held(int key) const {
    return m_key_states[key].state == GLFW_REPEAT;
}

bool input_system::is_key_down(int key) const {
    return m_key_states[key].state == GLFW_PRESS || m_key_states[key].state == GLFW_REPEAT;
}

// Mouse

void input_system::set_mouse_pos(const glm::vec2& pos) {
    m_mouse_state.delta_pos = m_old_mouse_pos - pos;
    m_mouse_state.pos       = pos;
    return;
}

void input_system::set_mouse_delta(const glm::vec2& pos) {
    m_mouse_state.delta_pos = pos;
    return;
}

glm::vec2 input_system::get_mouse_pos() const {
    return m_mouse_state.pos;
}

glm::vec2 input_system::get_mouse_delta() const {
    return m_mouse_state.delta_pos;
}

void input_system::subscribe_to_action(action_type type, const action_fn_t& callback) {
    m_action_listeners[type].push_back(callback);
}
