/* world.h
 *
 * Represents a map.
 *
 * (c) 2006, Joseph Curtis
 */

#include "x86.h"

#ifndef x86
#include "graphics.h"
#endif

#include "cell.h"
#include "town.h"
#include "army.h"

#define CELL_WIDTH 40 //32    /* cells 40 pixels wide */
#define CELL_HEIGHT 40 //32   /* cells 40 pixels high */

#define VIS_WIDTH 12 //15   /* (SCREEN_WIDTH / CELL_WIDTH) */
#define VIS_HEIGHT 6 //8 /* (SCREEN_HEIGHT / CELL_HEIGHT) */

#define VIS_CELLS 72 //120 /* visible is 12x6 cells (VIS_HEIGHTxVIS_WIDTH)*/

#define GRAPH_WIDTH 12 //15 /* width in cells of the source graphics file */

#define NUM_PLAYERS 1 /* May change in the future */

#define WORLD_NAME_LENGTH 50

/* commands */
#define CMD_NONE 0
#define CMD_INFO 1
#define CMD_MOVE_ARMY 2

/* macros for accessing map cells */

/**
 * Generate an index from two coordinates.
 * x and y coordinates, w represents width of matrix.
 */
#define I(x, y, w) (x + (y * w))

/**
 * Get the x coordinate from the index and the width.
 */
#define X(i, w) (i % w)

/**
 * Get the y coordinate from the index and the width.
 */
#define Y(i, w) (i / w)

/**
 * Contains everything.  Terrain cells, towns, armies.
 */
struct world {
  int width;       /* width of map in cells */
  int height;      /* height of map in cells */
  int num_towns;   /* how many towns? */
  int num_armies;  /* Actually number of army groups */
  int num_players; /* I guess this should always be 8. */
  int vis_x;       /* world relative coordinate of the top-left of the visible window. */
  int vis_y;       /* as above */
  int turn;        /* current turn */
                   /* Was going to put an indicator of whose turn it
		      is however this information can be gleaned from
		      turn % num_players. */
  char command;    /* Command currently being undertaken by current player. */

  char name[WORLD_NAME_LENGTH]; /* The name of the world */
  //  struct cell vis[VIS_CELLS]; /* cells currently visible */
  struct cell *map;     /* The terrain */
  struct town *towns;   /* towns, duh */
  struct army_group *armies;  /* where the troops are */
  struct player *players; /* */
#ifndef x86
  Image *graphics; /* matrix of cells for the graphics.  GRAPH_WIDTH
		      wide, multiple of CELL_HEIGHT high.  Images are
		      numbered from left to right and top to bottom,
		      starting with 0. */
  Image *army_graphics; /* as above but for the armies.  Uses
			  TROOP_WIDTH and TROOP_HEIGHT and
			  ARMY_WIDTH. */
  //  Image *graphics[VIS_CELLS];  /* Experimenting with this for ease of use */
#endif
};


/**
 * Returns a pointer to a newly created world object.  Zeroed.  All
 * worlds must be created in this manner, self malloc'ed worlds will
 * not be tolerated!
 *
 * @return A pointer to a new world on success, NULL on failure.
 */
struct world *create_world();

/**
 * Destroys the world via a swift free or two.  All worlds must be
 * destroyed in this manner, self free'd worlds will not be tolerated!
 *
 * @param w The world to destroy
 *
 * @return 1 on success, NULL on failure.
 */
int destroy_world(struct world *w);

/**
 * Load a world from a file.
 *
 * @param w Pointer to the world.  Previously created with create_world.
 * @param file The file to load from.
 *
 * @return 1 on success, NULL on failure.
 */
int load_world(struct world *w, char * file);


/**
 * Save a world to a file.
 *
 * @param w Pointer to the world.
 * @param file The file to save to.
 *
 * @return 1 on success, NULL on failure.
 */
int save_world(struct world *w, char * file);


/**
 * Setup the default world, mainly here for testing purposes.
 */
int setup_default_world();

/**
 * Print out a text pic of teh world
 */
void print_world(struct world *w);

/**
 * Load a world from the text format.
 */
int load_world_text(struct world *w, char *file);


/**
 * Self-explanitory test function.
 */
void create_test_army(struct world *w);

/**
 * Ditto.
 */
void create_test_player(struct world *w);

