#include "Input.h"


// Constructeur et Destructeur
Input::Input()
        : m_x(0), m_y(0), m_xRel(0), m_yRel(0),
          m_finished(false), m_relativeMouse(false), m_window(0), m_windowHalfHeight(0), m_windowHalfWidth(0) {
    // Initialisation du tableau m_keys[]
    for (int i(0); i < SDL_NUM_SCANCODES; i++)
        m_keys[i] = false;

    // Initialisation du tableau m_mouseKeys[]
    for (int i(0); i < 8; i++)
        m_mouseKeys[i] = false;
}


Input::~Input() {}


// Méthodes
void Input::updateEvents() {
    // Réinitialise les coordonnées relatives
    m_xRel = 0;
    m_yRel = 0;

    // Boucle d'évènements
    while (SDL_PollEvent(&m_events)) {
        // Switch sur le type d'évènement
        switch (m_events.type) {
            // Cas d'une touche enfoncée
            case SDL_KEYDOWN:
                m_keys[m_events.key.keysym.scancode] = true;
                break;

                // Cas d'une touche relâchée
            case SDL_KEYUP:
                m_keys[m_events.key.keysym.scancode] = false;
                break;

                // Cas de pression sur un bouton de la souris
            case SDL_MOUSEBUTTONDOWN:
                m_mouseKeys[m_events.button.button] = true;
                break;

                // Cas du relâchement d'un bouton de la souris
            case SDL_MOUSEBUTTONUP:
                m_mouseKeys[m_events.button.button] = false;
                break;

                // Cas d'un mouvement de souris
            case SDL_MOUSEMOTION:
                if (m_relativeMouse) {
                    m_xRel = m_events.motion.x - m_windowHalfWidth;
                    m_yRel = m_events.motion.y - m_windowHalfHeight;
                } else {
                    m_x = m_events.motion.x;
                    m_y = m_events.motion.y;
                    m_xRel = m_events.motion.xrel;
                    m_yRel = m_events.motion.yrel;
                }

                break;

                // Cas de la fermeture de la fenêtre
            case SDL_WINDOWEVENT:
                if (m_events.window.event == SDL_WINDOWEVENT_CLOSE)
                    m_finished = true;
                break;


            default:
                break;
        }
    }

    // Pour éviter que la souris se barre en mode relative, on la "warp"
    if (m_relativeMouse)
        SDL_WarpMouseInWindow(m_window, m_windowHalfWidth, m_windowHalfHeight);
}


bool Input::isFinished() const {
    return m_finished;
}


void Input::showCursor(bool reponse) const {
    if (reponse)
        SDL_ShowCursor(SDL_ENABLE);

    else
        SDL_ShowCursor(SDL_DISABLE);
}


void Input::capPtr(bool reponse) {
    m_relativeMouse = reponse;
}



// Getters

bool Input::getKey(const SDL_Scancode key) const {
    return m_keys[key];
}

bool Input::getMouseKey(const Uint8 key) const {
    return m_mouseKeys[key];
}


bool Input::isMouseMoving() const {
    return !(m_xRel == 0 && m_yRel == 0);
}


// Getters concernant la position du curseur

int Input::getX() const {
    return m_x;
}

int Input::getY() const {
    return m_y;
}

int Input::getXRel() const {
    return m_xRel;
}

int Input::getYRel() const {
    return m_yRel;
}

void Input::setWindow(SDL_Window *activWindow) {
    // Attributio directe
    m_window = activWindow;

    // Détermination de l'endroit de capture du pointeur
    SDL_GetWindowSize(activWindow, &m_windowHalfWidth, &m_windowHalfHeight);
    m_windowHalfWidth /= 2;
    m_windowHalfHeight /= 2;
}

int Input::getMouseRelX() const {
    return m_xRel;
}

int Input::getMouseRelY() const {
    return m_yRel;
}
