/**********************************************/
/* Evert Glebbeek 2003                        */
/* eglebbk@phys.uva.nl                        */
/**********************************************/
#include <allegro.h>
#include <stdio.h>
#include "gamegfx.h"
#include "gfx.h"
#include "global.h"
#include "intrface.h"
#include "fonts.h"
#include "dialog.h"

/* Macro: Change mouse pointer and set hotspot */
#define SET_MOUSE_CURSOR(curs) {set_mouse_sprite((curs).gfx); set_mouse_sprite_focus((curs).hotx,(curs).hoty); current_ptr=&(curs);}
/* Check if passed cursor is the current mouse cursor */
#define IS_CURRENT_MS_CURSOR(curs) (&(curs)==current_ptr)

/* Structure to hold mouse pointers */
typedef struct MS_CURSOR {
   BITMAP *gfx;                 /* Mouse pointer graphic */
   int hotx, hoty;              /* Hot-spot coordinates */
} MS_CURSOR;

static DATAFILE *intrface_dat = NULL;
static DATAFILE *fonts_dat = NULL;

static PALETTE *colour_values;
static FONT *default_font = NULL;
COLOR_MAP *light_map = NULL;
COLOR_MAP *trans_map = NULL;

/* Mouse pointers */
static MS_CURSOR mouse_ptr;     /* Default mouse arrow */
static MS_CURSOR *current_ptr;  /* Pointer to struct of current mouse ptr */
static MS_CURSOR dir_arrows[8]; /* Direction arrows */
static MS_CURSOR mouse_detail;  /* Magnifying glass */
static MS_CURSOR mouse_map_target;  /* Mouse cursor for selecting a target */
static MS_CURSOR mouse_unit_target; /* Mouse cursor for selecting a target */

/***************************/
/* Font selection routines */
/***************************/
const FONT *get_royal_font(void)
{
   return fonts_dat[ROYAL_FONT].dat;
}

const FONT *get_normal_font(void)
{
   return fonts_dat[REGULAR_FONT].dat;
}

const FONT *get_large_font(void)
{
   return default_font;
}

const FONT *get_menu_font(void)
{
   return fonts_dat[MENU_FONT].dat;
}

const FONT *get_menu_bold_font(void)
{
   return fonts_dat[MENU_BOLD_FONT].dat;
}

const FONT *get_small_font(void)
{
   return fonts_dat[SMALL_FONT].dat;
}

const FONT *get_colour_font(void)
{
   return fonts_dat[COLOUR_FONT].dat;
}

const FONT *get_alt_colour_font(void)
{
   return fonts_dat[LUC].dat;
}

const FONT *get_title_font(void)
{
   return fonts_dat[TITLE_FONT].dat;
}

const FONT *get_password_font(void)
{
   return fonts_dat[PASSWORD_FONT].dat;
}


PALETTE *get_font_palette(void)
{
   ASSERT(fonts_dat);

   return fonts_dat[FONT_PALETTE].dat;
}

/***************************/
/* Mouse pointer status    */
/***************************/
int get_mcptr_hotx(void)
{
   return current_ptr->hotx;
}
int get_mcptr_hoty(void)
{
   return current_ptr->hoty;
}
int get_mcptr_w(void)
{
   return current_ptr->gfx->w;
}
int get_mcptr_h(void)
{
   return current_ptr->gfx->h;
}

/***************************/
/* Interface bitmaps       */
/***************************/
BITMAP *get_button_bitmap(const int buttonstyle)
{
   return intrface_dat[BUTTON0 + buttonstyle].dat;
}

BITMAP *get_ror_button_bitmap(void)
{
   return intrface_dat[BUTTON_ROR].dat;
}

BITMAP *get_rol_button_bitmap(void)
{
   return intrface_dat[BUTTON_ROL].dat;
}

SAMPLE *get_button_sample(void)
{
   return intrface_dat[BUTTON_WAV].dat;
}

BITMAP *get_proind_bitmap(void)
{
   return intrface_dat[PROIND].dat;
}

BITMAP *get_dframe_bitmap(void)
{
   return intrface_dat[FRAME1].dat;
}

BITMAP *get_alt_dframe_bitmap(void)
{
   return intrface_dat[FRAME1a].dat;
}


BITMAP *get_cboxnch_bitmap(void)
{
   return intrface_dat[CBOXNCH].dat;
}

BITMAP *get_cboxch_bitmap(void)
{
   return intrface_dat[CBOXCH].dat;
}

BITMAP *get_obutnch_bitmap(void)
{
   return intrface_dat[OBUTNCH].dat;
}

BITMAP *get_obutch_bitmap(void)
{
   return intrface_dat[OBUTCH].dat;
}

BITMAP *get_opt_frame_bitmap(void)
{
   return intrface_dat[OPT_FRAME].dat;
}

BITMAP *get_empty_slot_bitmap(void)
{
   return intrface_dat[EQPSLOT].dat;
}

PALETTE *get_game_palette(void)
{
   //return intrface_dat[ZZZ_PALETTE].dat;
   return colour_values;
}

BITMAP *get_cursor_bitmap(void)
{
   return intrface_dat[CURSOR].dat;
}

/* Load tile and interface graphics and fonts */
/* Initialize everything */
void load_global_gfx(void)
{
   int c;

   //set_color_conversion (COLORCONV_TOTAL+COLORCONV_DITHER);
   if (fonts_dat) {
      unload_datafile(fonts_dat);
      fonts_dat = NULL;
   }
   if (intrface_dat) {
      unload_datafile(intrface_dat);
      intrface_dat = NULL;
   }

   if (!default_font) {
      default_font = font;
   }
   //set_color_conversion (COLORCONV_NONE);
   intrface_dat = load_datafile(get_game_path("intrface.dat"));

   if (!intrface_dat) {
      set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
      allegro_message("Unable to load interface data!\n"
                      "Make sure that the datafile is in the current directory\n");
      exit(EXIT_FAILURE);
   }

   colour_values = intrface_dat[ZZZ_PALETTE].dat;
   select_palette(*get_game_palette());

   if (bitmap_color_depth(screen) == 8) {
      unload_datafile(intrface_dat);
      intrface_dat = load_datafile(get_game_path("intrface.dat"));
      colour_values = intrface_dat[ZZZ_PALETTE].dat;
   }

   set_color_conversion (COLORCONV_NONE);
   fonts_dat = load_datafile(get_game_path("fonts.dat"));
   if (!fonts_dat) {
      set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
      allegro_message("Unable to load fonts!\n"
                      "Make sure that the datafile is in the current directory\n");
      exit(EXIT_FAILURE);
   }

   set_color_conversion(COLORCONV_TOTAL + COLORCONV_DITHER);

   /* Set proper colours */
   (*colour_values)[0].r = (*colour_values)[0].g = (*colour_values)[0].b = 0;

   set_palette(*get_game_palette());
   select_palette(*get_game_palette());
   if (bitmap_color_depth(screen) == 8) {
      if (light_map == NULL)
         light_map = malloc(sizeof(COLOR_MAP));
      if (trans_map == NULL)
         trans_map = malloc(sizeof(COLOR_MAP));
      create_light_table(light_map, *get_game_palette(), 0, 0, 0, NULL);
      create_trans_table(trans_map, *get_game_palette(), 0, 0, 0, NULL);
      color_map = light_map;
      makecolour = makecol8;
   } else {
      set_trans_blender(0, 0, 0, 128);
      switch (bitmap_color_depth(screen)) {
         case 15:
            makecolour = makecol15;
            break;
         case 16:
            makecolour = makecol16;
            break;
         case 24:
            makecolour = makecol24;
            break;
         case 32:
            makecolour = makecol32;
            break;
         default:
            makecolour = makecol8;
      }
   }
   /* Initialize symbolic colour names */
   black = makecolour(0, 0, 0);
   grey = makecolour(192, 192, 192);
   white = makecolour(255, 255, 255);
   yellow = makecolour(255, 255, 64);
   red = makecolour(192, 0, 0);
   blue = makecolour(0, 0, 192);
   bright_red = makecolour(240, 40, 40);
   bright_blue = makecolour(40, 40, 240);

   /* Set default font */
   font = (FONT *)get_normal_font();

   /* Initialize mouse pointers */
   mouse_ptr.gfx = intrface_dat[MOUSE_ARROW].dat;
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_ARROW], DAT_ID('H', 'O', 'T', 'X')), "%d",
          &(mouse_ptr.hotx));
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_ARROW], DAT_ID('H', 'O', 'T', 'Y')), "%d",
          &(mouse_ptr.hoty));

   mouse_detail.gfx = intrface_dat[MOUSE_DETAIL].dat;
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_DETAIL], DAT_ID('H', 'O', 'T', 'X')), "%d",
          &(mouse_detail.hotx));
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_DETAIL], DAT_ID('H', 'O', 'T', 'Y')), "%d",
          &(mouse_detail.hoty));

   mouse_map_target.gfx = intrface_dat[MOUSE_YELLOW_CROSS].dat;
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_YELLOW_CROSS], DAT_ID('H', 'O', 'T', 'X')),
          "%d", &(mouse_map_target.hotx));
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_YELLOW_CROSS], DAT_ID('H', 'O', 'T', 'Y')),
          "%d", &(mouse_map_target.hoty));

   mouse_unit_target.gfx = intrface_dat[MOUSE_RED_CROSS].dat;
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_RED_CROSS], DAT_ID('H', 'O', 'T', 'X')), "%d",
          &(mouse_unit_target.hotx));
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_RED_CROSS], DAT_ID('H', 'O', 'T', 'Y')), "%d",
          &(mouse_unit_target.hoty));

   for (c = 0; c < 8; c++) {
      dir_arrows[c].hotx = dir_arrows[c].hoty = 11;
   }

   dir_arrows[0].gfx = intrface_dat[MOUSE_N].dat;
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_N], DAT_ID('H', 'O', 'T', 'X')), "%d",
          &(dir_arrows[0].hotx));
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_N], DAT_ID('H', 'O', 'T', 'Y')), "%d",
          &(dir_arrows[0].hoty));

   dir_arrows[1].gfx = intrface_dat[MOUSE_NE].dat;
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_NE], DAT_ID('H', 'O', 'T', 'X')), "%d",
          &(dir_arrows[1].hotx));
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_NE], DAT_ID('H', 'O', 'T', 'Y')), "%d",
          &(dir_arrows[1].hoty));

   dir_arrows[2].gfx = intrface_dat[MOUSE_E].dat;
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_E], DAT_ID('H', 'O', 'T', 'X')), "%d",
          &(dir_arrows[2].hotx));
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_E], DAT_ID('H', 'O', 'T', 'Y')), "%d",
          &(dir_arrows[2].hoty));

   dir_arrows[3].gfx = intrface_dat[MOUSE_SE].dat;
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_SE], DAT_ID('H', 'O', 'T', 'X')), "%d",
          &(dir_arrows[3].hotx));
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_SE], DAT_ID('H', 'O', 'T', 'Y')), "%d",
          &(dir_arrows[3].hoty));

   dir_arrows[4].gfx = intrface_dat[MOUSE_S].dat;
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_S], DAT_ID('H', 'O', 'T', 'X')), "%d",
          &(dir_arrows[4].hotx));
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_S], DAT_ID('H', 'O', 'T', 'Y')), "%d",
          &(dir_arrows[4].hoty));

   dir_arrows[5].gfx = intrface_dat[MOUSE_SW].dat;
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_SW], DAT_ID('H', 'O', 'T', 'X')), "%d",
          &(dir_arrows[5].hotx));
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_SW], DAT_ID('H', 'O', 'T', 'Y')), "%d",
          &(dir_arrows[5].hoty));

   dir_arrows[6].gfx = intrface_dat[MOUSE_W].dat;
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_W], DAT_ID('H', 'O', 'T', 'X')), "%d",
          &(dir_arrows[6].hotx));
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_W], DAT_ID('H', 'O', 'T', 'Y')), "%d",
          &(dir_arrows[6].hoty));

   dir_arrows[7].gfx = intrface_dat[MOUSE_NW].dat;
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_NW], DAT_ID('H', 'O', 'T', 'X')), "%d",
          &(dir_arrows[7].hotx));
   sscanf(get_datafile_property
          (&intrface_dat[MOUSE_NW], DAT_ID('H', 'O', 'T', 'Y')), "%d",
          &(dir_arrows[7].hoty));

   SET_MOUSE_CURSOR(mouse_ptr);
}

/* Returns the game title screen bitmap */
BITMAP *get_title_screen(PALETTE pal)
{
   pal = intrface_dat[ZZZ_PALETTE].dat;
   return intrface_dat[TITLE].dat;
}

/* Select a specific mouse pointer */
/*  -1  default arrow */
/*   0  north (scroll) arrow */
/*   .   */
/*   .   */
/*   7  north-west (scroll) arrow */
/*   8  detailed cursor/information cursor */
/*   9  select map target cursor */
/*  10  select unit target cursor */
void select_mouse_cursor(const int id)
{
   MS_CURSOR *wanted_ptr = current_ptr;

   if (id == -1) {
      wanted_ptr = &mouse_ptr;
   } else if (id < 8) {
      wanted_ptr = &(dir_arrows[id]);
   } else if (id == 8) {
      wanted_ptr = &(mouse_detail);
   } else if (id == 9) {
      wanted_ptr = &(mouse_map_target);
   } else if (id == 10) {
      wanted_ptr = &(mouse_unit_target);
   }

   if (current_ptr != wanted_ptr) {
      scare_mouse();
      SET_MOUSE_CURSOR(*wanted_ptr);
      unscare_mouse();
   }
}
