#ifndef _SPRITES_H_
#define _SPRITES_H_

#include "../ma_allegro/ma_allegro.h"
#include "../ma_allegro/maps/mapas.h"

// -------------- Prototipos
//
class TESC_Seleccion_Idioma;
class TESC_Juego;
class TGlaurungGame;

class TSpriteSeleccion;
class TSpriteGlaurung;
class TSpriteBurladero;
class TSpriteFlecha;
class TSpriteArquero;
class TSpriteSpider;
class TSpriteLancero;
class TSpriteCaballero;
class TSpriteMurcielago;
class TSpriteMagma;
class TSpriteRedham;
class TSpriteAbreCofre;
class TSpriteTemporizador;
class TSpriteTexto;
class TSpriteBolsaDinero;
class TSpriteBrujoDragon;

typedef TSpriteSeleccion*       PSpriteSeleccion;
typedef TSpriteGlaurung*        PSpriteGlaurung;
typedef TSpriteBurladero*       PSpriteBurladero;
typedef TSpriteFlecha*          PSpriteFlecha;
typedef TSpriteArquero*         PSpriteArquero;
typedef TSpriteSpider*          PSpriteSpider;
typedef TSpriteLancero*         PSpriteLancero;
typedef TSpriteCaballero*       PSpriteCaballero;
typedef TSpriteMurcielago*      PSpriteMurcielago;
typedef TSpriteMagma*           PSpriteMagma;
typedef TSpriteRedham*          PSpriteRedham;
typedef TSpriteAbreCofre*       PSpriteAbreCofre;
typedef TSpriteTemporizador*    PSpriteTemporizador;
typedef TSpriteTexto*           PSpriteTexto;
typedef TSpriteBolsaDinero*     PSpriteBolsaDinero;
typedef TSpriteBrujoDragon*     PSpriteBrujoDragon;

// -------------- TSpriteSeleccion
//
class TSpriteSeleccion : public TMASprite 
{
    REGISTER_CLASS protected:

    	static const int ia_anim_idioma[2];
    	static const int ia_anim_game[2];
    	
        TMARectangle ir_destino;
        TESC_Seleccion_Idioma *notify;
    	bool ib_moviendo;
    	int ii_vel;
	
	public:
        PUBLIC_CLASS_ID;
        
        int gi_idioma;
        
        TSpriteSeleccion(PMAImageBank,bool idioma,TESC_Seleccion_Idioma* esc=NULL);
        void moveTo(int x,int y);
        void animate(void);
        bool isMoving(void) { return ib_moviendo; }	
};

// -------------- TSpriteGlaurung
//
class TSpriteGlaurung : public TMASprite 
{
    REGISTER_CLASS protected:
    
        friend class TESC_Juego;
    
        static const int _RadioSaltoLargo = 180;
    	static const int _RadioSaltoCorto = 10;
    	static const int _TileAX = 20;
    	static const int _TileAY = 20;

    	static int ia_SaltoLargo[240];
    	static int ia_SaltoCorto[240];
    	static int ia_SaltoRecto[240];
    	static int ia_AnimMuerte[8];
    	static PMAScreenMap io_Screen;
    	static TGlaurungGame *miGame;
        
        static void makeJumpArray(void);
        static PSpriteBurladero ispr_Burladero;

        TMARectangle rect_MemPos;
        bool MemPos_flipx,MemPos_flipy;
        int *ia_Salto;
        int ii_Salto,ii_SaltoVel;
        bool ib_Salto;
        int ii_SaltoPX,ii_SaltoPY;
        bool ib_muriendo;
        PSpriteGlaurung io_Target;
        
        int ii_tilesx,ii_tilesy;
        int spr_id;
    
    public:
        
        PUBLIC_CLASS_ID;
        static TMARandom miRND;
    	
        TSpriteGlaurung(PMAImageBank);    
    
        static void initialize(void);
        
        // Establece la referencia a la pantalla actual
        // para todos los sprites
        //
        static void setScreen(PMAScreenMap scr) { io_Screen = scr; }
    
        // Obtiene puntos de comprobación
        //
        virtual int getHotspotX(void)=0L;
        virtual int getHotspotY(void)=0L;
        
        void setSprID(int id) { spr_id = id; }
        int  getSprID(void) { return spr_id; }
        
        // Comprobar si esta saltando.
        //
        bool isJumpingShort() { return (ib_Salto && (ia_Salto == ia_SaltoCorto)); }
        bool isJumpingLong()  { return (ib_Salto && (ia_Salto == ia_SaltoLargo)); }
        bool isJumping()      { return ib_Salto; }

        void setTarget(PSpriteGlaurung spr) { io_Target = spr; }
        int  getDistance(TSpriteGlaurung& spr);
        void savePosition(void);
        void restorePosition(void);
    
        // --------------------- Comprobaciones para poder moverse
        
        virtual bool evalMaskRight(int mask);
        bool isTop(int px,int py);
        bool isDown(int px,int py);
        bool canWalkRight(int px,int py);
        bool canWalkLeft(int px,int py);
        bool canFallDown(int px,int py);
        bool canJumpLeft(int px,int py,int vel,int *arco,bool completo);
        bool canJumpSmallLeft(int px,int py,int vel);
        bool canJumpBigLeft(int px,int py,int vel);
        bool canJumpRight(int px,int py,int vel,int *arco,bool completo);
        bool canJumpSmallRight(int px,int py,int vel);
        bool canJumpBigRight(int px,int py,int vel);

        // --------------------- Realización de Salto

        void jumpRight(int vel,bool salto_bajo);
        void jumpLeft(int vel,bool salto_bajo);
        void jump(void);
        
        // ---------------------- Otros métodos
        
        static void setBurladero(PSpriteBurladero b) { ispr_Burladero=b; }
        virtual int *getKillSequence(int& length);
        bool kill(void);

        // ---------------------- Colisiones

        virtual bool collisionsWith(TSpriteGlaurung& spr);
        
};

// -------------- TSpriteBurladero
//
class TSpriteBurladero : public TSpriteGlaurung
{
    REGISTER_CLASS protected:
        
        static int ia_anim[15];
    
    public:
        PUBLIC_CLASS_ID;
        TSpriteBurladero(PMAImageBank);
        
        void animate(void);
        void open(void);
        
        bool isOpen(void) { return (ii_Frame==7); }        
        int getHotspotX() { return 0; }
        int getHotspotY() { return 0; }
        bool collisionsWith(TSpriteGlaurung& spr) { return false; }        
};

// -------------- TSpriteFlecha
//

#define TFLECHA 0
#define TSPIDER 1
#define TDRAGON 2
#define TBRUJO  3

class TSpriteFlecha : public TSpriteGlaurung
{
    REGISTER_CLASS protected:
    
    	static const int FLECHA_AX = 60;
    	static const int FLECHA_AY = 18;
    	static int ia_anim_flecha[3];
        static int ia_anim_fuego[3];
        static int ia_anim_dragon[8];
        static int ia_anim_brujo[10];
        
        int ii_velocidad;
        
    public:
        
        PUBLIC_CLASS_ID;
    
        TSpriteFlecha(PMAImageBank,int tipo=TFLECHA);
        void init(int x,int y,bool flip,int vel);
        bool draw(TMABitmap&);
        void animate(void);
        int getHotspotX(void);
        int getHotspotY(void);
        bool isCollisioningWith(TMASprite& s);
};

// -------------- TSpriteArquero
//
class TSpriteArquero : public TSpriteGlaurung
{
    REGISTER_CLASS protected:
    
        static const int _ARQUERO_ANDANDO = 2;
        static const int _ARQUERO_PERSIGUIENDO = 4;
        static const int _ARQUERO_AX = 80;
        static const int _ARQUERO_AY = 80;
    	static int ia_anim[4];
    	
        bool ib_menu;
        int ii_distance_detect;
        int il_ciclos;
        PSpriteFlecha io_flecha;
        
        void walk(void);
        void follow(void);
    
    public:        
        PUBLIC_CLASS_ID;        
        TSpriteArquero(PMAImageBank,PMAImageBank bflecha,bool menu=false);
        ~TSpriteArquero();
        
        PSpriteFlecha getFlecha(void) { return io_flecha; }
        
        void animate(void);
        int getHotspotX(void);
        int getHotspotY(void);
};

// -------------- TSpriteSpider
//
class TSpriteSpider : public TSpriteGlaurung
{
    REGISTER_CLASS protected:
    
        static const int _SPIDER_ANDANDO = 2;
        static const int _SPIDER_PERSIGUIENDO = 4;
        static const int _SPIDER_AX = 80;
        static const int _SPIDER_AY = 60;
    	static int ia_anim0[4];
    	static int ia_anim1[4];
    	
        int ii_distance_detect;
        int il_ciclos;
        PSpriteFlecha io_flecha;
        
        void walk(void);
        void follow(void);
    
    public:        
        PUBLIC_CLASS_ID;        
        TSpriteSpider(PMAImageBank,PMAImageBank bflecha);
        ~TSpriteSpider();
        
        PSpriteFlecha getFlecha(void) { return io_flecha; }
        
        void animate(void);
        int getHotspotX(void);
        int getHotspotY(void);
};

// -------------- TSpriteLancero
//
class TSpriteLancero : public TSpriteGlaurung
{
    REGISTER_CLASS protected:
    
        static const int _LANCERO_ANDANDO = 2;
        static const int _LANCERO_PERSIGUIENDO = 4;
        static const int _LANCERO_AX = 80;
        static const int _LANCERO_AY = 80;
    	static int ia_anim[4];
    	
        int ii_distance_detect;
        int il_ciclos;
        
        void walk(void);
        void follow(void);
    
    public:        
        PUBLIC_CLASS_ID;        
        TSpriteLancero(PMAImageBank);
        
        void animate(void);
        int getHotspotX(void);
        int getHotspotY(void);
};

// -------------- TSpriteCaballero
//
class TSpriteCaballero : public TSpriteGlaurung
{
    REGISTER_CLASS protected:
    
        static const int _CABALLERO_ANDANDO = 2;
        static const int _CABALLERO_PERSIGUIENDO = 4;
        static const int _CABALLERO_AX = 80;
        static const int _CABALLERO_AY = 80;
    	static int ia_anim[4];
    	
        int ii_distance_detect;
        int il_ciclos;
        
        void walk(void);
        void follow(void);
    
    public:        
        PUBLIC_CLASS_ID;        
        TSpriteCaballero(PMAImageBank);
        
        void animate(void);
        int getHotspotX(void);
        int getHotspotY(void);
};

// -------------- TSpriteMurcielago
//
class TSpriteMurcielago : public TSpriteGlaurung
{
    REGISTER_CLASS protected:
    
        static int ia_anim0[6];
        static int ia_anim1[6];
        
        static const int _MURCIELAGO_AX = 80;
        static const int _MURCIELAGO_AY = 40;
        
        int ii_vx,ii_vy;
	            
    public:        
        PUBLIC_CLASS_ID;        
        TSpriteMurcielago(PMAImageBank,int tipo);
        
        void animate(void);
        int getHotspotX(void);
        int getHotspotY(void);
};

// -------------- TSpriteSeleccion
//
class TSpriteMagma : public TSpriteGlaurung
{
    REGISTER_CLASS protected:

    	static const int ia_anim[5];
   	
	public:
        PUBLIC_CLASS_ID;
             
        TSpriteMagma(PMAImageBank);
        void animate(void);
        bool draw(TMABitmap& g);
        bool isHot(void);
        
        int getHotspotX(void) { return 0; }
        int getHotspotY(void) { return 0; }
};


// -------------- TSpriteRedham
//
class TSpriteRedham : public TSpriteGlaurung
{
    REGISTER_CLASS protected:
    
        friend class TESC_Juego;
    
        static int ia_Muerte[8];
        static int ia_AnimNormal[4];
        static int ia_AnimCerdo[4];

        bool ib_invisible,ib_inmune,ib_cerdo;
        bool ib_andando_izq,ib_andando_der;
        
        int ii_Saltando,ii_SaltoY;
        int velocidad_andar,velocidad_saltar,velocidad_caer;
        
        PSpriteFlecha sprFlecha;
        PSpriteBolsaDinero sprDinero;
        PSpriteTemporizador sprTemporizador;
	            
    public:        
        PUBLIC_CLASS_ID;        
        
        unsigned char ii_gemas,ii_llaves;
        int ii_flechas,ii_monedas,ii_vidas;
        long il_puntos_flechas,il_puntos_tesoros;
        bool ib_pocion_verde,ib_pocion_amarilla;
        
        TSpriteRedham(PMAImageBank bank,PMAImageBank bdinero);
        ~TSpriteRedham();
        
        void animate(void);
        int *getKillSequence(int& length);
        void stopJump(void);        
        int getHotspotX(void)   { return (position.x+10)  / _TileAX; }
        int getHotspotY(void)   { return (position.y + position.height - 1) / _TileAY; }
        void setTransform(bool cerdo);
        void transformToChiquito(bool pchiquito);
        bool draw(TMABitmap&);
        
        bool isInmune(void)     { return ib_inmune; }
        bool isInvisible(void)  { return ib_invisible; }
        bool isDying(void)      { return ib_muriendo; }

    	bool isEnterLeft(void ) { return (position.x < 8); }
    	bool isEnterRight(void) { return (position.x + position.width > 628 ); }
    	bool isEnterUp(void);
    	bool isEnterDown(void ) { return (position.y + position.height > 478);}
    	bool canGoUp(void);
    	
        void enterLeft(void);
        void enterRight(void);
        void enterUp(void);
        void enterDown(void);
        bool walkPasadizo(void);

    	bool kill(void);
    	bool evalMaskRight(int mask);
    	void move(void);
    	void shutArrow(void);
        void giveMoney(void);
        void setInvisible(void);
        void setInmunity(void);
        void setEnemyTarget(PSpriteGlaurung);
        void getCollisionFoot(int& px,int& py);
        void addPoints(PSpriteGlaurung);
        
        // ------------ Guardado y Recuperacion
        //
        void writeToFile(FILE*);
        void readFromFile(FILE*);
};

// -------------- TSpriteAbreCofre
//
class TSpriteAbreCofre : public TSpriteGlaurung
{
    REGISTER_CLASS protected:
    
        static int ia_anim[21];
        int velocidad;
        int tesoro_en_cofre;
        PSpriteRedham SprMain;
    	    
    public:        
        PUBLIC_CLASS_ID;        
        TSpriteAbreCofre(PMAImageBank);

        void init(int x,int y,int tipo_tesoro,PSpriteRedham rh);

        bool draw(TMABitmap& g);
        void animate(void);
        int getHotspotX(void) { return 0; }
        int getHotspotY(void) { return 0; }
        void showTreasure(bool enemigos=true);
};


// -------------- TSpriteTemporizador
//
class TSpriteTemporizador : public TSpriteGlaurung
{
    REGISTER_CLASS protected:
        
        PSpriteGlaurung sprOver;
        PMAFont io_font;
        int ii_id,ii_time;
        long il_basetime;
        bool ib_show_time;
        
    public:
        PUBLIC_CLASS_ID;
        TSpriteTemporizador(PMAImageBank);
        
        void init(PSpriteGlaurung over,int time,PMAFont font,int id);
        void restore(PSpriteGlaurung over,PMAFont font);
        int getID(void) { return ii_id; }
        void showTime(bool show=true);
        
        virtual bool draw(TMABitmap&);
        virtual int getHotspotX(void);
        virtual int getHotspotY(void);
        
        // ------------ Guardado y Recuperacion
        //
        void writeToFile(FILE*);
        void readFromFile(FILE*);
};

// -------------- TSpriteTexto
//
class TSpriteTexto : public TSpriteTemporizador
{
    REGISTER_CLASS protected:
        
        TMAString text;
        
    public:
        PUBLIC_CLASS_ID;
        TSpriteTexto();
        
        void init(int time,int x,int y,PMAFont font,const char *txt);
        bool draw(TMABitmap&);
};	

// -------------- TSpriteBolsaDinero
//
class TSpriteBolsaDinero : public TSpriteTemporizador
{
    REGISTER_CLASS protected:
        
        static int ia_anim[1];

    public:
        PUBLIC_CLASS_ID;
        TSpriteBolsaDinero(PMAImageBank);
        
        void init(int time,int x,int y,PMAFont font);
        void animate(void);
};	

// -------------- TSpriteBrujoDragon
//
class TSpriteBrujoDragon : public TSpriteGlaurung
{
    REGISTER_CLASS protected:
    
        static const int _VELX = 2;
        static const int _VELY = 2;
    	static int ia_anim_dragon[4];
    	static int ia_anim_brujo[4];
        static int ia_anim_aparicion[9];
    	
    	PSpriteRedham redham;
        PSpriteFlecha io_flecha;
        bool ib_brujo;
        int il_ciclos;

        void move(void);
            	    
    public:        
        PUBLIC_CLASS_ID;        
        TSpriteBrujoDragon(PMAImageBank,PSpriteRedham r,bool brujo=true);
        ~TSpriteBrujoDragon();

        PSpriteFlecha getFuego(void) { return io_flecha; }
        
        void animate(void);
        int getHotspotX(void);
        int getHotspotY(void);
        
        bool collisionsWith(TSpriteGlaurung& spr);
        int *getKillSequence(int& length);
};

#endif
