#ifndef _TSPRITEREDHAM_CPP_
#define _TSPRITEREDHAM_CPP_

#include "../main/glaurung.h"
#include "../escenas/escenarios.h"
#include "sprites.h"
#include "../gp2x/gp2x.h"


REGISTER_CLASS_ID(TSpriteRedham);

int TSpriteRedham::ia_Muerte[8]={82,83,84,85,86,87,88,89};
int TSpriteRedham::ia_AnimNormal[4]={0,0,0,0};
int TSpriteRedham::ia_AnimCerdo[4]={0,0,0,0};

TSpriteRedham::TSpriteRedham(PMAImageBank bank,PMAImageBank bdinero):TSpriteGlaurung(bank)
{    
    stopJump();
    ii_SaltoY=0;
    
    ii_vidas=9;ii_flechas=10;ii_monedas=10; 
    ii_gemas=0; ii_llaves = 0;
    il_puntos_flechas = 0;
    il_puntos_tesoros = 0;
    ib_pocion_verde = false;        // Poción de inmunidad
    ib_pocion_amarilla = false;     // Poción de invisibilidad
    ib_invisible=false;
    ib_inmune=false;
        
    sprFlecha = new TSpriteFlecha(bank);
    sprDinero = new TSpriteBolsaDinero(bdinero);
    sprTemporizador=new TSpriteTemporizador(NULL);
	    
    sprTemporizador->invalidate();
    sprDinero->invalidate();
    sprFlecha->invalidate();
    velocidad_andar=5;
    velocidad_saltar=5;
    velocidad_caer=10;	

    // Establecemos el Sprite en forma de Persona
    //
    setTransform(false);
    transformToChiquito(false);
}

TSpriteRedham::~TSpriteRedham()
{
    delete sprTemporizador;
    delete sprDinero;
    delete sprFlecha;
}

void TSpriteRedham::animate(void)
{
	switch (ii_EstadoAnim)
	{
	  case 0: // Animación Andando Normal.

		if (ii_RetardoPos<ii_Retardo)
		{
			ii_RetardoPos ++;
		}
		else
		{
			ii_Frame = (ii_Frame<ii_AnimSequenceLength-1)?(ii_Frame+1):0;
			ii_RetardoPos=0;
		}

		break;
	}

	TSpriteGlaurung::animate();
}

int *TSpriteRedham::getKillSequence(int& length)
{
    length=8;
    return ia_Muerte;
}

void TSpriteRedham::stopJump(void)
{
    ia_Salto = NULL;
    ii_Saltando=0;
    ib_andando_izq=false;
    ib_andando_der=false;
    ii_Retardo=2;
    ib_Salto = false;
}

void TSpriteRedham::setTransform(bool cerdo)
{
	if (!cerdo)
	{
		ia_AnimSequence = ia_AnimNormal;
		if (ib_cerdo) 
        {
            position.y -= _TileAY;
            rect_MemPos.y -= _TileAY;
        }

		// Establecemos el ancho/alto del sprite
		//
		position.width = 40;
		position.height = 80;
        rect_MemPos.width = 40;
        rect_MemPos.height = 80;

		// Indicamos cuantos cuadrados ocupa el Sprite
		ii_tilesy=3; ii_tilesx=2;
	}
	else
	{
		// Si estamos muriendo, no podemos transformarnos en cerdito.
		//
		if (ib_muriendo) return;
		
		ia_AnimSequence = ia_AnimCerdo;
		if (!ib_cerdo) 
        {
            position.y += _TileAY;
            rect_MemPos.y += _TileAY;
        }

		// Establecemos el ancho/alto del sprite
		//
		position.width = 40;
		position.height = 60;
        rect_MemPos.width = 40;
        rect_MemPos.height = 60;

		// Indicamos cuantos cuadrados ocupa el Sprite
		ii_tilesy=3; ii_tilesx=2;
	}

    ib_cerdo = cerdo;
	ii_Frame=0;
	ii_AnimSequenceLength=4;
	animate();
}

void TSpriteRedham::transformToChiquito(bool pchiquito)
{
	int valor;

	valor=(pchiquito)?4:0;

	ia_AnimNormal[0]=1+valor; 
	ia_AnimNormal[1]=2+valor;
	ia_AnimNormal[2]=3+valor;
	ia_AnimNormal[3]=4+valor;

	ia_AnimCerdo[0]=13+valor;
	ia_AnimCerdo[1]=14+valor;
	ia_AnimCerdo[2]=15+valor;
	ia_AnimCerdo[3]=16+valor;

    ii_CurrentFotograma = ia_AnimSequence[0];
    ii_Frame=0;
}

bool TSpriteRedham::draw(TMABitmap& g)
{
	// Si han matado al personaje, salimos..
	//
	if (ib_muriendo) 
	{
		TSpriteGlaurung::draw(g);
		kill();
		return true;
	}
	
	// Dibujamos el Personaje segun se encuentre..
	//
    if (ib_invisible)
    {
        g.drawSpriteAlpha(io_images->getBitmap(ii_CurrentFotograma),position.x,position.y,ib_flip_x,ib_flip_y,180);
    }
    else if (ib_inmune)
    {
        g.drawSpriteColorized(io_images->getBitmap(ii_CurrentFotograma),position.x,position.y,ib_flip_x,ib_flip_y,0,255,150);
	}
    else
    {
        TSpriteGlaurung::draw(g);
    }
	
	// Si la flecha esta lanzada, la dibujamos.
    //
	if (sprFlecha->isValid()) sprFlecha->draw(g);

	
    // Si hay bolsa de dinero, la dibujamos.
    //
    if (sprDinero->isValid())
    {
        sprDinero->animate();
        
        // Si se acaba el tiempo de la bolsa de dinero.
        //
        if (!sprDinero->draw(g)) 
        {
            // Si aun tenemos pocima de invisibilidad, no nos pueden ver
            //
            if (sprTemporizador->isValid() && sprTemporizador->getID()==1)
            {
                setEnemyTarget(NULL);
            }
            else
            { 
                // En otro caso, volvemos a ser el objetivo.
                //        
                setEnemyTarget(this);
            }
        }
    }

    // Si hay temporizador por haber usnado una pocima, la dibujamos.
    //
    if (sprTemporizador->isValid())
    {
        if (!sprTemporizador->draw(g))
        {
            switch (sprTemporizador->getID())
            {
            	case 1:     // Se acabo la poción amarilla.
	                ib_invisible=false;
	                setEnemyTarget(this);
	                break;                

	            case 2:     // Se acabo la poción verde.
	                ib_inmune=false;
	                break;
            }
        }
    }
	return true;
}

bool TSpriteRedham::isEnterUp(void)
{		
	bool lb_goup = canGoUp();
	
    if (ib_cerdo)
    {
        return (lb_goup && (position.y - _TileAY < 10));
    }
    return (lb_goup && (position.y < 10));
}

bool TSpriteRedham::canGoUp(void)
{
	int px = getHotspotX();
	int py = getHotspotY();
	
	for (int i=0;i<ii_tilesx;i++)
	{
        if (py-ii_tilesy>=0)
        {
		    if (io_Screen->getMask(px+i,py-ii_tilesy) == 6) return true;
        }
	}
	return false;
}

void TSpriteRedham::enterLeft(void)
{
    sprDinero->invalidate();
    sprFlecha->invalidate();
    position.x = 628 - position.width ;
    savePosition();
}

void TSpriteRedham::enterRight(void)
{
    sprDinero->invalidate();
	sprFlecha->invalidate();
	position.x = 20;
	savePosition();
}

void TSpriteRedham::enterUp(void)
{	
    sprDinero->invalidate();
	sprFlecha->invalidate();
	position.y = 478 - position.height;
	if (ia_Salto!=NULL) ii_SaltoY = position.y + (ii_SaltoY - 20);
	savePosition();
}

void TSpriteRedham::enterDown(void)
{
    sprDinero->invalidate();
	sprFlecha->invalidate();
    if (ib_cerdo)
    {
        position.y = 10+_TileAY;
    }
    else
    {
	    position.y = 10;
    }
	if (ia_Salto!=NULL) ii_SaltoY = position.y  + ia_Salto[ii_Saltando];
	savePosition();
}

bool TSpriteRedham::kill(void)
{
	if (!ib_muriendo)
	{
		if (ib_cerdo) position.y -= _TileAY;
		sprTemporizador->invalidate();
        sprFlecha->invalidate();
        ib_invisible=false;
        ib_inmune=false;
		ii_Frame=0;
		ib_muriendo = true;
		ii_Retardo=3;
		ia_AnimSequence = getKillSequence(ii_AnimSequenceLength);
		ib_flip_x = false;
		animate();
		miGame->isnd_Muerte.play(false);
	}
	else
	{
		if ((ii_Frame+1)==ii_AnimSequenceLength)
		{
            restorePosition();
            setTransform(false);
			ib_muriendo = false;
			ib_andando_izq = false;
			ib_andando_der = false;
			ia_Salto = NULL;
			ii_Saltando=0;
			ii_Retardo=2;
			ii_vidas --;
            savePosition();
            sprDinero->invalidate();
            TESC_Juego* g = (TESC_Juego*)miGame->getScene();				
			g->enterOnScreen(io_Screen->getID());
            return false;
		}
	}
	animate();
	return true;
}

bool TSpriteRedham::evalMaskRight(int mask)
{
	switch (mask)
	{
		case 1: // Muro
			
			return false;
			
		case 3: // Burladero
			
			if (ispr_Burladero!=NULL && ispr_Burladero->isValid())
		    {
				return ispr_Burladero->isOpen();
		    }
			return false;
			
		case 7: // Puerta	
			
			// Si tiene la llave roja y esta en la pantalla 43, se puede pasar.
			//
			if ((ii_llaves & 0x01)>0 && (ii_gemas == 0x07) && io_Screen->getID()==43) return true;
			// Si tiene la llave azul y esta en la pantalla 74, se puede pasar.
			//
			if ((ii_llaves & 0x02)>0 && io_Screen->getID()==74) return true;
			return false;		
	}
	if (mask == 1) return false;
	
	return true;
}

void TSpriteRedham::move(void)
{
	int px,py;
	
    // Si la flecha esta lanzada, la animamos.
    //
	if (sprFlecha->isValid()) sprFlecha->animate();

	if (ib_muriendo) return;

    px = getHotspotX();
    py = getHotspotY();

	if ( (ia_Salto==NULL) || 
		 ((ia_Salto==ia_SaltoLargo || ia_Salto==ia_SaltoRecto) && (ii_Saltando >= 120)) ||
		 ((ia_Salto==ia_SaltoCorto) && (ii_Saltando >= 220)) )
		 
	{
		// Determinamos si hay algo bajo nuestro personaje
		//
		if ( isDown(px,py) )
		{
			// Corregimos la posición del Sprite, para que quede sobre el suelo.
			//
			position.y = ((py + 1)* _TileAY) - position.height;
			if (ia_Salto!=NULL)
			{
                // Esta corrección evita que cuando termine el salto
                // el personaje se quede incrustado en una baldosa.
                //
                if (io_Screen->getMask(px,py)==1) 
                {
                    position.x = (px*_TileAX)+10;
                }
                if (io_Screen->getMask(px+ii_tilesx-1,py)==1) 
                {
                    position.x = (px*_TileAX)-20;
                }
                
				stopJump();			
			}
		}
		else
		{
			// Como el personaje esta sobre el aire, hacemos que caiga
			// y no atendemos ningun otro control sobre el.
			//
			if (ia_Salto==NULL) 
			{
				position.y += velocidad_caer;
				return;
			}
		}
	}

	if (ia_Salto==NULL)
	{	
		// Determinamos si se han pulsado las teclas de salto
		//
		poll_joystick();
		if ((ia_Salto==NULL) && (joy[0].button[GB_JUMP1].b)) // Salto Largo (Arriba)
		{
			ii_Saltando=0;
			ii_SaltoY = position.y;
			poll_joystick();
			if (joy[0].stick[0].axis[0].d1) ib_andando_izq=1;
			if (joy[0].stick[0].axis[0].d2) ib_andando_der=1;
            if (!(ib_andando_izq || ib_andando_der))
            {
                ia_Salto = ia_SaltoRecto;
            }
            else
            {
                ia_Salto = ia_SaltoLargo;
            }
            ib_Salto = true;
		}
		else if ((ia_Salto==NULL) && (joy[0].button[GB_JUMP2].b)) // Salto Corto (Abajo)
		{
			ii_Saltando=0;
			ia_Salto = ia_SaltoCorto;
			ii_SaltoY = position.y;
			ib_andando_izq = ib_flip_x;
			ib_andando_der = !ib_flip_x;
			ii_Retardo=1;
			ib_Salto = true;
		}
	}
	else
	{
		// Determinamos si hay algo sobre nuestro personaje
		//
		if ( isTop(px,py) ) 
		{
            stopJump();
		}
		else
		{
			position.y = ii_SaltoY - ia_Salto[ii_Saltando];
			if (ii_Saltando+velocidad_saltar<240) ii_Saltando += velocidad_saltar;
			else 
			{
                stopJump();
			}
		}
	}

	// Intentando Caminar hacia la izquierda
	//
	poll_joystick();
	if (((joy[0].stick[0].axis[0].d1) && (ia_Salto==NULL)) || ib_andando_izq)
	{		
		// Determinamos si el personaje puede andar hacia la izquierda
		//
		if (canWalkLeft(px,py))
		{
			animate();
			
            // Con el siguiente IF, hacemos que no ande justo al cambiar de sentido.
            //
			if (ib_flip_x) position.x -= velocidad_andar;
            ib_flip_x=true;

            if (miGame->isSoundAvailable())
            {
    			if (ia_Salto==NULL) 
                    { if (!miGame->isnd_Paso.isPlaying()) miGame->isnd_Paso.play(false); }
    			else 
                    { if (!miGame->isnd_Carrera.isPlaying()) miGame->isnd_Carrera.play(false); }
            }
		}
		else
		{
            ib_flip_x=true;
			stopJump();
		}
	}
	
	// Intentando Caminar hacia la derecha
	//
	else if (((joy[0].stick[0].axis[0].d2) && (ia_Salto==NULL)) || ib_andando_der)
	{	
				
		// Determinamos si el personaje puede andar hacia la derecha
		//
		if (canWalkRight(px,py))
		{
			animate();

            // Con el siguiente IF, hacemos que no ande justo al cambiar de sentido.
            //
			if (!ib_flip_x) position.x += velocidad_andar;
            ib_flip_x = false;

            if (miGame->isSoundAvailable())
            {
    			if (ia_Salto==NULL) 
                    { if (!miGame->isnd_Paso.isPlaying()) miGame->isnd_Paso.play(false); }
    			else 
                    { if (!miGame->isnd_Carrera.isPlaying()) miGame->isnd_Carrera.play(false); }
            }
		}
		else
		{
            ib_flip_x=false;
			stopJump();
		}
	}
}

void TSpriteRedham::shutArrow(void)
{
	int px,py,off;
	
	px = getHotspotX();
    py = getHotspotY();
    
    if (!isDown(px,py)) return;
    
	if (!ib_cerdo && ii_flechas>0 && !sprFlecha->isValid() )
	{
		ii_flechas --;
        off = (ib_flip_x)?30:-40;
		sprFlecha->init(position.x+off,position.y + 30,ib_flip_x,20);
	}
}

void TSpriteRedham::giveMoney(void)
{
	int px,py;
	if (!ib_cerdo && ii_monedas>0 && !sprDinero->isValid())
    {
        // Para soltar dinero, tenemos que estar sobre suelo.
        //
        px = getHotspotX();
        py = getHotspotY();
        if (isDown(px,py))
        {
            ii_monedas--;
            sprDinero->init(20,position.x,(position.y + position.height - sprDinero->position.height),&miGame->fontNumeric);
            miGame->isnd_SoltarDinero.play(false);
	        setEnemyTarget(sprDinero);
	    }
	}
}

void TSpriteRedham::setInvisible(void)
{
    ib_invisible=true;
    ib_inmune=false;
    ib_pocion_amarilla=false;

    // Hacemos que los enemigos no nos vean.
    //
    setEnemyTarget(NULL);

    // Iniciamos el Temporizador.
    //
    sprTemporizador->init(this,90,&miGame->fontNumeric,1);
}

void TSpriteRedham::setInmunity(void)
{
    ib_invisible=false;
    ib_inmune=true;
    ib_pocion_verde=false;

    // Hacemos que los enemigos no nos vean.
    //
    setEnemyTarget(NULL);

    // Iniciamos el Temporizador.
    //
    sprTemporizador->init(this,90,&miGame->fontNumeric,2);
}

void TSpriteRedham::setEnemyTarget(PSpriteGlaurung target)
{
    
	TESC_Juego *j = (TESC_Juego*)miGame->getScene();
	if (j!=NULL) j->setEnemyTarget(target);
}

void TSpriteRedham::getCollisionFoot(int& px,int& py)
{
	int px1;

	py = (position.y + position.height - 16)/ _TileAY;
	px = (position.x + 8) / _TileAX ;
	px1 =(position.x + position.width - 16)/ _TileAX ;

	px = io_Screen->getMask(px,py);
	py = io_Screen->getMask(px1,py);
}

void TSpriteRedham::addPoints(PSpriteGlaurung spr)
{
    if (spr->isInstanceOf(CLASS_ID(TSpriteArquero)))          il_puntos_flechas+=800;
    else if (spr->isInstanceOf(CLASS_ID(TSpriteLancero)))     il_puntos_flechas+=1600;
    else if (spr->isInstanceOf(CLASS_ID(TSpriteCaballero)))   il_puntos_flechas+=2400;
    else if (spr->isInstanceOf(CLASS_ID(TSpriteMurcielago)))  il_puntos_flechas+=1600;
    else if (spr->isInstanceOf(CLASS_ID(TSpriteSpider)))     il_puntos_flechas+=1600;
}

bool TSpriteRedham::walkPasadizo(void)
{
	int px,py;
   
    animate();
    position.x += velocidad_andar-2;
    if (miGame->isSoundAvailable())
    { 
        if (!miGame->isnd_Paso.isPlaying()) miGame->isnd_Paso.play(false,50);
    }
    
	px = getHotspotX();
    py = getHotspotY();
    return canWalkRight(px,py);
}

void TSpriteRedham::writeToFile(FILE* f)
{
    fwrite(&ib_invisible,sizeof(ib_invisible),1,f);
    fwrite(&ib_inmune,sizeof(ib_inmune),1,f);
    fwrite(&ib_cerdo,sizeof(ib_cerdo),1,f);
    fwrite(&ib_andando_izq,sizeof(ib_andando_izq),1,f);
    fwrite(&ib_andando_der,sizeof(ib_andando_der),1,f);
    fwrite(&ii_gemas,sizeof(ii_gemas),1,f);
    fwrite(&ii_llaves,sizeof(ii_llaves),1,f);
    fwrite(&ii_flechas,sizeof(ii_flechas),1,f);
    fwrite(&ii_monedas,sizeof(ii_monedas),1,f);
    fwrite(&ii_vidas,sizeof(ii_vidas),1,f);
    fwrite(&il_puntos_flechas,sizeof(il_puntos_flechas),1,f);
    fwrite(&il_puntos_tesoros,sizeof(il_puntos_tesoros),1,f);
    fwrite(&ib_pocion_verde,sizeof(ib_pocion_verde),1,f);
    fwrite(&ib_pocion_amarilla,sizeof(ib_pocion_amarilla),1,f);
    fwrite(&rect_MemPos,sizeof(rect_MemPos),1,f);
    fwrite(&MemPos_flipx,sizeof(MemPos_flipx),1,f);
    fwrite(&MemPos_flipy,sizeof(MemPos_flipy),1,f);
    fwrite(&ib_muriendo,sizeof(ib_muriendo),1,f);
    fwrite(&ib_valido,sizeof(ib_valido),1,f);
    fwrite(&ib_flip_x,sizeof(ib_flip_x),1,f);
    fwrite(&ib_flip_y,sizeof(ib_flip_y),1,f);         
    fwrite(&position,sizeof(position),1,f);         
    fwrite(&ii_tilesy,sizeof(ii_tilesy),1,f);
    fwrite(&ii_tilesx,sizeof(ii_tilesx),1,f);
    
    sprTemporizador->writeToFile(f);
    sprDinero->writeToFile(f);
}

void TSpriteRedham::readFromFile(FILE* f)
{
    fread(&ib_invisible,sizeof(ib_invisible),1,f);
    fread(&ib_inmune,sizeof(ib_inmune),1,f);
    fread(&ib_cerdo,sizeof(ib_cerdo),1,f);
    fread(&ib_andando_izq,sizeof(ib_andando_izq),1,f);
    fread(&ib_andando_der,sizeof(ib_andando_der),1,f);
    fread(&ii_gemas,sizeof(ii_gemas),1,f);
    fread(&ii_llaves,sizeof(ii_llaves),1,f);
    fread(&ii_flechas,sizeof(ii_flechas),1,f);
    fread(&ii_monedas,sizeof(ii_monedas),1,f);
    fread(&ii_vidas,sizeof(ii_vidas),1,f);
    fread(&il_puntos_flechas,sizeof(il_puntos_flechas),1,f);
    fread(&il_puntos_tesoros,sizeof(il_puntos_tesoros),1,f);
    fread(&ib_pocion_verde,sizeof(ib_pocion_verde),1,f);
    fread(&ib_pocion_amarilla,sizeof(ib_pocion_amarilla),1,f);
    fread(&rect_MemPos,sizeof(rect_MemPos),1,f);
    fread(&MemPos_flipx,sizeof(MemPos_flipx),1,f);
    fread(&MemPos_flipy,sizeof(MemPos_flipy),1,f);
    fread(&ib_muriendo,sizeof(ib_muriendo),1,f);
    fread(&ib_valido,sizeof(ib_valido),1,f);
    fread(&ib_flip_x,sizeof(ib_flip_x),1,f);
    fread(&ib_flip_y,sizeof(ib_flip_y),1,f);         
    fread(&position,sizeof(position),1,f);         
    fread(&ii_tilesy,sizeof(ii_tilesy),1,f);
    fread(&ii_tilesx,sizeof(ii_tilesx),1,f);
    
    if (ib_cerdo) ia_AnimSequence = ia_AnimCerdo;
      
    sprTemporizador->readFromFile(f);
    if (sprTemporizador->isValid()) 
    {
        sprTemporizador->restore(this,&miGame->fontNumeric);
        if (sprTemporizador->getID()==1) setEnemyTarget(NULL);
    }
    
    sprDinero->readFromFile(f);
    if (sprDinero->isValid())
    {
        setEnemyTarget(sprDinero);
        sprDinero->restore(sprDinero,&miGame->fontNumeric);
    }
    
    stopJump();
    restorePosition();
    
    ii_CurrentFotograma = ia_AnimSequence[0];
    ii_Frame=0;
}

#endif
