#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include "defines.h"
#include "struct.h"
#include "globals.h"
#include "protos.h"

static char *mission_high_name(mission *mp)
{
  static char buffer[256];
  char *dir;

  if(!(dir = getenv("RAWK_HIGHSCOREDIR"))) dir = "./.data/rawks/High";
  strcpy(buffer,dir); /* Construct name for high score file */
  strcat(buffer,"/");
  strcat(buffer,amh_basename(mp->name));

  return buffer;
}

static int read_mission_high_array(mission *mp)
{
  FILE *f;
  unsigned int t;

  f = fopen(mission_high_name(mp),"r");
  if(!f) return -1;

  /* Check to see if the mission file has changed */
  mp->miss_checksum = get_mission_checksum(mp->name);
  mp->high_checksum = get_mission_checksum(mission_high_name(mp));

  mp->high = (mission_high *)
	     realloc(mp->high,sizeof(mission_high)*mp->numlevels);

  if(1!=fread(&t,sizeof(unsigned int),1,f) || (t != mp->high_checksum)) {
    fclose(f);
    return -1;
  }
  if(1!=fread(&t,sizeof(unsigned int),1,f) || (t != mp->miss_checksum)) {
    fclose(f);
    return -1;
  }
  if(mp->numlevels != fread(mp->high,sizeof(mission_high),mp->numlevels,f)) {
    fclose(f);
    return -1;
  }
  if(1 != fread(&(mp->topscore),sizeof(unsigned int),1,f)) {
    fclose(f);
    return -1;
  }
  if(MAX_SCORENAME != fread(&(mp->topname),sizeof(char),MAX_SCORENAME,f)) {
    fclose(f);
    return -1;
  }
  return 0;
}

static void write_mission_high_(mission *mp)
{
  FILE *f;
  f = fopen(mission_high_name(mp),"w");
  if(!f) return;

  if((1!=fwrite(&(mp->high_checksum),sizeof(unsigned int),1,f)) ||
     (1!=fwrite(&(mp->miss_checksum),sizeof(unsigned int),1,f)) ||
  (mp->numlevels!= fwrite((mp->high),sizeof(mission_high),mp->numlevels,f)) ||
      (1 != fwrite(&(mp->topscore),sizeof(unsigned int),1,f)) ||
      (MAX_SCORENAME != fwrite(&(mp->topname), sizeof(char),MAX_SCORENAME,f)) )
    printf("NOTICE: Could not save high score %s\n",mission_high_name(mp));

  fclose(f);
}

void write_mission_high(mission *mp)
{
  struct stat filestat;
  FILE *f;

  if(stat(amh_dirname(mission_high_name(mp)),&filestat) == -1) {
    printf("Error writing high score:\n");
    printf("High score directory, %s, does not exist\n",
      amh_dirname(mission_high_name(mp)));
    return;
  } else if(!(filestat.st_mode & 0111)) {
    printf("Error, high score dir, %s, has wrong permissions\n",
	   mission_high_name(mp));
  }
  mp->miss_checksum = get_mission_checksum(mp->name);

  write_mission_high_(mp);

  mp->high_checksum = get_mission_checksum(mission_high_name(mp));
/*   printf("Writing mission with high checksum %u\n",mp->high_checksum); */

  /* Write again with correct checksum */
  write_mission_high_(mp);
}

static void erase_mission_high(mission *mp)
{
/*   printf("Erasing mission\n"); */
  mp->high = realloc(mp->high,sizeof(mission_high)*mp->numlevels);
  bzero(mp->high,sizeof(mission_high)*mp->numlevels);
  mp->topscore = 0;
  write_mission_high(mp);
}

/* For the said mission, return it's high score table , creating anew
   if the level has been rewritten since last write or if not exists */
void read_mission_high(mission *mp)
{
  struct stat filestat;

  if(stat(amh_dirname(mission_high_name(mp)),&filestat) == -1) {
    printf("Error reading high score:\n");
  } else if(!(filestat.st_mode & 0111)) {
    printf("Error, direcotry %s does not have permissions set properly\n",
	   mission_high_name(mp));
  }
  if(stat(mission_high_name(mp),&filestat) == -1) {
    printf("Could not stat mission file\n");
    erase_mission_high(mp);
  } else if(read_mission_high_array(mp)) {
/*     printf("Error in checksum for mission\n"); */
    erase_mission_high(mp);
  }
}
