/* '='='=' '@' '='='='='='='='='=' '@' '='='='='='='='='=' '@' '='='='| */
/* ='='=' '@'@' '='='='='='='='=' '@'@' '='='='='='='='=' '@'@' '='='=| */
/* '='=' '@':'@' '='='='='='='=' '@':'@' '='='='='='='=' '@':'@' '='='| */
/* ='=' '@':':'@' '='='='='='=' '@':':'@' '='='='='='=' '@':':'@' '='=| */
/* '=' '@':':':'@' '='='='='=' '@':':':'@' '='='='='=' '@':':':'@' '='| */
/* =' '@':':':':'@' '='='='=' '@':':':':'@' '='='='=' '@':':':':'@' '=| */
/* ' '@':'                                                       '@' '| */
/*  '@'         3rd Year Project - ROY SCHESTOWITZ - 2002          @' | */
/* '@                                                               @'| */
/* @':':':':':':':':'@' ' '@':':':':':':':':'@' ' '@':':':':':':':':'@| */
/* ':':':':':':':':':'@' '@':':':':':':':':':'@' '@':':':':':':':':':'| */
/* :':':':':':':':':':'@'@':':':':':':':':':':'@'@':':':':':':':':':':| */
/* ':':':': : :':':':':'@':':':':': : :':':':':'@':':':':': : :':':':'| */
/*  -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
/*              Name:           loaders.c                               */
/*              Version:        0.6.6                                   */
/*              Date:           12/2/2003                               */
/*                                                                      */
/*              Misc. functions that load data                          */
/*                                                                      */
/*  -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */

#include "loaders.h"
#include "misc.h"


/******************************************************************************/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/* glmReadPPM - loads a PPM file                                              */
/* On entry: *filename is a pointer to the string holding a filename to open  */
/*           *width is a pointer to some address where image width will be    */
/*                      stored                                                */
/*           *height is a pointer to some address where image height will be  */
/*                      stored                                                */
/* On exit:  width and height are pointers to image dimensions                */
/*                                                                            */
/*                                                                            */


GLubyte *
glmReadPPM ( char *filename, int *width, int *height )
{
  FILE *fp;			/* file pointer to be used for filename */
  int i,			/* index variable                       */

    w,				/* returned width                       */

    h,				/* returned height                      */

    d;				/* holds some more data scanned from file */
  unsigned char *image;		/* the image itself stored in bytes       */
  char head[70];		/* max line <= 70 in PPM (per spec).      */

  fp = fopen ( filename, "rb" );	/* open file                             */
  if ( !fp )			/* if can't open file                    */
    {
      perror ( filename );
      return NULL;
    }

  /* grab first two chars of the file and make sure that it has the
     correct magic cookie for a raw PPM file. */
  fgets ( head, 70, fp );
  if ( strncmp ( head, "P6", 2 ) )
    {
      fprintf ( stderr, "%s: Not a raw PPM file\n", filename );
      return NULL;
    }

  /* grab the three elements in the header (width, height, maxval). */
  i = 0;
  while ( i < 3 )
    {
      fgets ( head, 70, fp );
      if ( head[0] == '#' )	/* skip comments. */
	continue;
      if ( i == 0 )
	i += sscanf ( head, "%d %d %d", &w, &h, &d );
      else if ( i == 1 )
	i += sscanf ( head, "%d %d", &h, &d );
      else if ( i == 2 )
	i += sscanf ( head, "%d", &d );
    }

  /* grab all the image data in one fell swoop. */
  image = ( unsigned char * ) malloc ( sizeof ( unsigned char ) * w * h * 3 );
  fread ( image, sizeof ( unsigned char ), w * h * 3, fp );
  fclose ( fp );		/* close the file */

  *width = w;			/* update the width            */
  *height = h;			/* and the height              */
  return image;			/* return opinter to the image */
}


/*                                                                            */
/*                                                                            */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/******************************************************************************/




/******************************************************************************/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/* save_game - saves a game of Othello master on a file                       */
/* On entry: filename point to filename string                                */
/* returns: true if save operation was successful, false otherwise            */
/*                                                                            */
/*                                                                            */

int
save_game_to_filename ( char *filename )
{
  FILE *saved_game_file;	/* file pointer to the saved game file */
  int i,
    j;
  int game_save_header = GAME_SAVE_HEADER;	/* local varaibles to hold the global */

  /* definitions                        */
  int game_save_version = GAME_SAVE_VERSION;

  saved_game_file = fopen ( filename, "w" );	/* open the file for writing  */
  if ( saved_game_file == NULL )	/* if unable to open the file */
    {
      if ( VERBOSE )
	printf ( "Could not create the file %s.\n", filename );
      return FALSE;
    }
  /* write misc. values that together retain some state */
  fwrite ( &game_save_header, 4, 1, saved_game_file );
  fwrite ( &game_save_version, 4, 1, saved_game_file );
  fwrite ( &difficulty, 4, 1, saved_game_file );
  fwrite ( &movecount, 4, 1, saved_game_file );
  fwrite ( &turn, 4, 1, saved_game_file );
  fwrite ( &playing_against_cpu, 4, 1, saved_game_file );
  fwrite ( &stat_mode_difficulty, 4, 1, saved_game_file );
  fwrite ( &gather_statistics, 4, 1, saved_game_file );
  fwrite ( &game_on, 4, 1, saved_game_file );
  fwrite ( &non_determinism, 4, 1, saved_game_file );

  for ( i = 0; i < 10; i++ )	/* save board state */
    for ( j = 0; j < 10; j++ )
      fwrite ( &board.slot[i][j], 4, 1, saved_game_file );

  fclose ( saved_game_file );	/* close the file */
  if ( VERBOSE )
    printf ( "Game saved as %s\n", filename );
  return TRUE;


}

/*                                                                            */
/*                                                                            */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/******************************************************************************/




/******************************************************************************/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/* save_game - saves a game of Othello master on a slot                       */
/* On entry: slot number                                                      */
/* returns: true if save operation was successful, false otherwise            */
/*                                                                            */
/*                                                                            */

int
save_game ( int slot_number )
{
  char file_to_build[] =
    { 'g', 'a', 'm', 'e', '0', '0', '0', 'x', '.', 's', 'a', 'v', '\0' };
  /* the template of the file to be built */
  char slot_number_as_char;	/* the character of the number holding the slot */

  if ( !( slot_number >= 0 && slot_number <= 9 ) )	/* if slot number is invalid */
    {
      if ( VERBOSE )
	printf ( "Invalid slot number is requested to be saved onto.\n" );
      return FALSE;
    }

  slot_number_as_char = slot_number + 0x30;	// conversion by ASCII table offset
  file_to_build[7] = slot_number_as_char;	// completes the name of the dest. file
  return save_game_to_filename ( file_to_build );
}


/*                                                                            */
/*                                                                            */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/******************************************************************************/





/******************************************************************************/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/* load_game - load a game of Othello master from a file given a slot number  */
/* On entry: slot number                                                      */
/* returns: true if save operation was successful, false otherwise            */
/*                                                                            */
/*                                                                            */


int
load_game ( int slot_number )
{
  char file_to_load[] =
    { 'g', 'a', 'm', 'e', '0', '0', '0', 'x', '.', 's', 'a', 'v', '\0' };
  /* template for the file to be loaded */
  char slot_number_as_char;

  /* holds the number of the slot as a character */
  if ( !( slot_number >= 0 && slot_number <= 9 ) )	/* check if the number is within range */
    {

      if ( VERBOSE )
	printf ( "Invalid slot number is requested to be loaded.\n" );
      return FALSE;
    }
  slot_number_as_char = slot_number + 0x30;	// conversion by ASCII table offset
  file_to_load[7] = slot_number_as_char;	// modify the name of the dest. file

  return load_game_from_filename ( file_to_load );	// return status from file handling routine
}


/*                                                                            */
/*                                                                            */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/******************************************************************************/



/******************************************************************************/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/* load_game_from_filename - load a game of Othello master from a file        */
/* given a filename                                                           */
/* On entry: filename is a pointer to the characters of the file to open      */
/* returns: true if save operation was successful, false otherwise            */
/*                                                                            */
/*                                                                            */


int
load_game_from_filename ( char *filename )
{
  FILE *loaded_game_file;	/* the loaded file pointer */
  int data[LOAD_BLK_LENGTH];	/* data buffer             */
  unsigned int length_read;	/* length of file read     */

  loaded_game_file = fopen ( filename, "r" );	/* open the file for reading */
  if ( loaded_game_file == NULL )	/* if unable to open it      */
    {
      if ( VERBOSE )
	printf ( "Could not open the file %s.\n", filename );
      return FALSE;
    }
  length_read = fread ( data, 4, LOAD_BLK_LENGTH, loaded_game_file );
  /* read data from file, a word per slot and save length onto leangth_read */
  if ( VERBOSE )
    printf ( "length of file %s: %d bytes\n", filename, length_read );
  if ( length_read != SAVED_FILE_SIZE )	/* if the file is of wrong length/size */
    {
      if ( VERBOSE )
	printf ( "Loaded file %s is of invalid size.\n", filename );
      return FALSE;
    }
  else				/* if the file was the right length */
    {
      int i,
        j;			/* to index the board positions */

      if ( data[0] != GAME_SAVE_HEADER )	/* check file header */
	{
	  if ( VERBOSE )
	    printf ( "%s is not an Othello Master file.\n", filename );
	  return FALSE;
	}
      if ( data[1] != GAME_SAVE_VERSION )	/* check saved agme version */
	{
	  if ( VERBOSE )
	    printf ( "%s complies with an older version of Othello Master.\n",
		     filename );
	  return FALSE;
	}
      difficulty = data[2];	/* load global variables one by one */
      movecount = data[3];
      turn = data[4];
      playing_against_cpu = data[5];
      stat_mode_difficulty = data[6];
      gather_statistics = data[7];
      game_on = data[8];
      non_determinism = data[9];
      for ( i = 0; i < 10; i++ )	/* get board state */
	for ( j = 0; j < 10; j++ )
	  board.slot[i][j] = data[10 * i + j + 10];	/* spread across 100 slots */
      if ( VERBOSE )
	printf ( "The file %s was loaded successfully.\n", filename );
    }
  fclose ( loaded_game_file );
  calculatescore (  );		/* check score    */
  calculate_mobility (  );	/* check mobility */
  check_deadlock (  );		/* given the new mobility check for deadlocks  */
  return TRUE;
}



/*                                                                            */
/*                                                                            */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/******************************************************************************/



/*                                                                      */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
/*                     end of loaders.c                                 */
/************************************************************************/

