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

#include "x86.h"

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

//#include "display.h"
#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 */

#ifdef x86
#define VIS_WIDTH ((SCREEN_WIDTH / CELL_WIDTH) + 1)
#define VIS_HEIGHT ((SCREEN_HEIGHT / CELL_HEIGHT) + 1)
#else
#define VIS_WIDTH 12 //15   /* (SCREEN_WIDTH / CELL_WIDTH) */
#define VIS_HEIGHT 7 //8 /* (SCREEN_HEIGHT / CELL_HEIGHT) */
#endif

#ifdef x86
#define VIS_CELLS (VIS_HEIGHT * VIS_WIDTH)
#else
#define VIS_CELLS 72 //120 /* visible is 12x7 cells */
#endif

#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
#define CMD_DIALOGUE 3 /* special command for displaying dialogue
			  boxes in the status bar. */
#define CMD_PROD 4 /* when changing productions */

/* 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. */
  int selected_town; /* town which is currently selected...? */
  int selected_army; /* army group which is currently selected. -1
			means no selection. */

  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 *font; /* the font */
  Image *graphics2; /* more graphics*/
#endif
#ifdef x86
  SDL_Surface *graphics;
  SDL_Surface *army_graphics;
  SDL_Surface *font;
  SDL_Surface *graphics2;
#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);

/**
 * Initiate a new turn.
 */
void start_turn(struct world *w, struct display *d);

/**
 * Emerge a hero out of the ether.
 */
void emerge_hero(struct world *w);

/**
 * Generate a random hero name.
 */
char *hero_name();

/**
 * Fire up the production panel.
 */
void production(struct world *w, struct display *d);

/**
 * Move the selected army to the next one owned by the current player.
 */
void select_next_army(struct world *w);

/**
 * Move the selected army to the previous one owned by the current
 * player.
 */
void select_prev_army(struct world *w);

