#include <stdio.h>
#include <string.h>

#include "angband.h"

char basepath[4096];

void die(const char *format, ...)
{
   va_list ar;

   va_start(ar, format);
   vprintf(format, ar);
   va_end(ar);
   exit(0);
};

#define suffix(a,b) ((a)[strlen(a)-1]==(*b))

static void init_path(void)
{
    cptr tail;
    
    /* Get the environment variable */
    tail = getenv("ANGBAND_PATH");

    /* Use the angband_path, or a default */
    strcpy(basepath, tail ? tail : DEFAULT_PATH);

    /* Hack -- Add a path separator (only if needed) */
    if (!suffix(basepath, PATH_SEP)) strcat(basepath, PATH_SEP);
}

void main(int argc, char **argv)
{
   header head;
   FILE *f, *pref;
   char *ftext;
   int outsym;
   char filename[256];

   init_path();
   sprintf(filename,"%suser/%s",basepath,(argc==2)?argv[1]:"graf-ibm.prf");
   pref = fopen(filename,"w");
   if (!pref) die("Cannot create %s",filename);

   fprintf(pref,"# Graphics definition preference file.\n#\n"
            "# Generated automatically by `makepref' by Mike Marcelais\n#\n");

   {
      /* Do F_INFO.RAW  Feature types */
      feature_type *ftype = NULL;
      int i;

      fprintf(stderr,"Processing F_INFO.RAW...\n");
      fprintf(pref,"# Feature Graphic Definitions\n\n");

      sprintf(filename,"%sdata/f_info.raw",basepath);
      f = fopen(filename,"rb");
      if (!f) die("Cannot open f_info.raw\n");
      fread(&head,sizeof(header),1,f);

      ftype = (feature_type *)malloc(sizeof(feature_type)*head.info_num);
      fread(ftype,head.info_num,sizeof(feature_type),f);

      ftext = (char *)malloc((head.name_size|0x0F)+1);
      fread(ftext,(head.name_size+15)/16,16,f);
      fclose(f);

      for(i=0;i<head.info_num;i++)
         {
         outsym = 0;
         switch(ftype[i].f_char)
            {
            case 0:                  break;  /* Unused */
            case ' ':                break;  /* Unused */
            case '.':  outsym = 217; break;  /* Floor like thing */
            case ';':  outsym = 208; break;  /* Glyph */
            case '\'': outsym = 216; break;  /* Open door */
            case '<':  outsym = 224; break;  /* Up stairs */
            case '>':  outsym = 206; break;  /* Dn stairs */
            case '1':  outsym = 195; break;  /* General Store */
            case '2':  outsym = 196; break;  /* Armory */
            case '3':  outsym = 197; break;  /* Weapon Shop */
            case '4':  outsym = 198; break;  /* Temple */
            case '5':  outsym = 199; break;  /* Alchemist */
            case '6':  outsym = 200; break;  /* Magic Shop */
            case '7':  outsym = 201; break;  /* Black Market */
            case '8':  outsym = 202; break;  /* Home */
            case '^':  switch((i & 0x0F)>>2) /* Trap */
                          {
                          case 0: outsym = 222; break;   /* Pit */
                          case 1: outsym = 223; break;   /* Rune */
                          case 2: outsym = 220; break;   /* Dart */
                          case 3: outsym = 221; break;   /* Gas */
                          };
                       break;
            case '+':  if (i & 0x08)         /* Secured Door */
                          outsym = 213;      /* Jammed Door */
                       else if (i & 0x07)
                          outsym = 214;      /* Locked Door */
                       else
                          outsym = 205;      /* Closed Door */
                       break;
            case '#':  outsym = 212; break;  /* Granite Wall */
            case ':':  outsym = 219; break;  /* Rubble */
            case '%':  if (i & 0x01)
                          outsym = 218;      /* Quartz */
                       else
                          outsym = 215;      /* Magma */
                       break;
            case '*':  if (i & 0x01)
                          outsym = 211;      /* Gold in Quartz */
                       else
                          outsym = 210;      /* Gold in Magma */
                       break;
            default:   fprintf(stderr,"Warning: Don't know how to handle feature %d (%c).\n",i,ftype[i].f_char);
                       break;
            };
         if (outsym)
            {
            fprintf(pref,"# %s\n",&ftext[ftype[i].name]);
            fprintf(pref,"F:%d:%d/%d\n\n",i,ftype[i].f_attr,(signed char)outsym);
            };
         };

      fprintf(pref,"\n");
      free(ftype);
      free(ftext);
   }

   {
      /* Do K_INFO.RAW  Item types */
      object_kind *ftype = NULL;
      int i;

      fprintf(stderr,"Processing K_INFO.RAW...\n");
      fprintf(pref,"# Item Graphic Definitions\n\n");

      sprintf(filename,"%sdata/k_info.raw",basepath);
      f = fopen(filename,"rb");
      fread(&head,sizeof(header),1,f);

      ftype = (object_kind *)malloc(sizeof(object_kind)*head.info_num);
      fread(ftype,head.info_num,sizeof(object_kind),f);

      ftext = (char *)malloc((head.name_size|0x0F)+1);
      fread(ftext,(head.name_size+15)/16,16,f);
      fclose(f);

      for(i=0;i<head.info_num;i++)
         {
         outsym = 0;
         switch(ftype[i].tval)
            {
            case 0:                           break;
            case TV_SKELETON:   outsym = 152; break;
            case TV_BOTTLE:     outsym = 146; break;
            case TV_JUNK:       outsym = 140; break;
            case TV_SPIKE:      outsym = 153; break;
            case TV_CHEST:      outsym = 135; break;
            case TV_SHOT:       outsym = 142; break;
            case TV_ARROW:      outsym = 142; break;
            case TV_BOLT:       outsym = 142; break;
            case TV_BOW:        outsym = 143; break;
            case TV_DIGGING:    outsym = 151; break;
            case TV_HAFTED:     outsym = 160; break;
            case TV_POLEARM:    outsym = 159; break;
            case TV_SWORD:      outsym = 158; break;
            case TV_BOOTS:      outsym = 134; break;
            case TV_GLOVES:     outsym = 138; break;
            case TV_HELM:       outsym = 139; break;
            case TV_CROWN:      outsym = 139; break;
            case TV_SHIELD:     outsym = 150; break;
            case TV_CLOAK:      outsym = 136; break;
            case TV_SOFT_ARMOR: outsym = 132; break;
            case TV_HARD_ARMOR: outsym = 132; break;
            case TV_DRAG_ARMOR: outsym = 132; break;
            case TV_LITE:       switch (ftype[i].sval)
                                   {
                                   case 0: outsym = 156; break;  /* Torch */
                                   case 1: outsym = 141; break;  /* Lamp */
                                   case 4: outsym = 145; break;  /* Phial */
                                   case 5: outsym = 155; break;  /* Star */
                                   case 6: outsym = 131; break;  /* Ark */
                                   };
                                break;
            case TV_AMULET:     outsym = 130; break;
            case TV_RING:       outsym = 147; break;
            case TV_STAFF:      outsym = 154; break;
            case TV_WAND:       outsym = 157; break;
            case TV_ROD:        outsym = 148; break;
            case TV_SCROLL:     outsym = 149; break;
            case TV_POTION:     outsym = 146; break;
            case TV_FLASK:      outsym = 146; break;
            case TV_FOOD:       if (ftype[i].sval < 32)
                                   outsym = 144;  /* Mushrooms */
                                else
                                   outsym = 137;  /* Food */
                                break;
            case TV_MAGIC_BOOK: outsym = 133; break;
            case TV_PRAYER_BOOK:outsym = 133; break;
            case TV_GOLD:       if (ftype[i].k_char == '*')
                                   outsym = 207;
                                else
                                   outsym = 209;
                                break;
            default:   fprintf(stderr,"Warning: Don't know how to handle item %d (%d/%d).\n",
                                      i,ftype[i].tval,ftype[i].sval);
                       break;
            };
         if (outsym)
            {
            fprintf(pref,"# %s\n",&ftext[ftype[i].name]);
            fprintf(pref,"K:%d:%d/%d\n\n",i,ftype[i].k_attr,(signed char)outsym);
            };
         };

      fprintf(pref,"\n");
      free(ftype);
      free(ftext);

      /* Do the unidentified items */
      fprintf(pref,"# TV_AMULET\nU:%d:%d/%d\n\n",TV_AMULET,0,130);
      fprintf(pref,"# TV_RING\nU:%d:%d/%d\n\n"  ,TV_RING  ,0,147);
      fprintf(pref,"# TV_STAFF\nU:%d:%d/%d\n\n" ,TV_STAFF ,0,154);
      fprintf(pref,"# TV_WAND\nU:%d:%d/%d\n\n"  ,TV_WAND  ,0,157);
      fprintf(pref,"# TV_ROD\nU:%d:%d/%d\n\n"   ,TV_ROD   ,0,148);
      fprintf(pref,"# TV_SCROLL\nU:%d:%d/%d\n\n",TV_SCROLL,0,149);
      fprintf(pref,"# TV_POTION\nU:%d:%d/%d\n\n",TV_POTION,0,146);
      fprintf(pref,"# TV_FOOD\nU:%d:%d/%d\n\n"  ,TV_FOOD  ,0,144);
   };

   /* Don't process A_INFO.RAW -- no need */
   /* Don't process E_INFO.RAW -- no need */

   {
      /* Do R_INFO.RAW  Monster Races */
      monster_race *ftype = NULL;
      int i;

      fprintf(stderr,"Processing R_INFO.RAW...\n");
      fprintf(pref,"# Monster Graphic Definitions\n\n");

      sprintf(filename,"%sdata/r_info.raw",basepath);
      f = fopen(filename,"rb");
      fread(&head,sizeof(header),1,f);

      ftype = (monster_race *)malloc(sizeof(monster_race)*head.info_num);
      fread(ftype,head.info_num,sizeof(monster_race),f);

      ftext = (char *)malloc((head.name_size|0x0F)+1);
      fread(ftext,(head.name_size+15)/16,16,f);
      fclose(f);

      for(i=0;i<head.info_num;i++)
         {
         outsym = 0;
         if ((ftype[i].d_char >= 'A') && (ftype[i].d_char <= 'Z'))
            outsym = 165+ftype[i].d_char-'A';   /* Uppercase letters */
         else if ((ftype[i].d_char >= 'a') && (ftype[i].d_char <= 'z'))
            outsym = 225+ftype[i].d_char-'a';   /* Lowercase letters */
         else
            switch (ftype[i].d_char)
               {
               case 0:                  break;  /* Unused */
               case '@':  outsym = 251; break;
               case ',':  outsym = 252; break;
               case '.':  outsym = 217; break;
               case '$':  outsym = 209; break;
               case '!':  outsym = 146; break;
               case '=':  outsym = 147; break;
               case '?':  outsym = 149; break;
               default:   fprintf(stderr,"Warning: Don't know how to handle monster %d (%c)\n",i,ftype[i].d_char);
                          break;
               };

         if (outsym)
            {
            fprintf(pref,"# %s\n",&ftext[ftype[i].name]);
            fprintf(pref,"R:%d:%d/%d\n\n",i,ftype[i].d_attr,(signed char)outsym);
            };
         };

      fprintf(pref,"\n");
      free(ftype);
      free(ftext);
   };


   /* Don't process V_INFO.RAW -- no need */

   fclose(pref);
   fprintf(stderr,"Finished.\n");
};

