#ifndef _TABLERO_H_
#define _TABLERO_H_

#include"gfx/datafile_tablero.h"


//Direcciones de las flechas(golpes)
//si hay 2 o mas direcciones, significa q hay un golpe multiple
#define   IZQUIERDA           1
#define   MEDIO               2
#define   DERECHA             4


//Puntaje de cada golpe
#define   ERRADO              1
#define   EXCELENTE           3
#define   PERFECTO            4


//Margenes de error del diablo maldito demoniaco puro y complicado(con limon y sal)
#define   MARGEN_PERFECTO     1
#define   MARGEN_EXCELENTE    2


//Velocidad de los golpes
#define   VELOCIDAD_GOLPES    3



extern BITMAP *buffer;
extern int cuadro_actual;

bool escapo=false;

struct golpe
{
    int y;
    bool activo;
        
    int tipo;
    int cuadro_de_aparicion;
    int cuadro_de_golpe;
};


class tablero
{
      private:
          int x;
          int y;
          int estado;
          
          int y_mira;
          int cantidad_golpes;
          int golpe_actual;
          
          DATAFILE *data;
          MIDI     *midi;
          PACKFILE *ARCH;
          
          golpe  *golpes;
          
      public:
          tablero();
          ~tablero();
             
          void dibujar();
          void procesar();
          
          void reservar_memoria(int cuanta);
          void set_golpe(int _tipo,int _aparicion,int _golpe);
          
          void set_estado(int _estado) { estado=_estado; }
          int  golpeo();
          void empezar();
          void cargar(int cual);
};


tablero::tablero()
{
    x=482;
    y=0;
    estado=0;
    
    y_mira=80;
    cantidad_golpes=0;
    golpe_actual=0;
    
    data = load_datafile("gfx/tablero.dat");
    
}


tablero::~tablero()
{
    unload_datafile(data);
    delete golpes;
}


void tablero::reservar_memoria(int cuanta)
{
     cantidad_golpes=cuanta;
     golpes = new golpe[cantidad_golpes];
}

void tablero::set_golpe(int _tipo,int _aparicion,int _golpe)
{
     if(golpe_actual>=cantidad_golpes)
         return;
     
     golpes[golpe_actual].tipo=_tipo;
     golpes[golpe_actual].cuadro_de_aparicion=_aparicion;
     golpes[golpe_actual].cuadro_de_golpe=_golpe;
     
     golpes[golpe_actual].y=490;
     golpes[golpe_actual].activo=false;
     
     golpe_actual++;
}


void tablero::procesar()
{
    for(int i=0;i!=cantidad_golpes;i++)
    {
        if(golpes[i].cuadro_de_aparicion==cuadro_actual)
            golpes[i].activo=true;
        
        if(golpes[i].activo)
        {
            golpes[i].y-=VELOCIDAD_GOLPES;
            if(golpes[i].y<(-10))
            {
                golpes[i].activo=false;
                escapo=true;
            }
        }    
    }       
}
     


void tablero::dibujar()
{
     draw_sprite(buffer,(BITMAP*)data[TABLERO].dat,x,y);
     draw_sprite(buffer,(BITMAP*)data[MIRA].dat,x+7,y_mira);
     if(estado & IZQUIERDA)
         draw_trans_sprite(buffer,(BITMAP*)data[ROJO].dat,x+7,y_mira+10);
     if(estado & MEDIO)
         draw_trans_sprite(buffer,(BITMAP*)data[VERDE].dat,x+43,y_mira+10);
     if(estado & DERECHA)
         draw_trans_sprite(buffer,(BITMAP*)data[AZUL].dat,x+78,y_mira+10);
     
     for(int i=0;i!=cantidad_golpes;i++)
     {
         if(golpes[i].activo)
         {
             if(golpes[i].tipo & IZQUIERDA)
                 draw_sprite(buffer,(BITMAP*)data[LINEA1].dat,x+7,golpes[i].y);
             if(golpes[i].tipo & MEDIO)
                 draw_sprite(buffer,(BITMAP*)data[LINEA2].dat,x+43,golpes[i].y);
             if(golpes[i].tipo & DERECHA)
                 draw_sprite(buffer,(BITMAP*)data[LINEA3].dat,x+78,golpes[i].y);
         }
     }
}


int tablero::golpeo()
{
    for(int i=0;i!=cantidad_golpes;i++)
    {
        if(golpes[i].activo)
        {
            if(golpes[i].cuadro_de_golpe-MARGEN_PERFECTO<=cuadro_actual && 
               golpes[i].cuadro_de_golpe+MARGEN_PERFECTO>=cuadro_actual)
            {
                if(golpes[i].tipo==estado)
                {
                    golpes[i].activo=false;
                    return PERFECTO;
                }
            }
            
            if(golpes[i].cuadro_de_golpe-MARGEN_EXCELENTE<=cuadro_actual && 
               golpes[i].cuadro_de_golpe+MARGEN_EXCELENTE>=cuadro_actual)
            {
                if(golpes[i].tipo==estado)
                {
                    golpes[i].activo=false;
                    return EXCELENTE;
                }
            }
        }
    }
    return ERRADO;
}


void tablero::cargar(int cual)
{
    if(cual==0)
    {
        ARCH = pack_fopen("songs/secret.dat","r");
        midi = load_midi("songs/secret.mid");
    }
    else if(cual==1)
    {
        ARCH = pack_fopen("songs/beatles.dat","r");
        midi = load_midi("songs/beatles.mid");
    }
    else if(cual==2)
    {
        ARCH = pack_fopen("songs/bird.dat","r");
        midi = load_midi("songs/bird.mid");
    }         
    if(!ARCH) return;
    cantidad_golpes = pack_mgetw(ARCH);
    
    reservar_memoria(cantidad_golpes);
    
    for(int i=0;i!=cantidad_golpes;i++)
    {     
             
        golpes[i].tipo                   =       pack_mgetw(ARCH);
        golpes[i].cuadro_de_aparicion    =       pack_mgetw(ARCH);
        golpes[i].cuadro_de_golpe        =       pack_mgetw(ARCH);
        
        golpes[i].y=490;
        golpes[i].activo=false;  
        golpe_actual++;
    }
    pack_fclose(ARCH);
}


void tablero::empezar()
{
     play_midi(midi,0);
}

#endif

