#pragma once
#include <stdint.h>

namespace input
{
    /// @brief Inicialitza els sistemes de teclat, ratolí i gamepad
    void init();
    
    /// @brief Determina si la tecla especificada està sent polsada ara mateix
    /// @param key tecla a consultar
    /// @return true si està polsada, false si no
    bool keyDown(const uint8_t key);

    /// @brief Determina si la tecla especificada ha sigut polsada, pero no tornarà a ser true fins
    /// @brief que no se solte la tecla i se torne a polsar.
    /// @param key tecla a consultar
    /// @return true si està polsada, false si no
    bool keyPressed(const uint8_t key);

    /// @brief Determina si hi ha alguna tecla polsada ara mateix
    /// @return true si hi ha alguna tecla polsada, false si no
    bool anyKey();

    /// @brief Torna el codi de la tecla que està sent polsada ara mateix
    /// @return Quina tecla està sent polsada
    const uint8_t whichKey();

    /// @brief Torna el codi de la tecla que està sent polsada ara mateix
    /// @brief (nomes una vegada, com keypress)
    /// @return Quina tecla està sent polsada
    const uint8_t getKeyPressed();


    /// @brief Determina si el botó del pad especificat està sent polsat ara mateix
    /// @param btn botó del pad a consultar
    /// @return true si està polsat, false si no
    bool padBtnDown(const int8_t btn);

    /// @brief Determina si el botó del pad especificat ha sigut polsat, pero no tornarà a ser true fins
    /// @brief que no se solte el botó i se torne a polsar.
    /// @param btn botó del pad a consultar
    /// @return true si està polsat, false si no
    bool padBtnPressed(const int8_t btn);

    /// @brief Determina si hi ha algun botó del pad polsat ara mateix
    /// @return true si hi ha algun botó del pad polsat, false si no
    bool anyPadBtn();

    /// @brief Torna el codi del botó del pad que està sent polsat ara mateix
    /// @return Quina botó del pad està sent polsat
    const int8_t whichPadBtn();

    /// @brief Torna el codi del botó del pad que està sent polsat ara mateix
    /// @brief (nomes una vegada, com padBtnPressed)
    /// @return Quina botó del pad està sent polsat
    const int8_t getPadBtnPressed();


    /// @brief (US INTERN) Actualitza la tecla actualment polsada (keydown) desde jgame
    /// @param key tecla polsada
    void updateKey(const uint8_t key);

    /// @brief (US INTERN) Actualitza la tecla actualment polsada (keypress) desde jgame
    /// @param key tecla polsada
    void updateKeypressed(const uint8_t key);

    /// @brief (US INTERN) Actualitza el botó del ratolí actualment polsat desde jgame
    /// @param btn botó polsat
    void updateClk(const uint8_t btn);

    /// @brief (US INTERN) Actualitza el valor de la roda del ratolí actual desde jgame
    /// @param dy desplaçament de la rodeta
    void updateWheel(const int dy);

    /// @brief (US INTERN) Actualitza el botó actualment polsat (keydown) desde jgame
    /// @param btn botó polsat
    void updatePadBtn(const int8_t btn);

    /// @brief (US INTERN) Actualitza el botó actualment polsat (keypress) desde jgame
    /// @param btn botó polsat
    void updatePadBtnPressed(const int8_t btn);

    /// @brief Torna la posició X actual del ratolí
    /// @return valor de la coordenada X del ratolí
    const int mouseX();

    /// @brief Torna la posició Y actual del ratolí
    /// @return valor de la coordenada Y del ratolí
    const int mouseY();

    /// @brief Determina si el botó del ratolí especificat està sent polsada ara mateix
    /// @brief (Equivalent a keydown en tecles)
    /// @param btn botó a consultar
    /// @return true si està polsat, false si no
    const bool mouseBtn(const int btn);

    /// @brief Determina si el botó especificat ha sigut polsat, pero no tornarà a ser true fins
    /// @brief que no se solte el botó i se torne a polsar (Equivalent a keypress en tecles).
    /// @param btn botó a consultar
    /// @return true si està polsat, false si no
    const bool mouseClk(const int btn);

    /// @brief Obté el valor actual de la rodeta del ratolí
    /// @return 0 si no es mou, positiu si roda cap amunt, negatiu si roda cap avall
    const int mouseWheel();

}