#ifndef LEVEL_H
#define LEVEL_H
/*! \file level.h
 *  \brief Dungeon level description and content
 */
#include "items.h"
#include "monsters.h"

/*! The maximum number of distinct entries in the content array */
#define MAXITEMS 100

/*! Status of a map cell */
typedef enum _occupation {
	BUSY /*! The cell is permanently occupied by a wall or such */, 
	FREE /*! The cell is free (though items can be there) */,
	ATCK /*! The cell is occupied by a monster. Moving there means to attack */
} occupation;

/*! \Brief Status of an object in the level object array. 
 *
 * This enum is used because the set of objects in the level is defined
 * as a (dynamic) array of content structures. 
 * \todo It would be better handled as a list (implementing this feature is 
 * a good exercise for the winter break!)
 */
typedef enum _obj_valid {
	INVALID /*! Not used */,
	VALID /*! The object is valid */,
	REMOVED /*! The object was destroyed or removed */
} obj_valid;



/*! This is a placeholder for future development
 *  Effects are merely numbered, for now */
typedef enum _effect { NOEFFECT } effect;

/*! \brief This structure represents the content of a dungeon cell 
 *
 * There may be multiple object stashes or stashes and a monster
 * in a single cell
 * \todo Exercise: implement a check to verify that only one monster is present.
 * \todo Exercise: merge stashes in the same location, but not those associated
 * with an eventual monster.
 */
typedef struct _content{
	int row;         /*! position: row */ 
	int col;         /*! position: col */
	item *stash;     /*! Items present in the cell
	                  *  if monster!=NOMONSTER, these items are moved with the monster 
	                  *  and part of its equipment/treasure */
	effect special;  /*! trap or special effect */
	monster *npc;    /*! monster or npc */
	obj_valid valid; /*! Whether the object is in use, removed, or not initialized */
} content;

/*! \brief Definition of a dungeon level 
 *
 * This information is read from a level configuration file
 */
typedef struct _Level {
	char *name;/*! Dungeon level name (e.g.: Temple of Orcus) */
	char **map;/*! Array of arrays representing the level map */
	int rows;  /*! Number of rows in map */
	int cols;  /*! Number of cols in map */
	int depth; /* Determines random threats levels */
	content *objs; /*! Array of content objects. 
	                *  \todo See \see obj_valid for possible variations */
} Level;

/*! Load a level map from the specified file 
 *  \param filename  A file name, read from the level configuration file 
 *  \return   The level map 
 */
Level *load_level_map(char *filename);

/*! Load a level from the specified file
 *  \param filename  The file containing the description of the level
 *  \return   A Level data struction 
 */
Level *load_level(char *filename);

/*! Counts how many objects are found in the level */
int count_objs_in_level(Level *level);

/*! Adds an item to the level */
void add_item_to_level(Level *level, int row, int col, item_types itype,
											 int quantity, int magic, char *text, int special);

/*! Removes i-th object from the level */
void *remove_object_from_level(Level *level, int i);

/*! Find if a position (row,col) is occupied by walls or
 * other impassable obstacles, or by a monster 
 */
occupation can_move_to(Level *level, int row, int col);

/*! Determines if there is a monster at a given location (row, col) */
monster *find_monster_at(Level *level, int row, int col);

/*! Removes a monster from the level */
void remove_monster_from_level(Level *level, monster *npc);

/*! Adds a new monster to the level at position row, col */
void add_monster_to_level(Level *level, int row, int col, monsters type);


/*! Print the level map using the printer library */
void print_level(Level *level, int row, int col, char pcsymbol);

#endif /*  LEVEL_H */
