/* level.h

   This module handles levels in their initial state. They are all loaded
   from disk and kept in the memory. The tile map is already suitable for use
   by the preview.h module. However, when a game is played, the game.h module
   duplicates the tile map, initialises the sprites, and takes over. It does
   not modify the data set up here.


   LEVEL FORMAT:
	This is how the level format will look on disk. The level will be a
	text file accompanied by two bitmaps (a height map and a texture map -
    see later for details). The size of the heightmap will determine the total
	size of the map. The level name will be displayed in the game. The level number
	will be used to order the levels once they are loaded. The number MUST be the
	slot where the level will go into. Set 'Number' to -1 for automatic.

<FILE>

	[level]
	Name = (string)
	Number = (int)
	HeightMap = path/filename.ext	(MUST BE AN 8BPP IMAGE)
	TextureMap = path/filename.ext  (MUST BE AN 8BPP IMAGE)
	BorderTexture= (int)
	

	[Cat]
	X=(int)
	Y=(int)
	Direction=(int)

	[Duck]
	...

	[Rabbit]
	...

	[Chipmunk]
	...

	[level]
	(start second level in list)
	.
	.
	.

	[end]   (no more levels in this file)


</FILE>

	The height map will be a simple 16bpp bitmap where the height of the tile at
	the position is the luminance of the pixel. The heightmap will be loaded
	interpreted, converted to a tilemap, then destroyed. The heights 0-255 will be
	linearly mapped to z-values of the range (0.0-scale_factor).

	The texture map will hold the data in the level. The value of the pixels are to be
	turned directly into the TEXTURE_* constants.

	Note that the bitmaps and the level data could be inside datafiles, so the datafile#object
	notation can be used and must be interpreted correctly. See Zasx/weapon.c for details on
	the implementation.

	Also note that the level file can actually contain multiple levels. This is done by using
	another [level] tag.
*/

#ifndef INCLUDED_LEVEL_H
#define INCLUDED_LEVEL_H

#include "main.h"
#include "tilemap.h"
#include "sprite.h"


typedef struct LEVEL {

 /* All fields in the tile map, including those that will be modified during
    the game, are set to their initial states.
 */
 TILEMAP *map;
 float scale_factor;

 /* The players' starting coordinates are specified as integers. The players
    will be placed in the centres of their tiles when initialised, so 0.5
    must be added to each ordinate.

    The players' directions are specified as follows:
      0 = up
      1 = up right
      2 = right
      3 = down right
      4 = down
      5 = down left
      6 = left
      7 = up left
    To convert to radians, as will be necessary when initialising the
    sprites, this value can be multiplied by (M_PI / 4.0).
 */
 struct {
  int x;
  int y;
  int dir;
 } player[N_PLAYERS];

 BITMAP *HeightMap, *TextureMap;
 int border;

 int number;

 struct SPRITE *portalsprite;

} LEVEL;


#define MAX_LEVELS 4096


/* These arrays will store all the levels loaded from the disk.
   the_level_names[] is compatible with md_selection() (see menuproc.h).
   n_levels should be initialised to 0.
*/
extern LEVEL *the_levels[MAX_LEVELS];
extern char *the_level_names[MAX_LEVELS];
extern int n_levels;


/* load_level(): suitable for use with for_each_file(), this function loads a
   level and adds it to 'the_levels'. If it fails to load a level owing to a
   corrupt file or lack of memory, it should free any memory belonging to the
   partial level and return. It should *not* set errno; on the contrary it
   should make sure errno is clear before returning, so that the other levels
   will be loaded. However, it can safely use allegro_message() to report
   levels that could not be loaded. Errors should look like this:

   "Unable to load %s\n"

   %s is the level filename, obviously.

   If the arrays are full (n_levels == MAX_LEVELS), then we should display:

   "Unable to accommodate so many levels!\n"

   (Make sure you spell 'accommodate' right, even though no sane person will
   have 4097 levels on their disk :-P)

   Then set errno to ENOMEM. That way for_each_file() will not try to load
   any further levels.
*/
void load_level(const char *filename, int attrib, int param);


/* load_levels(): this uses for_each_file() with load_level() to load all
   levels from the disk and put them in 'the_levels'. It should be called
   once at the beginning of the program. If it returns 1, the program should
   promptly exit; this code means no levels could be loaded!

   If, after calling for_each_file(), n_levels is 0, then use
   allegro_message() to display the following:

   "No levels available to play!\n"

   Then return 1.

   In all other cases, return 0 - even if errors occurred loading some of the
   levels. These errors have already been handled inasmuch as error messages
   have been printed by load_level().
*/
int load_levels();


void destroy_level(LEVEL *level);


/* Used when starting a game. */
TILEMAP *level_initiate_tilemap(LEVEL *level);

/* Used when game ends */
void level_uninitiate_tilemap(TILEMAP *map);

/* This frees all memory occupied by the levels. It should be called once at
   the end of the program.
*/
void unload_levels();


#endif /* INCLUDED_LEVEL_H */
