/* engine.h
* This software is released under the revised BSD license.  
* See license.txt for details
* Copyright 2006 Dale Wick, John-Paul Gignac.
*/

#ifdef _cpp
extern "C" {
#endif

#define PRECISION 480
#define PTILEWIDTH 16
#define PTILEHEIGHT 16
#define TILEWIDTH (PTILEWIDTH*PRECISION)
#define TILEHEIGHT (PTILEHEIGHT*PRECISION)
#define TILESACROSS 16
#define TILESDOWN 24
#define SCREENWIDTH 30
#define SCREENHEIGHT 17

#define MAXNPC 20480
#define MAXCOLLISIONS 64  // The max # of collisions per animation frame
#define MAXKITTEN 6

struct Character {
	int type;	// See T_ defines below
	int x,y;
	int x_velocity;
	int y_velocity;
	int health;
	int delay;
	struct TileProp *prop;	// Currently playing animation
	int frame;
	int homex,homey;
	int facing;	// Which direction the character is facing
    int invincible;  // Normally 0; counts down after the player gets hurt
    int gravity;  // The amount of gravitational acceleration
    struct Character *prev,*next;
    int marked;
    struct Character *next_marked;
    struct Character *next_active;

    struct Character *landed_on;
	struct Character *first_landed;
	struct Character *next_landed;
	struct Character *prev_landed;
    int oldx, oldy;

    int x_tweak;
};

struct CharIterator {
    int minx,miny,maxx,maxy;
    int x,y;
    struct Character *last;
};

struct Collision {
    struct Character *a;
    struct Character *b;
    int dir;
};

struct Game {
	short *map;
	int w,h,t,l;	// Width, height, top, left (of visible) measured in tiles
	int available;	// Fruit available
	int collected;	// Fruit collected
	int bomb;		// number of bombs on hand.
	int checkpointX,checkpointY;
	int level;
	int score;
	int bonus[3];
	int key[4];	// YELLOW, GREEN, BLUE, RED
	int activeTeleport;
	int lives;
	int joystick;	// Last seen direction
	struct Character player;
	struct Character npc[MAXNPC];
    struct Character *first_unused_npc;
	int invalidate;
	int mode;
    struct Character *first_marked;
    struct Character *kitten[MAXKITTEN];
    int kittenCount;

    int gridw, gridh;
    struct Character **grid;

    int collisionCount;
    struct Collision collision[MAXCOLLISIONS];

    struct Character *first_active;
};
extern struct Game game;

extern struct TileProp {
	int ch;
    int type;
	int id;         // Tile id of top left corner
	int gfxw;
	int gfxh;
	int frames;     // For animated tiles
	int flags;
    int offsetx,offsety,w,h;   // Core position in pixels
    int inertia;
    int rigidity;
} tileProp[];

#define M_BRIDGE 0
#define M_FRUIT1 48
#define M_SOLIDGROUND 32
#define M_EXIT 33
#define M_CRATE 1
#define M_ELEVATOR 5
#define M_PONY 512
#define M_GRASS 16
#define M_KITTEN 1024
#define M_HAYBALE 3
#define M_SPARKLE 27
#define M_KISSING 192

#define S_JUMP 0
#define S_LEVELSTART 1
#define S_KITTEN 2
#define S_LEVELEND 3
#define S_DIE 4
#define S_ELEVATOR 5
#define S_MATCH 6
#define S_DOOR 7
#define S_LEVELSONG 8

#define D_NONE -1
#define D_LEFT 0
#define D_UP 1
#define D_RIGHT 2
#define D_DOWN 3

#define T_PLAYER 0
#define T_SPECIALEFX 8
#define T_GROUND 10
#define T_FRUIT 12
#define T_EXIT 23
#define T_CRATE 26
#define T_ELEVATOR 27
#define T_PONY 28
#define T_KITTEN 29


#define MODE_RUNNING 0
#define MODE_MENU 1
#define MODE_GETREADY 2
#define MODE_LEVELOVER 3
#define MODE_GAMEOVER 4

extern struct Game game;
// Engine implemented
void new_game();
void new_level(int level);
void load_level(const char *fname);
void save_level(const char *fname);
void next_frame(int elapsed);
void draw_map();
void set_player_direction(int direction);
void do_jump();
void release_jump();
void do_bomb();
void do_attack();
void do_special();

void construct_level(int w,int h);
void set_tiles(int x,int y,int tile);
struct TileProp *tile_to_prop(int tile);
int ch_to_tile(int ch);
extern int editMode;

// SDL implemented
void draw_tile(int id,int x,int y);
void draw_tile_rect(int id,int x,int y,int w,int h);
void play_sound(int id);
void draw_number(int id,int x,int y);
void draw_message(int size,int x,int y,const char *msg);

#ifdef _cpp
}
#endif
