#include <stdio.h>   /*  For perror, debug */
#include <fcntl.h>
#include <io.h>
#include <dir.h>
#include <errno.h>
#include <string.h>

extern int errno;

#define SAVE_NAME 			"save.dat"
#define EXPECTED_LENGTH 	34

typedef struct {
	unsigned char unknown_1[6];
	unsigned char lives;
	unsigned char lives_saved;
	unsigned char floor;
	unsigned char grenades;
	unsigned char unknown_2[5];
	unsigned char bombs;
	unsigned char freezers;
	unsigned char sheilds;
	unsigned char barriers;
	unsigned char unknown_3[15];
} save_format;

enum status_names {
	Normal,
	More,
	Max
};

enum status_names request;

void
print_current_directory()
{
	char dirname[100];
    char *test;

	test = getcwd( dirname, 100 );
	if ( test == NULL ) {
		perror( "Where am I???  What's going on???" );
		exit( 17 );
	}

	printf( "Your current directory is \"%s\".\n\n", dirname );

	return;
}

void
no_save_file()
{
	int result;

	result = access( "DGEN.EXE", 00 );
	if ( result == 0 ) {
		printf( "No valid save file found.  You must start a game and save it with <Alt>S\n" );
		printf( "before you run this program.\n\n" );
	}
	else {
		printf( "You need to be in the D/Generation directory before you run this program.\n" );
		print_current_directory();
	}

	return;
}


void
print_saved_game( char *msg, save_format *status )
{
	printf( "%s : %3u lives %3u grenades %3u bombs ",
			msg, status->lives, status->grenades, status->bombs );
	printf( "%3u freezers %3u sheilds %3u barriers\n",
			status->freezers, status->sheilds, status->barriers );

	return;
}

void
bad_command_line( char *argv[] )
{
	printf( "Usage:  %s [ /normal | /more | /max ]\n", argv[0] );
	exit( 077 );
	return;
}

int
main( int argc, char *argv[] )
{
	int save_file;
	int status;
	long length;
	save_format saved_game;

	if ( argc == 1 ) {
		request = Normal;
	}
	else if ( argc > 2 ) {
		bad_command_line( argv );
	}
	else {
		if ( strcmpi( argv[1], "/normal" ) == 0 ) {
			request = Normal;
        }
		else if ( strcmpi( argv[1], "/more" ) == 0 ) {
			request = More;
		}
		else if ( strcmpi( argv[1], "/max" ) == 0 ) {
			request = Max;
		}
		else {
			bad_command_line( argv );
        }
	}

	save_file = _open( SAVE_NAME, O_RDWR | O_BINARY );
	if ( save_file == -1 ) {
		if ( errno == ENOENT ) {
			no_save_file();
			exit( 01 );
		}
		else {
			perror( "Problems opening file \"save.dat\"" );
			exit( 02 );
		}
	}

	length = filelength( save_file );
	if ( length != EXPECTED_LENGTH ) {
		no_save_file();
		exit( 03 );
	}

	status = _read( save_file, &saved_game, EXPECTED_LENGTH );
	if ( status != EXPECTED_LENGTH ) {
		perror( "Problems reading from \"save.dat\"" );
		exit( 04 );
	}

	print_saved_game( "OLD", &saved_game );

	switch ( request ) {
	case Normal:
		if ( saved_game.lives < 30 )    saved_game.lives    += 1;
		if ( saved_game.grenades < 39 ) saved_game.grenades += 2;
		if ( saved_game.bombs < 4 )     saved_game.bombs    += 1;
		if ( saved_game.freezers < 3 )  saved_game.freezers += 1;
		if ( saved_game.sheilds < 3 )   saved_game.sheilds  += 1;
		if ( saved_game.barriers < 3 )  saved_game.barriers += 1;
		break;

	case More:
		if ( saved_game.lives < 30 )    saved_game.lives    += 1;
		if ( saved_game.grenades < 79 ) saved_game.grenades += 2;
		if ( saved_game.bombs < 9 )     saved_game.bombs    += 1;
		if ( saved_game.freezers < 9 )  saved_game.freezers += 1;
		if ( saved_game.sheilds < 9 )   saved_game.sheilds  += 1;
		if ( saved_game.barriers < 9 )  saved_game.barriers += 1;
		break;

	case Max:
		if ( saved_game.lives < 80 )    saved_game.lives    = 80;
		if ( saved_game.grenades < 80 ) saved_game.grenades = 80;
		if ( saved_game.bombs < 9 )     saved_game.bombs    =  9;
		if ( saved_game.freezers < 9 )  saved_game.freezers =  9;
		if ( saved_game.sheilds < 9 )   saved_game.sheilds  =  9;
		if ( saved_game.barriers < 9 )  saved_game.barriers =  9;
		break;

	}

	print_saved_game( "NEW", &saved_game );

	status = lseek( save_file, 0L, SEEK_SET );
	if ( status == -1 ) {
		perror( "Problems rewinding file \"save.dat\"" );
		exit( 05 );
	}

	status = _write( save_file, &saved_game, EXPECTED_LENGTH );
	if ( status != EXPECTED_LENGTH ) {
		perror( "Problems writing to \"save.dat\"" );
		exit( 06 );
	}

	(void) _close( save_file );

	return 0;
}