#include "Liner.h"

static SDL_Surface* s_linerSurface[4];
static SDL_Surface* s_trainee[15];
static SDL_Surface* s_mort(0);

Liner::Liner(int x, int y, int orientation, int id, SDL_Surface *screen, SDL_Surface *pseudo, Collisions *collisioneur, TableauPower *powerGetter)
: m_x(x), m_y(y), m_orientation(orientation), m_id(id), m_estVivant(false), m_fin(false), m_meurtrier(-1),
m_collisioneur(collisioneur), m_screen(screen), m_liner(0), m_cercle(0), m_pseudo(pseudo),
m_powerGetter(powerGetter), m_power(0)
{
    if (HAUT <= orientation && orientation <= GAUCHE)
        m_liner = s_linerSurface[orientation];

    SDL_Surface* cercle = SDL_LoadBMP("Textures/Cercle.bmp");

    if (!m_liner)
        std::cout << "Image du liner inexistante. Attention � initPict(). " << SDL_GetError() << std::endl;

    if (!cercle)
        std::cout << "Impossible de charger une surface dans l'objet Liner : " << SDL_GetError() << std::endl;
    else
    {
        m_cercle = colorMightyObjet(cercle, id);
        SDL_FreeSurface(cercle);
        SDL_SetColorKey( m_cercle, SDL_SRCCOLORKEY, SDL_MapRGB(m_cercle->format, 0, 0, 0) );
    }

}///Constructeur

Liner::~Liner()
{
    SDL_FreeSurface(m_cercle);
    m_trainee.clear();
}///Destructeur

void Liner::actualiser(int direction)
{
    //[1] Calcule le changement de direction
    m_orientation += direction;
    if (m_orientation==4)
        m_orientation=HAUT;

    else if (m_orientation==-1)
        m_orientation=GAUCHE;

    if (m_estVivant)//D�but d'�x�cution vivant
    {
            //[2] Rajoute un mur
            m_collisioneur->ajouter(m_x, m_y, m_id);

            //[3] Avance
            avancer(1);
    }//Fin d'ex�cution vivant

    //[4] Misa � jour du pointeur de pouvoir
    if (m_power!=0)
    {
        if(m_power->estUtilise())
            m_power=0;
    }
    else
        m_power=m_powerGetter->chercherPouvoir(m_x, m_y);

}///actualiser

void Liner::collisioner()
{
    if (m_collisioneur->tester(m_x, m_y) != VIDE)
    {
        if (m_power!=0)
        {
            m_power->postMortemPower(m_x, m_y, m_id);
            m_power = 0;
        }
        if (m_collisioneur->tester(m_x, m_y) != VIDE){
            m_estVivant = false;
            m_meurtrier = m_collisioneur->tester(m_x, m_y);
            if ( m_meurtrier == NEUTRE || m_meurtrier == m_id ) m_meurtrier = 5;
        }
    }
}///collisioner

void Liner::afficher()
{
    //[1] Calculs
    m_position.x = m_x * 20;
    m_position.y = m_y * 20;

    if (m_estVivant)
        m_liner = s_linerSurface[m_orientation];
    else
        m_liner=s_mort;

    //[2] Affiche train�e
    for ( Uint16 i(1); i<m_trainee.size(); i++ )
    {
        SDL_BlitSurface( s_trainee[i-1], 0, m_screen, &m_trainee[i] );
    }

    //[3] Affiche liner
    SDL_BlitSurface(m_cercle, 0, m_screen, &m_position);
    SDL_BlitSurface(m_liner, 0, m_screen, &m_position);

    //[4] Affiche pseudo
    if ( m_fin )
    {
        m_position.y += 20;
        SDL_BlitSurface(m_pseudo, 0, m_screen, &m_position);
    }

    //[5] Affiche pouvoir
    if (m_power!=0)
        m_power->afficher(m_x, m_y);
}///afficher

void Liner::direEstFini(bool fin)
{
    m_fin = fin;
}///direEstFini

bool Liner::estVivant() const
{
    return m_estVivant;
}///estVivant

void Liner::avancer(int nbFois)
{
    // Avanc�e
    for (int i(0); i<nbFois; i++)
    {
        switch (m_orientation)
        {
            case HAUT:
                m_y-=1;
                break;
            case BAS:
                m_y+=1;
                break;
            case DROITE:
                m_x+=1;
                break;
            case GAUCHE:
                m_x-=1;
                break;
        }//Switch
    }//For

    // Remise sur le terrain
    m_collisioneur->coorectPos(m_x, m_y);

    // Mise � jour de la train�e
    m_trainee.push_front( { m_x * 20, m_y * 20, 0, 0 } );
    if ( m_trainee.size() > 16 ) m_trainee.pop_back();

}///avancer

void Liner::utiliserPouvoir()
{
    if (m_power!=0)
    {
        m_power->usePower(m_orientation, m_x, m_y, m_id);
        m_power=0;
        m_collisioneur->coorectPos(m_x, m_y);
    }
}///utiliserPouvoir

void Liner::reset( int x, int y, int orientation )
{
    // Attributs
    m_x = x ;
    m_y = y ;
    m_orientation = orientation ;
    m_estVivant = true ;
    m_fin = false ;
    m_meurtrier = -1 ;
    m_power = 0x0 ;
    m_trainee.clear();

    // Surface
    if (HAUT <= orientation && orientation <= GAUCHE)
        m_liner = s_linerSurface[orientation];
    else
        m_orientation = BAS ;
}///reset

int Liner::getMeurtrier()
{
    return m_meurtrier;
}///getMeutrier

/************************************Fonctions ind�pendantes************************************/

bool initialisationPict()
{
    /// Chargement
    s_linerSurface[HAUT] = SDL_LoadBMP("Textures/Haut.bmp");
    s_linerSurface[DROITE] = retournement(s_linerSurface[HAUT],1);
    s_linerSurface[BAS] = retournement(s_linerSurface[HAUT],2);
    s_linerSurface[GAUCHE] = retournement(s_linerSurface[HAUT],3);
    s_mort = SDL_LoadBMP("Textures/Mort.bmp");

    for ( int i(0); i<15; i++ )
    {
        s_trainee[i] = SDL_CreateRGBSurface( SDL_HWSURFACE, 20, 20, 32, 0, 0, 0, 0 );
        if ( !s_trainee[i] )
            return false;
        else
        {
            SDL_FillRect( s_trainee[i], 0, SDL_MapRGB( s_trainee[i]->format, 255, 255, 255 ) );
            SDL_SetAlpha( s_trainee[i], SDL_SRCALPHA, 255-12*i );
        }
    }

    /// Tests
    for (int i(0); i<4; i++)
    {
        if (!s_linerSurface[i])
            return false;
        else
            SDL_SetColorKey(s_linerSurface[i],SDL_SRCCOLORKEY,SDL_MapRGB(s_linerSurface[i]->format,255,0,0));
    }

    if (!s_mort)
        return false;

    return true;

}///initialisationPict

void fermeturePict()
{
    for(int i(0); i<4; i++)
    {
        SDL_FreeSurface(s_linerSurface[i]);
        s_linerSurface[i]=0;
    }

    SDL_FreeSurface(s_mort);
    s_mort=0;

    for ( int i(0); i<15; i++ )
    {
        SDL_FreeSurface(s_trainee[i]);
        s_trainee[i]=0;
    }

}///fermeturePict