#ifndef _TESC_JUEGO_CPP_
#define _TESC_JUEGO_CPP_

#include "../main/glaurung.h"
#include "escenarios.h"
#include <string.h>
#include <ctype.h>
#include "../gp2x/gp2x.h"


#define MENU_OPCIONES   0
#define MENU_CARGAR     1
#define MENU_GUARDAR    2
#define MENU_NOMBRAR    3
#define MENU_MAP        100

#define MAP_SCR_AX      30
#define MAP_SCR_AY      20

#define ESPERA_BRUJO_DRAGON     2000
#define ESPERA_APARECE          2200
#define ESPERA_DESAPARECE       3500

REGISTER_CLASS_ID(TESC_Juego);

int TESC_Juego::pasadizos[5][2] = { {33,66},{184,204},{138,214},{108,128},{91,122} };

TESC_Juego::TESC_Juego():TMAScene()
{
    miGame = (TGlaurungGame*)TMAGame::getCurrentGame();
    for (int i=0;i<6;i++) iaEnemyPos[i]=false;
    for (int i=0;i<3;i++) snap_bmp[i]=NULL;
    ii_seleccion=_Obj_Flechas;
    ii_brujo_dragon = E_SIN_BRUJO_DRAGON;
    ii_tiempo_brujo_dragon = 0;
    scrInfo = NULL;
    io_Screen=NULL;
    SprBurladero = new TSpriteBurladero(miGame->glaurungMap.getImageBank(0));
    SprSeleccion = new TSpriteSeleccion(miGame->glaurungMap.getImageBank(0),false,NULL);
    SprRedham = new TSpriteRedham(miGame->glaurungMap.getImageBank(0),miGame->glaurungMap.getImageBank(1));
    SprBrujoDragon = NULL;

    loadSnap();
}

TESC_Juego::~TESC_Juego()
{    
    if (SprBurladero!=NULL) delete SprBurladero;
    if (SprSeleccion!=NULL) delete SprSeleccion;
    if (SprRedham!=NULL) delete SprRedham;
    if (scrInfo!=NULL) delete[] scrInfo;
    if (io_Screen!=NULL) delete io_Screen;
    for (int i=0;i<3;i++) if (snap_bmp[i]) delete snap_bmp[i];
}

bool TESC_Juego::doInit(const PMAObject params)
{
    // Inicialmente el modo menu esta desactivado
    //
    ib_menu_mode = false;
    ii_menu_option=0;
    ii_menu_state=0;
    ii_snap_index=0;
    ii_mapx = 100; ii_mapy=100;
        
    TSpriteGlaurung::setBurladero(SprBurladero);
    SprSeleccion->putAt(475,0);
    
    // Obtenemos la información de las pantallas.
    //
    scrInfo = TScreenInfo::getScreenInfo();
    
    // Establecemos la velocidad de refresco.
    //
    miGame->setGameFPS(32);
        
    // Posicionamos el personaje
    //
    SprRedham->putAt(20*4,20*18);
    SprRedham->transformToChiquito(miGame->gi_idioma == TGlaurungGame::LG_CHIQUITISTANI);
    SprRedham->savePosition();
    
    // Establecemos le color de fondo y preparamos la primera pantalla
    //
    enterOnScreen(1);

    /* Probar Final
    SprRedham->ii_llaves=1;
    SprRedham->ii_gemas=0x07;
    enterOnScreen(43);
    */

    return true;
}
    
bool TESC_Juego::doRun(void)
{
	// Caso que estemos en la pantalla de Pasadizo.
	// En esta pantalla, no se permite la activación del menu.
	//
	if (io_Screen!=NULL && io_Screen->getID()==0)
	{
        if (!SprRedham->walkPasadizo()) exitPasadizo();
        return true;
    }
    
    // Si se pulsa la tecla opciones, pasamos al menu de opciones.
	//
	if (!ib_menu_mode)
    {
		poll_joystick();
        if (joy[0].button[GB_START].b && joy[0].button[GB_CLICK].b)
	    {
    		ib_menu_mode=true;
			joy[0].button[GB_START].b=0;
			joy[0].button[GB_CLICK].b=0;
            return true;
	    }
	    
	    if (joy[0].button[GB_R].b)
	    {
    		ib_menu_mode=true;
			joy[0].button[GB_R].b=0;
    		ii_menu_state=MENU_MAP;
    		// Centramos el mapa en la pantalla actual.
    		//
    		ii_mapx = scrInfo[io_Screen->getID()].posx * MAP_SCR_AX;
    		ii_mapy = scrInfo[io_Screen->getID()].posy * MAP_SCR_AY;
    		ii_mapx = 320 - ii_mapx - (MAP_SCR_AX/2);
    		ii_mapy = 240 - ii_mapy - (MAP_SCR_AY/2);
            return true;
	    }
	    
    }
    else
    {
        // Caso que estemos gestionando el menu.
        //
        doRunMenu();
        return true;
    }
	    
	// Caso que estemos gestionando el juego.
	//
    doRunGame();    
    
    // Devuelvemos true, porque hemos manejado los eventos RUN
    //
    return true;
}
 
void TESC_Juego::doRunGame(void)
{	
    static int tmp_tiempo_brujo = 0;
    ii_tiempo_brujo_dragon++;
    
    switch (ii_brujo_dragon)
    {
        case E_SIN_BRUJO_DRAGON:
            if (ii_tiempo_brujo_dragon == ESPERA_BRUJO_DRAGON) aparecerBrujoDragon();
            break;
            
        case E_APARECIENDO_BRUJO:
            if (ii_tiempo_brujo_dragon >= ESPERA_APARECE)
            {
                ii_brujo_dragon = E_CON_BRUJO;
                aparecerBrujoDragon();
            }
            break;
            
        case E_APARECIENDO_DRAGON:
            if (ii_tiempo_brujo_dragon >= ESPERA_APARECE) 
            {
                ii_brujo_dragon = E_CON_DRAGON;
                aparecerBrujoDragon();
            }
            break;
            
        case E_CON_BRUJO:
        case E_CON_DRAGON:
            
            if (SprBrujoDragon == NULL)
            {
                tmp_tiempo_brujo++;
                if (tmp_tiempo_brujo >= 30) aparecerBrujoDragon();
            } else tmp_tiempo_brujo=0;
            
            if (ii_tiempo_brujo_dragon == ESPERA_DESAPARECE) desaparecerBrujoDragon();
            break;            
    }    
    
	SprRedham->move();
	if (SprBurladero->isValid()) SprBurladero->animate();
	
	// Detectamos el cambio de pantalla
	//
	if (SprRedham->isEnterLeft()) enterLeftScreen();
	else if (SprRedham->isEnterUp()) enterUpScreen();
	else if (SprRedham->isEnterRight()) 
    {
        // Si se entra en la pantalla 239, se ha llegado el final del juego.
        //
        if (scrInfo[io_Screen->getID()].right==239)
        {
            gotoEndGame();
            return;
        }
        enterRightScreen();
    }
	else if (SprRedham->isEnterDown()) enterDownScreen();
	else
	{
    	// Detectamos las colisiones
    	//
    	if (!SprRedham->isDying())
    	{
    		detectCollisions();
    	}
 
    	if (SprRedham->ii_vidas<0) 
        {
            gotoMainMenu();
            return;
        }
    }
}

void TESC_Juego::doRunMenu(void)
{    
    static char buff[2]={0,0};
    //ii_menu_option=1;
    switch (ii_menu_state)
    {
        case MENU_OPCIONES:
				gotoMainMenu();
				return;
            	break;
        case MENU_MAP:
			poll_joystick();
            if (joy[0].button[GB_SELECT].b)
            {
                ib_menu_mode = false;
            	ii_menu_state=MENU_OPCIONES;
            	joy[0].button[GB_SELECT].b=0;
            	return;
            }

            if (joy[0].stick[0].axis[0].d2) ii_mapx+=10;
            if (joy[0].stick[0].axis[0].d1) ii_mapx-=10;
            if (joy[0].stick[0].axis[1].d1) ii_mapy-=10;
            if (joy[0].stick[0].axis[1].d2) ii_mapy+=10;     
            break;
    }
}	
    
void TESC_Juego::doPaint(TMABitmap& g) 
{
    g.clear(0);
	drawScreen(g);
	drawGameInfo(g);		
    if (ib_menu_mode) 
    {
       doPaintMenu(g);
    }
}

void TESC_Juego::doPaintMenu(TMABitmap& g)
{
    PMAImageBank img = NULL;
            
    // Creamos una pixelado de puntos negros alternados
    // para oscurecer la zona de juego.
    //
    /*
	for (int py=0;py<480;py++)
    {
        int odd=(py%2);
        for (int px=0;px<640;px+=2)
        {
            g.setPixel(odd+px,py,0);
        }
    }
*/
    switch (ii_menu_state)
    {
        case MENU_MAP:
            doPaintMap(g);
            break;
    }
}	

void TESC_Juego::doPaintMap(TMABitmap& g)
{
     static int flash=0;
     int ax=MAP_SCR_AX,ay=MAP_SCR_AY;
     int tx=ax/3,ty=ay/3;
     int cred = TMAGame::getRGBColor(255,0,0);        
     int ccofre = TMAGame::getRGBColor(200,180,20); 
     int cblack = TMAGame::getRGBColor(0,0,0);
     int cgreen = TMAGame::getRGBColor(120,190,90);
     int cburladero = TMAGame::getRGBColor(0,100,255);
     
     flash++;
     if (flash>20) flash=0;
     g.drawRectFilled(0,0,640,480,makecol(40,40,40));
     for (int j=0;j<2;j++)
     {
        for (int i=1;i<TScreenInfo::MAX_PANTALLAS;i++)
        {
            int color = (j==0)?cblack:((i==1)?cred:cgreen);
                   
            if (scrInfo[i].visitada)
            {
                int x = (ii_mapx + (scrInfo[i].posx*ax))-j;
                int y = (ii_mapy + (scrInfo[i].posy*ay))-j;
                
                // Dibujamos parte superior
                //
                if (scrInfo[i].top==-1)
                {
                    g.drawLine(x,y,x+ax-1,y,color);
                }
                else
                {
                    g.drawLine(x,y,x+tx-1,y,color);   
                    g.drawLine(x+2*tx,y,x+ax-1,y,color);
                }
                
                // Dibujamos parte Inferior
                //
                if (scrInfo[i].bottom==-1)
                {
                    g.drawLine(x,y+ay-1,x+ax-1,y+ay-1,color);
                }
                else
                {
                    g.drawLine(x,y+ay-1,x+tx-1,y+ay-1,color);
                    g.drawLine(x+2*tx,y+ay-1,x+ax-1,y+ay-1,color);
                }
                    
                // Dibujamos parte Izquierda
                //
                if (scrInfo[i].left==-1)
                {
                    g.drawLine(x,y,x,y+ay-1,color);
                }
                else
                {
                    g.drawLine(x,y,x,y+2*ty-1,color);
                }
                
                // Dibujamos parte Derecha
                //
                if (scrInfo[i].right==-1)
                {
                    g.drawLine(x+ax-1,y,x+ax-1,y+ay-1,color);
                }
                else
                {
                    g.drawLine(x+ax-1,y,x+ax-1,y+2*ty-1,color);
                }         
                
                if (j==1)
                {
                    
                    // Dibujamos el simbolo del cofre si lo hay
                    //
                    if (scrInfo[i].cofre!=TScreenInfo::SIN_COFRE)
                    {
                        g.drawRectFilled(x+tx,y+2*ty,x+2*tx,y+ay-3,ccofre);
                    }
                    
                    // Dibujamos el burladero si lo hay
                    //
                    for (int k=0;k<5;k++)
                    {
                        if (pasadizos[k][0]==i || pasadizos[k][1]==i)
                        {
                            g.drawRectFilled(x+tx+2,y+ty,x+2*tx-2,y+ay-3,cburladero);
                            
                            // Ahora dibujamos las lineas que unen las dos pantallas
                            // Si ambas han sido visitadas.
                            //
                            if (scrInfo[pasadizos[k][0]].visitada &&
                                scrInfo[pasadizos[k][1]].visitada)
                            {
                                int index = (pasadizos[k][0]==i)?1:0;
                                
                                if (index==1)
                                {                                    
                                    int x1 = (ii_mapx + (scrInfo[pasadizos[k][index]].posx*ax))-j;
                                    int y1 = (ii_mapy + (scrInfo[pasadizos[k][index]].posy*ay))-j;                                                                                                
                                    g.drawLine(x+ax/2, y+ay/2,  x+ax/2, y1+ay/2,cburladero);
                                    g.drawLine(x+ax/2, y1+ay/2, x1+ax/2,y1+ay/2,cburladero);
                                }
                            }                                              
                        }                                   
                    }
                    
                    // Dibujamos el indicador de donde estamos.
                    //
                    if (i==io_Screen->getID() && (flash<15))
                    {
                        g.drawCircleFilled(x+ax/2,y+ay/2,5,cred);
                    }
                }                
            }
         }
     }          
}

void TESC_Juego::drawSnap(TMABitmap& g)
{
    PMAImageBank img = miGame->glaurungMap.getImageBank(10);
    
    for (int i=0;i<3;i++)
    {
        g.drawSprite(img->getBitmap(8),45+i*180,150,false,false);
        if (i==ii_snap_index) g.drawSprite(img->getBitmap(9),45+i*180,150,false,false);
        if (snap_bmp[i]!=NULL) g.drawSprite(snap_bmp[i],55+i*180,158,false,false);
        if (snap_name[i].length()>0) 
        {
            int w = miGame->fontRubber.getTextWidth(snap_name[i].text());
            miGame->fontRubber.drawText(g,snap_name[i].text(),45+i*180+(170-w)/2,270);
        }
    }
}

void TESC_Juego::enterPasadizo(void)
{
    ii_scrBurladero = io_Screen->getID();
    enterOnScreen(0);
    findRedhamPosition();
    SprRedham->position.y+=20;
    if (miGame->isSoundAvailable()) miGame->isnd_Ultratumba.play(false);
}

void TESC_Juego::exitPasadizo(void)
{
    int lout=0;
        
    // En función del burladero de la pantalla en la que entremos
    // indicamos la pantalla por la que debe salir el personaje.
    //    
    for (int i=0;i<5;i++)
    {
        if (pasadizos[i][0]==ii_scrBurladero) lout=pasadizos[i][1];
        if (pasadizos[i][1]==ii_scrBurladero) lout=pasadizos[i][0];
    }
    
    if (lout!=0)
    {
        enterOnScreen(lout);
        SprBurladero->open();
        putRedhamOutBurladero();
        SprRedham->ib_flip_x=true;
    }
}       

bool TESC_Juego::enterOnScreen(int scr)
{        
	// Antes de pasar de pantalla, miramos si se estaba abriendo un cofre
	// para contabilizar su contenido.
	//
	for (int i=0;i<iv_SpritesFront.size();i++)
	{
		PSpriteGlaurung spr = (PSpriteGlaurung)iv_SpritesFront.elementAt(i);
		
        if (spr->isInstanceOf(CLASS_ID(TSpriteAbreCofre)))
		{
			PSpriteAbreCofre cofre = (PSpriteAbreCofre)spr;
			cofre->showTreasure(false);
			cofre->invalidate();
		}		
	}		
	
	// Preparamos la nueva pantalla
	//
	PMAScreenMap lo_scr = miGame->glaurungMap.getScreen(scr);
	if (lo_scr==NULL)
	{
		// Añadimos un texto indicando que la pantalla aun no esta desarrollada
		//
		PSpriteTexto sprtxt=new TSpriteTexto();
		sprtxt->init(2,-1,140,&miGame->fontMulti,"PANTALLA NO DESARROLLADA");
		addSprite(sprtxt,true);
		return false; 
	}
		
	// Asignamos la nueva pantalla
	//
	if (io_Screen!=NULL) delete io_Screen;
	io_Screen = lo_scr;
	lo_scr=NULL;
	
	// Debemos establecer la pantalla, para todos los sprites.
	//
	TSpriteGlaurung::setScreen(io_Screen);
	
	// Miramos si la pantalla actual tiene burladero.
	//
	findBurladero();
	
	// Miramis si la pantalla actual tenía un cofre abierto
	//
	openCofre(true);
	
	// Ahora preparamos el fondo de pantalla
	//
	miGame->glaurungMap.drawFastBuffer(io_Screen,0);
	
	// Ponemos los Sprites de la pantalla.
	// Los sprites frontales, textos y demás, no se tocan
	//
	removeGarbage(false);
	
	for (int i=0;i<6;i++) iaEnemyPos[i]=true;
	PMAImageBank bank=miGame->glaurungMap.getImageBank(0);
	
	for (int i=0;i<TScreenInfo::MAX_ENEMIGOS;i++)
	{
		if ( (scrInfo[scr].enemigos[i].tipo!=TEstadoEnemigo::NADA) && (scrInfo[scr].enemigos[i].vivo) )
		{
			PSpriteGlaurung enemigo = NULL;

            // El enemigo se crea, si su posicion es (0,1,2,3) o 
            // bien si es opcional (4,5) y el factor aleatorio es verdadero.
            //
			if (i<4||(i>3 && TSpriteGlaurung::miRND.nextInt(1000)<500))
			{

				switch (scrInfo[scr].enemigos[i].tipo)
				{
					case TEstadoEnemigo::SPIDER:
                        enemigo = new TSpriteSpider(bank,bank);
                        break;

					case TEstadoEnemigo::ARQUERO:
                        enemigo = new TSpriteArquero(bank,bank);
                        break;

					case TEstadoEnemigo::LANCERO:
                        enemigo = new TSpriteLancero(bank);
                        break;

					case TEstadoEnemigo::CABALLERO:
					    enemigo = new TSpriteCaballero(bank);
					    break;

					case TEstadoEnemigo::BAT0:
					    enemigo = new TSpriteMurcielago(bank,0);
					    break;

					case TEstadoEnemigo::BAT1:
					    enemigo = new TSpriteMurcielago(bank,1);
					    break;
					    
					case TEstadoEnemigo::MAGMA:
                        enemigo = new TSpriteMagma(bank);
                        break;
				}
			}

			if (enemigo!=NULL)
			{
				findEnemyPosition(enemigo);
				enemigo->setSprID(i);
				addSprite(enemigo,false);
			}
		}
	}
	
    if (SprRedham->isInvisible())
    {
        setEnemyTarget(NULL);
    }
    else
    {
        setEnemyTarget(SprRedham);
    }	
	
	scrInfo[scr].visitada = true;
	
	// Si no ha aparecido el brujo o el dragon, y cambiamos 
	// de pantalla, reseteamos el contador, le damos más tiempo.
	//
	if (ii_brujo_dragon == E_SIN_BRUJO_DRAGON) 
    {
        ii_tiempo_brujo_dragon-=100;
        if (ii_tiempo_brujo_dragon<0) ii_tiempo_brujo_dragon=0;
    }
	
    return true;
}

void TESC_Juego::enterLeftScreen(void)
{
	if (enterOnScreen(scrInfo[io_Screen->getID()].left))	SprRedham->enterLeft();
	else SprRedham->position.x = 8;
}

void TESC_Juego::enterUpScreen(void)
{
	if (enterOnScreen(scrInfo[io_Screen->getID()].top))
	{
		SprRedham->enterUp();
		findRedhamPosition();
	}		
}

void TESC_Juego::enterRightScreen(void)
{		    
    if (enterOnScreen(scrInfo[io_Screen->getID()].right)) SprRedham->enterRight();
	else SprRedham->position.x -= 8;
}

void TESC_Juego::enterDownScreen(void)
{
	if (enterOnScreen(scrInfo[io_Screen->getID()].bottom)) SprRedham->enterDown();
	else SprRedham->restorePosition();
}

void TESC_Juego::drawScreen(TMABitmap& g)
{
	int i;
	
	// Dibujamos el fondo de la pantalla
	//
	g.draw(miGame->glaurungMap.getFastScreenBuffer(),0,0,false);

	// Dibujamos las animaciones de la pantalla por detrans
	//
	miGame->glaurungMap.drawScreenGraphOperations(g,io_Screen,TMAGraphOperation::OP_ANIM_NORMAL);
	
	// Aqui deberiamos dibujar los Sprites
	//
	SprRedham->draw(g);
	
	i=0;
	while (i<iv_Sprites.size())
	{
		PSpriteGlaurung spr = (PSpriteGlaurung)iv_Sprites.elementAt(i);
		if (!spr->isValid())
		{
			removeSprite(spr,false);
		}
		else
		{
			if (!ib_menu_mode) spr->animate();
			spr->draw(g);
			i++;
		}
	}

	// Dibujamos el Burladero si lo hay
	//
	if (SprBurladero->isValid()) SprBurladero->draw(g);
			
	// Dibujamos las animaciones de la pantalla por delante
	//
	miGame->glaurungMap.drawScreenGraphOperations(g,io_Screen,TMAGraphOperation::OP_ANIM_FRONT);

	// Por ultimo dibujamos los Graficos que estan por delante
	//
	miGame->glaurungMap.drawScreenGraphOperations(g,io_Screen,TMAGraphOperation::OP_FRONT);	
	
	if (!ib_menu_mode) 
	{
    	// Dibujamos los posibles Sprites Frontales
    	//
    	i=0;
    	while (i<iv_SpritesFront.size())
    	{
    		PSpriteGlaurung spr = (PSpriteGlaurung)iv_SpritesFront.elementAt(i);
    		spr->animate();
            if (!spr->draw(g)) removeSprite(spr,true); else i++;
    	}
    }
}

void TESC_Juego::drawGameInfo(TMABitmap& g)
{
	char txt[10];
    PSpriteTexto sprTxt;
	PMAImageBank bank = miGame->glaurungMap.getImageBank(1);
	
	g.drawRectFilled(0,0,640,40,0);

	// Dibujamos marcador de vidas
	//
	sprintf(txt,"%i",SprRedham->ii_vidas);
	miGame->fontBlue.drawText(g,txt,0,8,NULL);	
	g.draw(bank->getBitmap((miGame->gi_idioma == TGlaurungGame::LG_CHIQUITISTANI)?10:11),20,0,true);
	
	// Gema Roja
	if ((SprRedham->ii_gemas & 0x01) > 0) g.draw(bank->getBitmap(7),60,0,true);	
	// Gema Azul
	if ((SprRedham->ii_gemas & 0x02) > 0) g.draw(bank->getBitmap(8),110,0,true);	
	// Gema Verde
	if ((SprRedham->ii_gemas & 0x04) > 0) g.draw(bank->getBitmap(9),160,0,true);	
	
	// Las 2 llaves
	if (SprRedham->ii_llaves == 3) g.draw(bank->getBitmap(2),220,0,true);	
	// Llave Roja
	else if (SprRedham->ii_llaves == 1) g.draw(bank->getBitmap(0),220,0,true);	
	// Llave Azul
	else if (SprRedham->ii_llaves == 2) g.draw(bank->getBitmap(1),220,0,true);			
	
	// Poción Verde
	if (SprRedham->ib_pocion_verde) g.draw(bank->getBitmap(3),270,0,true);
	// Poción Amarilla		
	if (SprRedham->ib_pocion_amarilla) g.draw(bank->getBitmap(4),300,0,true);
	
	// Monedas de Oro
	sprintf(txt,"%02i",SprRedham->ii_monedas);
	miGame->fontBlue.drawText(g,txt,350,8,NULL);
	g.draw(bank->getBitmap(6),390,0,true);
	
	// Flechas
	sprintf(txt,"%02i",SprRedham->ii_flechas);
    miGame->fontBlue.drawText(g,txt,435,8,NULL);
	g.draw(bank->getBitmap(5),475,0,true);
	
	// Puntos
	//sprintf(txt,"%06i",SprRedham->il_puntos_tesoros);
	sprintf(txt,"%06i",io_Screen->getID());
    miGame->fontNumeric.drawText(g,txt,550,5,NULL);
	sprintf(txt,"%06i",SprRedham->il_puntos_flechas);
    miGame->fontNumeric.drawText(g,txt,550,20,NULL);
	
	if (!ib_menu_mode)
	{
    	// Caso que se solicite cambiar de objeto seleccionado.
    	//
		poll_joystick();
    	if (joy[0].button[GB_SEL].b && (!SprSeleccion->isMoving()))
    	{
    		joy[0].button[GB_SEL].b=0;
			switch (ii_seleccion)
    		{
    			case _Obj_Flechas:
    				ii_seleccion = _Obj_Oro;
    				SprSeleccion->moveTo(390,0);
    				break;
    				
    			case _Obj_Oro:					
    	            
    				if (SprRedham->ib_pocion_amarilla)
    	            {
    	                ii_seleccion = _Obj_Amarillo;
    	                SprSeleccion->moveTo(300,0);
    	            }
    	            else if (SprRedham->ib_pocion_verde)
    	            {
    	                ii_seleccion = _Obj_Verde;
    	                SprSeleccion->moveTo(270,0);
    	            }
    	            else
    	            {
    				    ii_seleccion = _Obj_Flechas;
    				    SprSeleccion->moveTo(475,0);
    	            }					
    				break;
    				
    			case _Obj_Amarillo:
    	        
    				if (!SprRedham->ib_pocion_verde)
    	            {
    	                ii_seleccion = _Obj_Flechas;
    				    SprSeleccion->moveTo(475,0);
    	            }
    	            else
    	            {
    	                ii_seleccion = _Obj_Verde;
    	                SprSeleccion->moveTo(270,0);
    	            }
    				break;
    				
    			case _Obj_Verde:
    				
    				ii_seleccion = _Obj_Flechas;
    	            SprSeleccion->moveTo(475,0);
    				break;
    		}
    	}
    	
    	// Caso que se utilice un objeto seleccionado.
    	//
		poll_joystick();
		
    	if (joy[0].button[GB_FIRE].b)
    	{
			joy[0].button[GB_FIRE].b=0;
    		switch (ii_seleccion)
    		{
    		
    			case _Obj_Flechas:
    				
    				SprRedham->shutArrow();
    				break;
    				
    			case _Obj_Oro:
    				
    				SprRedham->giveMoney();
    				break;
    				
    			case _Obj_Amarillo:
    				
    				SprRedham->setInvisible();
    				ii_seleccion = _Obj_Flechas;
    				SprSeleccion->moveTo(475,0);
    				sprTxt=new TSpriteTexto();
    				sprTxt->init(2,-1,140,&miGame->fontBlue,((PMAString)miGame->iv_Textos.elementAt(5))->text());
    				addSprite(sprTxt,true);
    				break;
    				
    			case _Obj_Verde:
    				
    				SprRedham->setInmunity();
    				ii_seleccion = _Obj_Flechas;
    				SprSeleccion->moveTo(475,0);
    				sprTxt=new TSpriteTexto();
    				sprTxt->init(2,-1,140,&miGame->fontBlue,((PMAString)miGame->iv_Textos.elementAt(6))->text());
    				addSprite(sprTxt,true);
    				break;
            }
    	}
    	SprSeleccion->animate();
    }
	
    SprSeleccion->draw(g);
}

void TESC_Juego::findRedhamPosition(void)
{
	int tx,ty;

	tx = miGame->glaurungMap.getScreenX() / miGame->glaurungMap.getGridAX();
	ty = miGame->glaurungMap.getScreenY() / miGame->glaurungMap.getGridAY();

	for (int px=0;px<tx;px++)
	for (int py=2;py<ty;py++) // Comienza desde coordenada 2, ya que antes no existe nada.
	{
		if (io_Screen->getMask(px,py)==6)
		{
            SprRedham->stopJump();
            SprRedham->putAt(
            		px*miGame->glaurungMap.getGridAX(),
            		py*miGame->glaurungMap.getGridAY() - SprRedham->position.height);
            SprRedham->savePosition();
            return;
		}
	}
	
	do
	{
		tx = SprRedham->getHotspotX();
		ty = SprRedham->getHotspotY();
		if (SprRedham->isDown(tx,ty-1)) SprRedham->position.y -= TSpriteGlaurung::_TileAY;
	} while (SprRedham->isDown(tx,ty-1));
	
	SprRedham->savePosition();
}


void TESC_Juego::findEnemyPosition(PSpriteGlaurung S)
{
	int tx,ty,orden;

	// Localizamos dentro de la pantalla activa, un lugar donde
	// pueda colocarse el enemigo.
	//
	tx = miGame->glaurungMap.getScreenX() / miGame->glaurungMap.getGridAX();
	ty = miGame->glaurungMap.getScreenY() / miGame->glaurungMap.getGridAY();

	while(true)
	{
        orden=0;
		for (int px=0;px<tx;px++)
		for (int py=0;py<ty;py++)
		{
			if (io_Screen->getMask(px,py)==5)
			{
				if ( iaEnemyPos[orden] && (TSpriteGlaurung::miRND.nextInt(20)>=10) )
				{
					iaEnemyPos[orden]=false;
					S->putAt(px*miGame->glaurungMap.getGridAX(),(py+1)*miGame->glaurungMap.getGridAY() - (S->position.height));
					return;
				}
				orden++;
                if (orden>=TScreenInfo::MAX_ENEMIGOS) orden=0;
			}
		}
	}
}


void TESC_Juego::findBurladero(void)
{
	int px,py,count=0;
	TMAVector& elem = io_Screen->getGraphicsOperationsForType(TMAGraphOperation::OP_FRONT);
	
	// Invalidamos el Burladero, hasta que se encuentre uno.
	//
	SprBurladero->invalidate();
	
    for (count=0;count<elem.size();count++)
    {
        // Si se encuentra el burladero, lo activamos.
        // Solo puede haber un burladero por pantalla.
        //
    	TMAGraphOperation& gop = *((PMAGraphOperation)elem.elementAt(count));
    	
        if (gop.getBankID()==2 && gop.getTileID()>=22 && gop.getTileID()<=25)
        {
        	// Calculamos la posición del Sprite Burladero.
        	//
            px = (gop.getPosX() * miGame->glaurungMap.getGridAX()) + miGame->glaurungMap.getGridAX();
            py = gop.getPosY() * miGame->glaurungMap.getGridAY() + (miGame->glaurungMap.getGridAY()*2);
            SprBurladero->putAt(px,py);
            SprBurladero->validate();
            return;
        }
    }
}

void TESC_Juego::putRedhamOutBurladero(void)
{
	int px,py,count=0;
	TMAVector& elem = io_Screen->getGraphicsOperationsForType(TMAGraphOperation::OP_FRONT);
		
    for (count=0;count<elem.size();count++)
    {
    	TMAGraphOperation& gop = *((PMAGraphOperation)elem.elementAt(count));
    	
        if (gop.getBankID()==2 && gop.getTileID()>=22 && gop.getTileID()<=25)
        {
        	// Calculamos la posición del Sprite Burladero.
        	//
            px = (gop.getPosX() * miGame->glaurungMap.getGridAX()) + miGame->glaurungMap.getGridAX();
            py = gop.getPosY() * miGame->glaurungMap.getGridAY() + (miGame->glaurungMap.getGridAY()*2);
            SprRedham->putAt(px-3*20,py+20);
            return;
        }
    }
}

void TESC_Juego::detectCollisions(void)
{
    int cpx,cpy;
	
	// Detecta colision del Personaje Principal con Tesoros, fuegos, etc
	//
	SprRedham->getCollisionFoot(cpx,cpy);

    if (!SprRedham->isInmune())
    {
	    if (cpx==_Collision_Muerte || cpy==_Collision_Muerte)
	    {
		    killRedham();
		    return;
	    }
    }

	if (cpy==_Collision_Burladero)
	{
        enterPasadizo();
        return;
	}
	
	if (cpy==_Collision_Cofre)
	{
        if ( scrInfo[io_Screen->getID()].cofre == TScreenInfo::COFRE_CERRADO ) 
        {
            openCofre(false);
            return;
        }
	}  
	
	// Detectamos colisiones con otros personajes.
	//
	int py = SprRedham->getHotspotY();
    
    if (py<22)
    {
        // Detecta colision del Personaje con otros Sprites
        //
    	for (int i=0;i<iv_Sprites.size();i++)
	    {
            TSpriteGlaurung& spr = *((PSpriteGlaurung)iv_Sprites.elementAt(i));

            // Determinamos si la flecha del protagonista ha tocado
            // a algun enemigo.
            // Solo podemos matar al Arquero, Lancero, Araña, Murcielago.
            //                
            if (SprRedham->sprFlecha->isValid())
            {
                if (spr.collisionsWith(*SprRedham->sprFlecha))
                {
                    if (spr.isInstanceOf(CLASS_ID(TSpriteFlecha))) spr.invalidate();
					else if (spr.isInstanceOf(CLASS_ID(TSpriteArquero)) ||
					         spr.isInstanceOf(CLASS_ID(TSpriteLancero)) ||
					         spr.isInstanceOf(CLASS_ID(TSpriteSpider)) ||
					         spr.isInstanceOf(CLASS_ID(TSpriteMurcielago)) )
                            {
                                SprRedham->addPoints(&spr);
                                spr.kill();
                                if (spr.getSprID()>=0 && spr.getSprID()<TScreenInfo::MAX_ENEMIGOS)
                                    scrInfo[io_Screen->getID()].enemigos[spr.getSprID()].vivo = false;
                            }
                    
                    SprRedham->sprFlecha->invalidate();
                }
            }
            
            // Determinamos si el enemigo colisiona con el Personaje
            //
            if (spr.isValid() && spr.collisionsWith(*SprRedham))
            {         
                // Si se trata de Magma, solo mata si esta caliente.
                //
                if (spr.isInstanceOf(CLASS_ID(TSpriteMagma)))
                {
                    if (((PSpriteMagma)(&spr))->isHot())
                    {
                        if (!SprRedham->isInmune()) killRedham();
                        return;
                    }
                }
                else
                {                          
                    // Obtenemos el HOTSPOT Y del Enemigo, para comprobar alturas.
                    //
                    int ey = spr.getHotspotY();
    
                    // Si estamos por encima del enemigo, en principio le podemos.
                    //
                    if (py<ey)
                    {
                        if (spr.isInstanceOf(CLASS_ID(TSpriteBrujoDragon)))
                        {
                            if (!SprRedham->isInmune()) killRedham();
                            return;
                        }
                        // Si es una flecha, nos mata y desaparece.
                        //    
                        else if (spr.isInstanceOf(CLASS_ID(TSpriteFlecha)))
                        {
                            if (!SprRedham->isInmune()) killRedham();
                            spr.invalidate();
                            return;
                        }
                        else
                        {                    
                            // En otro caso, matamos nosotros si estamos saltando.
                            //
                			SprRedham->addPoints(&spr);
                			spr.kill();
                			if (spr.getSprID()>=0 && spr.getSprID()<TScreenInfo::MAX_ENEMIGOS)
                			     scrInfo[io_Screen->getID()].enemigos[spr.getSprID()].vivo = false;
                        }
                    }
                    else
                    {
                        if (spr.isInstanceOf(CLASS_ID(TSpriteFlecha)))
                        {
                        	if (!SprRedham->isInmune()) killRedham();
                            spr.invalidate();
                            return;
                        }
                        else if (spr.isInstanceOf(CLASS_ID(TSpriteArquero)) ||
                                 spr.isInstanceOf(CLASS_ID(TSpriteSpider)) ||
                                 spr.isInstanceOf(CLASS_ID(TSpriteLancero)))
                             {
                       		    // Si los dos estamos saltando corto, no pasa nada.
                        		//
                        		if (SprRedham->isJumpingShort() && spr.isJumpingShort()) return;
    
    	                        // Si estamos saltando corto, y ellos no.. le podemos.
    	                        //
                            	if (SprRedham->isJumpingShort() && !spr.isJumping())
                        		{
    								SprRedham->addPoints(&spr);
    							  	spr.kill();
                                    if (spr.getSprID()>=0 && spr.getSprID()<TScreenInfo::MAX_ENEMIGOS)
                                        scrInfo[io_Screen->getID()].enemigos[spr.getSprID()].vivo = false;
    							  	return;
                        		}
                            	
                            	// En otro caso nos matan.
                            	//
                            	if (!SprRedham->isInmune()) killRedham();                        		
                            	return;
                            }
                        else
                        {
                            // En otro caso, nos matan.
                            //
                            if (!SprRedham->isInmune()) killRedham();
                            return;
                        }
                    }
                }
            }
	    }
    }                
}


void TESC_Juego::openCofre(bool solo_cambiar_imagen)
{
    int i=io_Screen->getID();

    if ( (scrInfo[i].cofre == TScreenInfo::COFRE_CERRADO && !solo_cambiar_imagen) || (scrInfo[i].cofre == TScreenInfo::COFRE_ABIERTO && solo_cambiar_imagen) )
    {
    	TMAVector& e = io_Screen->getGraphicsOperationsForType(TMAGraphOperation::OP_NORMAL);

        for (int count=0;count<e.size();count++)
        {
        	TMAGraphOperation& go = *((PMAGraphOperation)e.elementAt(count));
        	
            // Solo puede haber un cofre del tesoro por pantalla.
            //
            if (go.getBankID()==2 && go.getTileID()==20)
            {
                // Cambiamos el Tile, por el cofre abierto.
                //
                go.setTileID(21);
                
                // Redibujamos el fondo de la pantalla
                //
                miGame->glaurungMap.drawFastBuffer(io_Screen,0);

                if (!solo_cambiar_imagen)
                {
	                // Abrimos el cofre..
	                //
	                PSpriteAbreCofre cofre = new TSpriteAbreCofre(miGame->glaurungMap.getImageBank(0));
	                cofre->init(go.getPosX()*TSpriteGlaurung::_TileAX,go.getPosY()*TSpriteGlaurung::_TileAY,scrInfo[i].tipo_tesoro,SprRedham);
	                addSprite(cofre,true);
                }
                break;
            }
        }
        scrInfo[i].cofre=TScreenInfo::COFRE_ABIERTO;
    }
}

void TESC_Juego::addSprite(PSpriteGlaurung spr,bool front)
{
	if (front) 
	{
		iv_SpritesFront.addElement(spr);
	}
	else iv_Sprites.addElement(spr);
}


void TESC_Juego::removeSprite(PSpriteGlaurung spr,bool front)
{
    TMAVector& v = (front)?iv_SpritesFront:iv_Sprites;
    
    // Si se trata de un arquero, lo primero es eliminar la flecha.
    //
    if (spr->isInstanceOf(CLASS_ID(TSpriteArquero)))
    {
        PSpriteArquero a = (PSpriteArquero)spr;
        if (a->getFlecha()!=NULL) removeSprite(a->getFlecha(),front);
    }

    // Si se trata de una araña, lo primero es eliminar la flecha/fuego.
    //
    if (spr->isInstanceOf(CLASS_ID(TSpriteSpider)))
    {
        PSpriteSpider a = (PSpriteSpider)spr;
        if (a->getFlecha()!=NULL) removeSprite(a->getFlecha(),front);
    }

    // Si se trata del Brujo o Dragon la flecha/fuego.
    //
    if (spr->isInstanceOf(CLASS_ID(TSpriteBrujoDragon)))
    {
        PSpriteBrujoDragon a = (PSpriteBrujoDragon)spr;
        if (a->getFuego()!=NULL) removeSprite(a->getFuego(),front);
    }
    
    // Si se trata de una flecha, la eliminamos pero sin eliminar el objeto.
    //
    if (spr->isInstanceOf(CLASS_ID(TSpriteFlecha)))
    {
        v.removeElement(spr,false);
        return;
    }
    
    // En otro caso, se elimina el objeto.
    //
    v.removeElement(spr);
}

void TESC_Juego::setEnemyTarget(PSpriteGlaurung spr)
{
	int i;
	for (i=0;i<iv_Sprites.size();i++)
	{
		PSpriteGlaurung g = (PSpriteGlaurung)iv_Sprites.elementAt(i);
		g->setTarget(spr);
	}
	for (i=0;i<iv_SpritesFront.size();i++)
	{
		PSpriteGlaurung g = (PSpriteGlaurung)iv_SpritesFront.elementAt(i);
		g->setTarget(spr);
	}
}

void TESC_Juego::removeGarbage(bool front)
{    
    while (iv_Sprites.size()>0)
    {
        removeSprite((PSpriteGlaurung)iv_Sprites.elementAt(0),false);
    }

    if (front)
    {
        while (iv_SpritesFront.size()>0)
        {
            removeSprite((PSpriteGlaurung)iv_SpritesFront.elementAt(0),true);
        }
    }
    
    SprBrujoDragon = NULL;
}

void TESC_Juego::gotoMainMenu(void)
{
    desaparecerBrujoDragon();
    removeGarbage(true);
	miGame->setScene(new TESC_Menu_Principal());
}

void TESC_Juego::gotoEndGame(void)
{
    desaparecerBrujoDragon();
    removeGarbage(true);
	miGame->setScene(new TESC_Final());
}


void TESC_Juego::saveGame(int num)
{
    char filename[255];
    
    // Guardamos la imagen pequeña de la pantalla donde hemos guardado la partida
    //    
    sprintf(filename,"Data/Save/scr%i.png",num);
    PMABitmap bmp = TMABitmap::create(150,100,miGame->getScreenBufferDepth());
    PMABitmap bmp1 = TMABitmap::create(640,480,miGame->getScreenBufferDepth());
    
    drawScreen(*bmp1);    
    bmp->bilinearStretch(bmp1,0,40,640,440,0,0,150,100);
    bmp->saveToFile(filename);
    
    delete bmp;
    delete bmp1;
    
    // Ahora guardamos los datos de la partida
    //
    sprintf(filename,"Data/Save/sav%i",num);
    FILE *f = fopen(filename,"wb");
    if (!f) return;
    
    sprintf(filename,"%s      ",snap_name[num-1].text());
    fwrite(&filename[0],6,1,f);
    int scrid = io_Screen->getID();
    fwrite(&scrid,sizeof(scrid),1,f);
    TScreenInfo::writeToFile(f,scrInfo);
    SprRedham->writeToFile(f);
    fclose(f);
}

void TESC_Juego::loadGame(int num)
{
    char filename[255];
    
    // Ahora cargamos los datos de la partida
    //
    sprintf(filename,"Data/Save/sav%i",num);
    FILE *f = fopen(filename,"rb");
    if (!f) return;
    
    int scrid;
    fread(&filename[0],6,1,f);
    filename[6]=0;
    snap_name[num-1]=filename;
    fread(&scrid,sizeof(scrid),1,f);
    TScreenInfo::readFromFile(f,scrInfo);
    SprRedham->readFromFile(f);
    fclose(f);
    desaparecerBrujoDragon();
    enterOnScreen(scrid);
}

void TESC_Juego::loadSnap(void)
{
    char filename[255];
    
    // Cargamos los snap
    //
    for (int i=0;i<3;i++)
    {
        if (snap_bmp[i]) delete snap_bmp[i];
        snap_bmp[i]=NULL;
        snap_name[i]=((PMAString)miGame->iv_Textos.elementAt(17))->text();
        
        sprintf(filename,"Data/Save/sav%i",(i+1));
        FILE *f = fopen(filename,"rb");
        if (f)
        {
            fread(&filename[0],6,1,f);
            filename[6]=0;
            snap_name[i]=filename;
            snap_name[i]=snap_name[i].trim();
            fclose(f);
            sprintf(filename,"Data/Save/scr%i.png",(i+1));
            snap_bmp[i] = TMABitmap::loadFromFile(filename);
        }
    }
}

void TESC_Juego::aparecerBrujoDragon(void)
{
    bool brujo=false;
    PSpriteBrujoDragon spr=NULL;
    
    switch (ii_brujo_dragon)
    {
        case E_SIN_BRUJO_DRAGON:
            brujo = (TSpriteGlaurung::miRND.nextInt(50)<25);
            if (miGame->isSoundAvailable()) miGame->isnd_Moleston.play(true);
            if (brujo) ii_brujo_dragon = E_APARECIENDO_BRUJO;
            else ii_brujo_dragon = E_APARECIENDO_DRAGON;
            break;
            
        case E_CON_BRUJO:
            spr = new TSpriteBrujoDragon(miGame->glaurungMap.getImageBank(0),SprRedham,true);
            break;
            
        case E_CON_DRAGON:
            spr =new TSpriteBrujoDragon(miGame->glaurungMap.getImageBank(0),SprRedham,false);
            break;
    }
    
    if (spr!=NULL)
    {	
        if (miGame->isSoundAvailable()) miGame->isnd_ApareceBrujoDragon.play(false);
    	
        spr->position.y = SprRedham->position.y;
    	int px,py;
            	        
        if (SprRedham->position.x > 320) 
        {
            spr->position.x = 640 - spr->position.width;
            
            // Ajustamos X e Y
        	//
            px = spr->getHotspotX();
        	py = spr->getHotspotY(); 
    	    
    	    while (!spr->canWalkLeft(px,py))
    	    {
                spr->position.x--;
                px = spr->getHotspotX();
            	py = spr->getHotspotY(); 
            };
        }
    	else 
        {
            spr->position.x = 0;
            
            // Ajustamos X e Y
        	//
            px = spr->getHotspotX();
        	py = spr->getHotspotY(); 
    	    
    	    while (!spr->canWalkRight(px,py))
    	    {
                spr->position.x++;
                px = spr->getHotspotX();
            	py = spr->getHotspotY(); 
            };
        }    	
    	
    	addSprite(spr,false);
    	SprBrujoDragon = spr;
    }
}

void TESC_Juego::desaparecerBrujoDragon(void)
{
    ii_brujo_dragon = E_SIN_BRUJO_DRAGON;
    ii_tiempo_brujo_dragon = 0;

    // Paramos el sonido moleston
    //    
    if (miGame->isSoundAvailable() && miGame->isnd_Moleston.isPlaying()) 
    {
        miGame->isnd_Moleston.stop();
    }
    
    // Buscamos el Sprite del Brujo o Dragon, y lo invalidamos.
    //
    if (SprBrujoDragon!=NULL) 
    {
        SprBrujoDragon->kill();
        SprBrujoDragon = NULL;
    }
}

void TESC_Juego::killRedham(void)
{
    SprRedham->kill();
    desaparecerBrujoDragon();
}
	
#endif
