#ifndef _TESC_MENU_PRINCIPAL_CPP_
#define _TESC_MENU_PRINCIPAL_CPP_

#include <math.h>
#include "escenarios.h"
#include "../gp2x/gp2x.h"

REGISTER_CLASS_ID(TESC_Menu_Principal);

TMAString TESC_Menu_Principal::gs_menu_options_text[6];
TMAString TESC_Menu_Principal::gs_scroll_text;        

TESC_Menu_Principal::TESC_Menu_Principal()
{
    miGame = (TGlaurungGame*)TMAGame::getCurrentGame();
}

TESC_Menu_Principal::~TESC_Menu_Principal()
{
    if (offwave!=NULL) delete offwave;
    if (offrulo!=NULL) delete offrulo;
    if (io_arquero!=NULL) delete io_arquero;
    if (io_flecha!=NULL) delete io_flecha;
    if (img_portada!=NULL) delete img_portada;
    if (img_scroll!=NULL) delete img_scroll;
    if (img_alpha!=NULL) delete img_alpha;
    if (img_credits!=NULL) delete img_credits;
}

bool TESC_Menu_Principal::doInit(const PMAObject params)
{
    TSpriteGlaurung::setScreen(NULL);
    TSpriteGlaurung::setBurladero(NULL);
    
    offwave=NULL;
    img_credits=NULL;
    img_portada=NULL;
    img_scroll=NULL;
    offrulo=NULL;
    ii_rulo=0; ii_scroll_pos=0; ii_chars_scroll=0;
 	ii_Estado=0;
    
    io_arquero = new TSpriteArquero(miGame->glaurungMap.getImageBank(0),NULL,true);
    io_flecha = new TSpriteFlecha(miGame->glaurungMap.getImageBank(0));
    i_estado_arquero = 0;
    ii_opcion_menu=1; ii_opcion_menu_old=1;
    
    switch (miGame->gi_idioma)
    {
        case TGlaurungGame::LG_CHIQUITISTANI:
        case TGlaurungGame::LG_SPAIN:
            img_credits = TMABitmap::loadFromFile("Data/Idioma/Textos/creditos_es.png");
            break;
        case TGlaurungGame::LG_ENGLISH:
            img_credits = TMABitmap::loadFromFile("Data/Idioma/Textos/creditos_en.png");
            break;
        case TGlaurungGame::LG_FRENCH:
            img_credits = TMABitmap::loadFromFile("Data/Idioma/Textos/creditos_fr.png");
            break;
        case TGlaurungGame::LG_DEUTCH:
            img_credits = TMABitmap::loadFromFile("Data/Idioma/Textos/creditos_de.png");
            break;
    }                  
    
    img_portada = TMABitmap::loadFromFile("Data/Menu/Screen.png");
    img_scroll = TMABitmap::create(640,60,false);
    img_alpha = TMABitmap::create(640,1,false);
    createRollWave();
	createSinTable(4,20);
				
	// Ponemos el arquero.
	//
	io_arquero->putAt(530,120);
	io_arquero->setFlipX(true);
	
	return true;
}

void TESC_Menu_Principal::doPaint(TMABitmap& g)
{
	g.clear(0);
	
	switch (ii_Estado)
	{
		case 0:	// Efecto Rulo..
			rollEffect(g);
			break;
			
		case 1: // Menu del Juego
			drawMenu(g);
			break;
			
		case 2: // Definición de teclas
		case 3:
		case 4:
		case 5:
		case 6:
		case 7:
		case 8:
        case 9:
			drawDefineKeys(g);
			break;
		case 10:
            // Al terminar de redefinir el teclado, guardamos la configuración
            // y volvemos al menu.
            //
            miGame->saveConfiguration();
            drawMenu(g);
			gotoMenu(false);
			break;
			
		case 11: // Creditos
	       g.draw(img_credits,0,0,false);
	       break;
	}
}

bool TESC_Menu_Principal::doRun(void)
{
    if (ii_Estado<0) return false;
    
    switch (ii_Estado)
    {
        case 0:
			poll_joystick();
            if (joy[0].button[GB_START].b) 
            {
                joy[0].button[GB_START].b=0;
				gotoMenu(true);                
            }
            else if (joy[0].button[GB_SELECT].b) 
            {
				joy[0].button[GB_SELECT].b=0;
                gotoLanguage();
                return true;
            }
            break;
        
        case 1:
            
			poll_joystick();
			
			if (joy[0].button[GB_SELECT].b)
			{
				joy[0].button[GB_SELECT].b=0;
				gotoLanguage();
			}
			if (joy[0].button[GB_START].b)
			{
				joy[0].button[GB_START].b=0;
				if (ii_opcion_menu != ii_opcion_menu_old) break;
				ii_opcion_menu = 2;
			}			
			if (joy[0].button[GB_R].b)
			{
				joy[0].button[GB_R].b=0;
				if (ii_opcion_menu != ii_opcion_menu_old) break;
				ii_opcion_menu = 3;
			}			
            break;
            
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
        case 9:
            
        case 11: // Al pulsar una tecla en los creditos, volvemos al menu.
			poll_joystick();
			if (joy[0].button[GB_SELECT].b)
			{
	            joy[0].button[GB_SELECT].b=0;
				io_arquero->putAt(530,120);
                gotoMenu(false);
			}
            break;            
    }
    
    // Movemos el arquero si precisa.
    //
    if (ii_opcion_menu != ii_opcion_menu_old)
	{
		switch (ii_opcion_menu)
		{
		  case 1:
			  moverArquero(70,ii_opcion_menu);
			  break;

		  case 2:
			  moverArquero(120,ii_opcion_menu);
			  break;

		  case 3:
			  moverArquero(170,ii_opcion_menu);
			  break;
		}			
	}
    
    return false;
}                    

void TESC_Menu_Principal::gotoCredits(void)
{
    ii_Estado=11;
}

void TESC_Menu_Principal::gotoGame(void)
{
	ii_Estado=-1;
	miGame->setScene(new TESC_Juego());
}

void TESC_Menu_Principal::gotoDefineKeys(void)
{
    ii_Estado=2;
}

void TESC_Menu_Principal::gotoLanguage(void)
{
    ii_Estado=-1;
	miGame->setScene(new TESC_Seleccion_Idioma());
}

void TESC_Menu_Principal::gotoMenu(bool loadimage)
{
    if (loadimage) 
    {
        if (img_portada!=NULL) delete img_portada;
        img_portada = TMABitmap::loadFromFile("Data/Menu/ScreenLow.png");
    }
    ii_Estado=1;
}

void TESC_Menu_Principal::createRollWave(void)
{
    int *buff = getBresenhamDistances(MAX_RULO_SIZE - MAX_RULO_SIZE/3,MAX_RULO_SIZE/3,sizerulo);
    
    if (offrulo!=NULL) delete offrulo;
    offrulo = new int[sizerulo*2];

    for (int i=0;i<sizerulo;i++)
    {
        offrulo[i] = buff[sizerulo - i - 1];
        offrulo[i+sizerulo] = buff[i];
    }
    
    delete buff;
}

void TESC_Menu_Principal::createSinTable(int radio,int arcos)
{
    int i;
    double dx = (3.1415926535 * arcos) / 640;
    double val = 0;
    
    if (offwave!=NULL) delete offwave;
    offwave = new int[640];
    
    // Calculamos la tabla de senos para la onda vertical.
    //
    for(i=0;i<640;i++)
    {
        offwave[i]=(int)(radio*sin(val));
        val+=dx;
    }
}

void TESC_Menu_Principal::rotateSinTable(void)
{
	int tmp[2]= {offwave[639],offwave[638]};
	memmove(&offwave[2],&offwave[0],638*sizeof(int));
	offwave[0] = tmp[0];
	offwave[1] = tmp[1];
}

int* TESC_Menu_Principal::getBresenhamDistances(int radius_x,int radius_y,int& sizebuff)
{
    int x,y,a2,b2, S, T;
    sizebuff=radius_x+1;
    int *buffer = new int[sizebuff];
    
    a2 = radius_x*radius_x;
    b2 = radius_y*radius_y;
    x = 0;
    y = radius_y;
    S = a2*(1-2*radius_y) + 2*b2;
    T = b2 - 2*a2*(2*radius_y-1);
    
    buffer[x]=y;
    
    do
    {
        if (S<0)
        {
            S += 2*b2*(2*x+3);
            T += 4*b2*(x+1);
            x++;	  
        }
        else if (T<0)
        {
            S += 2*b2*(2*x+3) - 4*a2*(y-1);
            T += 4*b2*(x+1) - 2*a2*(2*y-3);
            x++;
            y--;
        }
        else
        {
            S -= 4*a2*(y-1);
            T -= 2*a2*(2*y-3);
            y--;           
        }
        buffer[x]=y;
    }
    while (y>0);
    for (int i=1;i<sizebuff;i++) buffer[i-1] = abs(buffer[i] - buffer[i-1]);
    return buffer;
}

void TESC_Menu_Principal::drawMenu(TMABitmap& g)
{
	g.draw(img_portada,0,0,false);
	
	miGame->fontRed.drawText(g,*gs_menu_options_text[2],-1,100,offwave,640);
	miGame->fontRed.drawText(g,*gs_menu_options_text[3],-1,150,offwave,640);
    miGame->fontRed.drawText(g,*gs_menu_options_text[1],-1,200,offwave,640);
    
    miGame->fontBlue.drawText(g,*gs_menu_options_text[0],-1,260,offwave,640);

	miGame->fontBlue.drawText(g,*gs_menu_options_text[4],-1,320,offwave,640);
	miGame->fontBlue.drawText(g,*gs_menu_options_text[5],-1,350,offwave,640);

	doScroll(g);
	
    // Movemos el arquero si precisa.
    //
    if (i_estado_arquero==2 || i_estado_arquero==3) borraFranja(g);        
	if (io_flecha->isValid()) io_flecha->draw(g);
	io_arquero->draw(g);	
	rotateSinTable();	
}

void TESC_Menu_Principal::drawDefineKeys(TMABitmap& g)
{
	g.draw(img_portada,0,0,false);
	doScroll(g);
	rotateSinTable();
}

void TESC_Menu_Principal::rollEffect(TMABitmap& g)
{
	int i,ydest,yorig,offx=0,offrulosize=sizerulo*2;
	
	// Dibujamos la parte que esta plegada.
	//
	g.draw(img_portada,0,0,640,ii_rulo,0,0,false);
	yorig = ii_rulo + offrulosize;
			
	for (i=0;i<offrulosize;i++)
	{
		ydest = ii_rulo +  - i;
		yorig += offrulo[i];
		if (i<sizerulo/2) offx +=offrulo[i]; else offx -= offrulo[i];
		g.draw(img_portada,0,yorig,640,1,offx,ydest,false);
	}
	
	if (ii_rulo<480) ii_rulo+=2; 
}

void TESC_Menu_Principal::doScroll(TMABitmap& g)
{
	int scrx = (ii_scroll_pos<610)?ii_scroll_pos:610;
	TMAString txt = gs_scroll_text.mid(ii_chars_scroll,ii_chars_scroll+32);
	
	img_scroll->clear(TMAGame::getRGBColor(255,0,255));
	miGame->fontMulti.drawText(*img_scroll,*txt,610-scrx,0);
	miGame->fontBlue.drawText(*img_scroll,*txt,610-scrx,30);
	
	ii_scroll_pos+=2;

	if (ii_scroll_pos>=610)
	{
		if (txt.text()[31]!='#')
		{
			ii_chars_scroll++;
			ii_scroll_pos -= 20;
		}
		else
		{
			ii_chars_scroll=0;
			ii_scroll_pos=0;
		}
	}
	
	// Copiamos el texto de scroll sin reflejar.
	//
	g.draw(img_scroll,30,0,610,30,15,400,true);
    
    // Copiamos la parte reflejada del Scroll, simulando onda.
	//
	g.setAlpha(180);
    for (int i=0;i<30;i++)
	{
		img_alpha->clear(TMAGame::getRGBColor(255,0,255));
        img_alpha->draw(img_scroll,30,30+i,610,1,15+offwave[i],0,true);
		g.drawAlpha(img_alpha,0,460-i);
	}    
	g.setAlpha(0);
}	

void TESC_Menu_Principal::borraFranja(TMABitmap& g)
{
    g.draw(img_portada,
		ir_borrado.x,ir_borrado.y,
		ir_borrado.width,ir_borrado.height,
		ir_borrado.x,ir_borrado.y,false);
}

void TESC_Menu_Principal::moverArquero(int y,int opcion)
{
	if (abs(io_arquero->position.y - y)<=4)
	{
		io_arquero->position.y = y;
		
		switch (i_estado_arquero)
		{
		case 0:
			i_estado_arquero++;

		case 1:
			io_flecha->init(io_arquero->position.x,io_arquero->position.y + 30,true,15);
            ir_borrado.x = io_flecha->position.x + io_flecha->position.width;
			ir_borrado.y = io_flecha->position.y-12;
			ir_borrado.width = ir_borrado.x;
            ir_borrado.height = 45;
            i_estado_arquero++;

		case 2:
            // Copiamos el trozo por el que va pasando la flecha, para ir borrando
            // el fondo.
            //
            io_flecha->animate();
            ir_borrado.x = io_flecha->position.x + io_flecha->position.width;
                
			if (!io_flecha->isValid()) i_estado_arquero++;
			break;

		case 3:
			ii_opcion_menu_old=opcion;
			i_estado_arquero=0;
			switch (opcion) 
            {
                case 1:
                    gotoDefineKeys();
                    break;
                case 2:
                    gotoGame();
                    return;
                case 3:
                    gotoCredits();
                    break;
            }
			break;
		}	
	}
	else if (io_arquero->position.y<y)
	{
		io_arquero->position.y+=4;
		io_arquero->animate();
	}
	else 
	{
		io_arquero->position.y-=4;
		io_arquero->animate();
	}
}

#endif
