#include "Input.h"


// Constructeur et Destructeur
Input::Input()
: m_x(0), m_y(0), m_xRel(0), m_yRel(0),
m_avancer(SDL_SCANCODE_UP), m_reculer(SDL_SCANCODE_DOWN), m_droite(SDL_SCANCODE_RIGHT), m_gauche(SDL_SCANCODE_LEFT),
m_terminer(false), m_relativeMouse(false), m_window(0), m_windowHalfHeight(0), m_windowHalfWidth(0)
{
    // Initialisation du tableau m_touches[]
    for(int i(0); i < SDL_NUM_SCANCODES; i++)
        m_touches[i] = false;

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


Input::~Input()
{}


// Méthodes
void Input::updateEvenements()
{
    // Pour éviter des mouvements fictifs de la souris, on réinitialise les coordonnées relatives
    m_xRel = 0;
    m_yRel = 0;

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

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

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

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

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

            break;

            // Cas de la fermeture de la fenêtre
            case SDL_WINDOWEVENT:
                if(m_evenements.window.event == SDL_WINDOWEVENT_CLOSE)
                    m_terminer = 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::terminer() const
{
    return m_terminer;
}


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

    else
        SDL_ShowCursor(SDL_DISABLE);
}


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



// Getters

bool Input::getTouche(const SDL_Scancode touche) const
{
    return m_touches[touche];
}


bool Input::getBoutonSouris(const Uint8 bouton) const
{
    return m_boutonsSouris[bouton];
}


bool Input::mouvementSouris() const
{
    if(m_xRel == 0 && m_yRel == 0)
        return false;

    else
        return true;
}


// 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;
}

void Input::setMoveKeys(SDL_Scancode avancer, SDL_Scancode reculer, SDL_Scancode droite, SDL_Scancode gauche)
{
    m_avancer = avancer;
    m_reculer = reculer;
    m_droite = droite;
    m_gauche = gauche;
}

float Input::getMainXRel() const
{
    return (float) m_xRel;
}

float Input::getMainYRel() const
{
    return (float) m_yRel;
}

float Input::getMainXMove() const
{
    // Avancée de la caméra
    if(getTouche(m_avancer))
    {
        return -1.0;
    }

    // Recul de la caméra
    if(getTouche(m_reculer))
    {
        return 1.0;
    }

    // Caméra immobile
    return 0.0;
}

float Input::getMainYMove() const
{
    // Déplacement vers la gauche
    if(getTouche(m_gauche))
    {
        return -1.0;
    }

    // Déplacement vers la droite
    if(getTouche(m_droite))
    {
        return 1.0;
    }

    // Caméra immobile
    return 0.0;
}
