#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

/* main header file */
#include "mud.h"

void save_pfile           ( D_MOBILE *dMob );
void save_profile         ( D_MOBILE *dMob );

void save_player(D_MOBILE *dMob)
{
  if (!dMob) return;

  save_pfile(dMob);      /* saves the actual player data */
  save_profile(dMob);    /* saves the players profile    */
}

void save_pfile(D_MOBILE *dMob)
{
    char pName[20];
    char pfile[256];
    FILE *fp;
    int size, i;

    pName[0] = toupper(dMob->name[0]);
    size = strlen(dMob->name);
    for (i = 1; i < size; i++)
        pName[i] = tolower(dMob->name[i]);
    pName[i] = '\0';

    /* open the pfile so we can write to it */
    sprintf(pfile, "../players/%s.pfile", pName);
    if ((fp = fopen(pfile, "w")) == NULL)
    {
        bug("Unable to write to %s's pfile", dMob->name);
        return;
    }

    /* dump the players data into the file */
    fprintf(fp, "Name               %s~\n", dMob->name);
    fprintf(fp, "Password           %s~\n", dMob->password);
    fprintf(fp, "Title              %s~\n", dMob->title);
    fprintf(fp, "Level              %d\n",  dMob->level);
    fprintf(fp, "PLevel             %d\n",  dMob->p_level);
    fprintf(fp, "Age                %d\n",  dMob->age);
    fprintf(fp, "Experience         %d\n",  dMob->xp);
    fprintf(fp, "HpMaStEg           %d %d    %d %d    %d %d    %d %d\n",
        dMob->stats[0], dMob->stats[1], dMob->stats[2], dMob->stats[3], dMob->stats[4],
        dMob->stats[5], dMob->stats[6], dMob->stats[7]);
    fprintf(fp, "Attribs            %d %d %d %d %d %d %d %d\n",
        dMob->attribs[0], dMob->attribs[1], dMob->attribs[2], dMob->attribs[3],
        dMob->attribs[4], dMob->attribs[5], dMob->attribs[6], dMob->attribs[7]);
    fprintf(fp, "Attribs_max        %d %d %d %d %d %d %d %d\n",
        dMob->attribs_max[0], dMob->attribs_max[1], dMob->attribs_max[2], dMob->attribs_max[3],
        dMob->attribs_max[4], dMob->attribs_max[5], dMob->attribs_max[6], dMob->attribs_max[7]);
    fprintf(fp, "Race               %d\n",  dMob->race);
    fprintf(fp, "Class              %d\n",  dMob->class);
    fprintf(fp, "Locationx          %d\n",  dMob->x);
    fprintf(fp, "Locationy          %d\n",  dMob->y);
    fprintf(fp, "Locationz          %d\n",  dMob->z);
    fprintf(fp, "ChunkX             %d\n",  dMob->i_x);
    fprintf(fp, "ChunkY             %d\n",  dMob->i_y);
    fprintf(fp, "ImmFlags           %ld\n", dMob->immortal_flags);
    fprintf(fp, "PlrFlags           %ld\n", dMob->player_flags);
    fprintf(fp, "ViewX              %d\n",  dMob->view_x);
    fprintf(fp, "ViewY              %d\n",  dMob->view_y);

    /* Time to save the Skills/talents/Knowledges */
    for (i = 0; i < MAX_TALENTS; i++)
    {
        if (talent_table[i].name != NULL && dMob->talents[i] != 0)
        {
            fprintf(fp, "Talent  %d %s\n", dMob->talents[i], talent_table[i].name);
        }
    }
    i = 0;
    /* Save Skills */
    for (i = 0; i < MAX_SKILLS; i++)
    {
        if (skill_table[i].name != NULL && dMob->skills[i] != 0)
        {
            fprintf(fp, "Skill   %d %s\n", dMob->skills[i], skill_table[i].name);
        }
    }
    i = 0;
    /* Save Knowledges */
    for (i = 0; i < MAX_KNOW; i++)
    {
        if (knowledge_table[i].name != NULL && dMob->knowledge[i] != 0)
        {
            fprintf(fp, "Knowle  %d %s\n", dMob->knowledge[i], knowledge_table[i].name);
        }
    }
    
    /* terminate the file */
    fprintf(fp, "%s\n", FILE_TERMINATOR);
    fclose(fp);
}

D_MOBILE *load_player(char *player)
{
    FILE *fp;
    D_MOBILE *dMob = NULL;
    char pfile[256];
    char pName[20];
    char *word;
    bool done = FALSE, found;
    int i, size;

    pName[0] = toupper(player[0]);
    size = strlen(player);
    for (i = 1; i < size; i++)
        pName[i] = tolower(player[i]);
    pName[i] = '\0';

    /* open the pfile so we can write to it */
    sprintf(pfile, "../players/%s.pfile", pName);     
    if ((fp = fopen(pfile, "r")) == NULL)
        return NULL;

    /* create new mobile data */
    if (dmobile_free == NULL)
    {
        if ((dMob = malloc(sizeof(*dMob))) == NULL)
        {
            bug("Load_player: Cannot allocate memory.");
            abort();
        }
    }
    else
    {
        dMob         = dmobile_free;
        dmobile_free = dmobile_free->next;
    }
    clear_mobile(dMob);

        /* load data */
        word = fread_word(fp);
        while (!done)
        {
            found = FALSE;
            switch (word[0])
            {
                case 'A':
                    IREAD( "Age",           dMob->age                   );
                    if (compares(word, "Attribs"))
                    {
                        dMob->attribs[0] = fread_number(fp);
                        dMob->attribs[1] = fread_number(fp);
                        dMob->attribs[2] = fread_number(fp);
                        dMob->attribs[3] = fread_number(fp);
                        dMob->attribs[4] = fread_number(fp);
                        dMob->attribs[5] = fread_number(fp);
                        dMob->attribs[6] = fread_number(fp);
                        dMob->attribs[7] = fread_number(fp);
                        found = TRUE;
                        break;
                    }
                    if (compares(word, "Attribs_max"))
                    {
                        dMob->attribs_max[0] = fread_number(fp);
                        dMob->attribs_max[1] = fread_number(fp);
                        dMob->attribs_max[2] = fread_number(fp);
                        dMob->attribs_max[3] = fread_number(fp);
                        dMob->attribs_max[4] = fread_number(fp);
                        dMob->attribs_max[5] = fread_number(fp);
                        dMob->attribs_max[6] = fread_number(fp);
                        dMob->attribs_max[7] = fread_number(fp);
                        found = TRUE;
                        break;
                    }
                    break;
                case 'C':
                    IREAD( "ChunkX",        dMob->i_x                   );
                    IREAD( "ChunkY",        dMob->i_y                   );
                    IREAD( "Class",         dMob->class                 );
                    break;
                case 'E':
                    EREAD( "EOF"                                        );
                    IREAD( "Experience",    dMob->xp                    );
                    break;
                case 'H':
                    VREAD( "HpMaStEg",      dMob                        );
                    break;
                case 'I':
                    IREAD( "ImmFlags",      dMob->immortal_flags        );
                    break;
                case 'L':
                    IREAD( "Level",         dMob->level                 );
                    IREAD( "Locationx",     dMob->x                     );
                    IREAD( "Locationy",     dMob->y                     );
                    IREAD( "Locationz",     dMob->z                     );
                    break;
                case 'K':
                    KREAD( "Knowle",        dMob                        );
                    break;
                case 'N':
                    SREAD( "Name",          dMob->name                  );
                    break;
                case 'P':
                    SREAD( "Password",      dMob->password              );
                    IREAD( "PlrFlags",      dMob->player_flags          );
                    IREAD( "PLevel",        dMob->p_level               );
                    break;
                case 'R':
                    IREAD( "Race",          dMob->race                  );
                    break;
                case 'S':
                    LREAD( "Skill",         dMob                        );
                    break;
                case 'T':
                    SREAD( "Title",         dMob->title                 );
                    TREAD( "Talent",        dMob                        );
                    break;
                case 'V':
                    IREAD( "ViewX",         dMob->view_x                );
                    IREAD( "ViewY",         dMob->view_y                );
                    break;
            }
        if (!found)
        {
            bug("Load_player: unexpected '%s' in %s's pfile.", word, player);
            free_mobile(dMob);
        }

        /* read one more */
        if (!done) word = fread_word(fp);
    }

    fclose(fp);
    return dMob;
}

/*
 * This function loads a players profile, and stores
 * it in a mobile_data... DO NOT USE THIS DATA FOR
 * ANYTHING BUT CHECKING PASSWORDS OR SIMILAR.
 */
D_MOBILE *load_profile(char *player)
{
  FILE *fp;
  D_MOBILE *dMob = NULL;
  char pfile[256];
  char pName[20];
  char *word;
  bool done = FALSE, found;
  int i, size;

  pName[0] = toupper(player[0]);
  size = strlen(player);
  for (i = 1; i < size; i++)
    pName[i] = tolower(player[i]);
  pName[i] = '\0';

  /* open the pfile so we can write to it */
  sprintf(pfile, "../players/%s.profile", pName);
  if ((fp = fopen(pfile, "r")) == NULL)
    return NULL;

  /* create new mobile data */
  if (dmobile_free == NULL)
  {
    if ((dMob = malloc(sizeof(*dMob))) == NULL)
    {
      bug("Load_profile: Cannot allocate memory.");
      abort();
    }
  }
  else
  {
    dMob         = dmobile_free;
    dmobile_free = dmobile_free->next;
  }
  clear_mobile(dMob);

  /* load data */
  word = fread_word(fp);
  while (!done)
  {
    found = FALSE;
    switch (word[0])
    {
      case 'E':
        if (compares(word, "EOF")) {done = TRUE; found = TRUE; break;}
        break;
      case 'N':
        SREAD( "Name",      dMob->name      );
        break;
      case 'P':
        SREAD( "Password",  dMob->password  );
        break;
    }
    if (!found)
    {
      bug("Load_player: unexpected '%s' in %s's pfile.", word, player);
      free_mobile(dMob);
      return NULL;
    }

    /* read one more */
    if (!done) word = fread_word(fp);
  }

  fclose(fp);
  return dMob;
}


/*
 * This file stores only data vital to load
 * the character, and check for things like
 * password and other such data.
 */
void save_profile(D_MOBILE *dMob)
{
  char pfile[256];
  char pName[20];
  FILE *fp;
  int size, i;
  
  pName[0] = toupper(dMob->name[0]);
  size = strlen(dMob->name);
  for (i = 1; i < size; i++)
    pName[i] = tolower(dMob->name[i]);
  pName[i] = '\0';
  
  /* open the pfile so we can write to it */
  sprintf(pfile, "../players/%s.profile", pName);
  if ((fp = fopen(pfile, "w")) == NULL)
  {
    bug("Unable to write to %s's pfile", dMob->name);
    return;
  }

  /* dump the players data into the file */
  fprintf(fp, "Name           %s~\n", dMob->name);
  fprintf(fp, "Password       %s~\n", dMob->password);

  /* terminate the file */
  fprintf(fp, "%s\n", FILE_TERMINATOR);
  fclose(fp);
}