/* display.h
 *
 * Renders the displays.
 *
 * (c) 2006, Joseph Curtis
 */

#include "x86.h"


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

/* dimensions of the graphical font */
#define FONT_WIDTH 16
#define FONT_HEIGHT 18
/** number of font elements per line in the font graphics */
#define FONT_GRAPHICS_WIDTH 16
#define SPACING 10
#define FONT_MUL 1

/* flagstaff location defines */
/** coords of the top-left corner of the flag block in pixels */
#define FLAG_X 0
#define FLAG_Y 280
/* flagstaff info */
#define FLAGSTAFF_X 32
#define FLAGSTAFF_Y 252
#define FLAGSTAFF_WIDTH 32
#define FLAGSTAFF_HEIGHT 28
/** width of the flag graphics block in FLAG_WIDTHs */
#define FLAG_GRAPHICS_WIDTH 5
#define FLAG_WIDTH 32
#define FLAG_HEIGHT 10
/* flag nub info */
#define FLAGNUB_X 160
#define FLAGNUB_Y 280
#define FLAGNUB_WIDTH 12
#define FLAGNUB_HEIGHT 10

/* Selection square defines.  Coords are for the ARMIESC.png file */
#define SSELECT_X 0     /* small selection square */
#define SSELECT_Y 400
#define SSELECT_WIDTH 40
#define SSELECT_HEIGHT 30
#define SELECT_X 0
#define SELECT_Y 430
#define SELECT_WIDTH 40
#define SELECT_HEIGHT 40

#define ASCII_SPACE 32

#define STATUS_BAR_HEIGHT 32

/* view types */
#define VIEW_MENU 0
#define VIEW_MAIN 1
#define VIEW_MAP 2
#define VIEW_BORDER 3
#define VIEW_PLAYERS 4
#define VIEW_LOAD 5

/* select players window defines for non majik, still kludgy */
#define SP_FIRST_X  36
#define SP_FIRST_Y 104

#define SP_SECOND_X 163
#define SP_SECOND_Y 168

#define SP_SPACING 64



struct view {
  int type; /* the view type */
#ifndef x86
  Image *image; /* the image to display */
#endif
#ifdef x86
  SDL_Surface *image;
#endif
  void *func; /* function to call to update.  I think we can say this
		 is obselete. */
};

struct display {
#ifdef x86
  SDL_Surface *screen;
#endif
  int current_view; /* Which display the screen is currently looking at. */
  int num_views; /* number of displays */
  struct view *views; /* array of displays */
  char status_bar_text[128]; /* sort of a kludge */
};


/* Macros for manipulating vis_x and vis_y to make sure they never go
   outside the bounds.  Only modifies vis_x if it is within bounds. */
#define VISX_MOD(visx, mod) ((((visx + mod) >= 0) && ((visx + mod) < ((default_world->width * CELL_WIDTH) - (SCREEN_WIDTH) - 1))) ? (visx += mod) : (visx = visx))
#define VISY_MOD(visy, mod) ((((visy + mod) >= 0) && ((visy + mod) < ((default_world->height * CELL_HEIGHT) - (SCREEN_HEIGHT) - 1))) ? (visy += mod) : (visy = visy))

#define VISX_SET(visx, set) ((((set) >= 0) && ((set) < ((default_world->width * CELL_WIDTH) - (SCREEN_WIDTH) - 1))) ? (visx = set) : (visx = visx))
#define VISY_SET(visy, set) ((((set) >= 0) && ((set) < ((default_world->height * CELL_HEIGHT) - (SCREEN_HEIGHT) - 1))) ? (visy = set) : (visy = visy))


/**
 * Update a view and it's corresponding crap on teh screen
 *
 * @param d The display containing the view to update.
 * @param v The view to update.
 * @param data The data to update the view with.
 * 
 * @return 1 on success, NULL on failure.
 */
int update_view(struct display *d, int v, void *data);


/**
 * Updates the current view in the display
 *
 * @param d Display to update current view.
 *
 * @return 1 on success, NULL on failure.
 */
int update(struct display *d, void *data);


/**
 * Update the main view
 */
int update_main(struct display *d, void *data);

/**
 * Update the menu view
 */
int update_menu(struct display *d, void *data);

/**
 * Update the map view
 */
int update_map(struct display *d, void *data);

/**
 * Set up the default display.  Temporary for getting it going.
 */
int setup_default_display();

/**
 * Destroy the default display.
 */
int destroy_default_display();

/**
 * Paint a beveled box to the image.
 */
//void beveled_box(int x, int y, int width, int height, Image *i);

/**
 * Print some text to the screen
 */
void putText(int x, int y, char *text, struct world *w, struct display *d, int view);

#ifdef x86
/**
 * load a file to a SDL surface
 */
SDL_Surface * load_surface(char * filename);
#endif

/**
 * Update the info in the select players view.
 */
int update_players(struct display *d, void *data);

/**
 * Blit the needed selection box.
 */
void blit_selection_box(struct world *w, struct display *d, int i);


#ifdef x86
/**
 * Blit and image to an image
 */
void blit_image_image(int x, int y, int w, int h, SDL_Surface *srcimage,
		      int x1, int y1, SDL_Surface *destimage);

void blit_image_screen(int x, int y, int w, int h, SDL_Surface *srcimage,
		       int x1, int y1);
#endif

#ifndef x86
#define blit_image_screen blitImageToScreen
#define blit_image_image blitAlphaImageToImage
#endif


/**
 * Put a dialogue of text on the screen, removed by x button.
 */
void dialogue_x(char *txt, struct world *w, struct display *d);

/**
 * Return the total width that this text will take up once rendered in
 * the font.  Uses the font_width struct.
 */
int text_width(char *txt);

/**
 * Flip the screen.
 */
void flip();

/**
 * Render the terrain to the main view.
 */
int render_terrain(struct display *d, struct world *w);

/**
 * Render the castles in the main view.
 */
int render_castles(struct display *d, struct world *w);

/**
 * Draw a box on the screen.
 */
int draw_box(int x, int y, int width, int height, struct world *w, struct display *d);

