/*-
 * Copyright (c) 2000
 * Tatsuya Kudoh(CDR/TK),ROYALPANDA.    All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */

#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<sys/bios.h>
#include"jump.h"

static record_t Record[10];
static int Num_record;


static void file_error( char far *msg )
{
	int i;

	i = 0;
	do{
		if( i % 8 == 0 ){
			if( i / 8 ){
				DISP_put_str(2,17,msg);
				DISP_put_str(22,17,"[Push A]");
			}else{
				screen_fill_char(1,1,17,30,1,14<<9|32);
			}
		}
		i = (i+1) & 15;
		GAME_scroll_back();
	}while( !(KEY_read(1) & K_A) );
	screen_fill_char(1,4,17,28,1,14<<9|32);
}


static show_record( int i, int show )
{
	char buf[32];

	if( show ){
		sprintf(buf,"%2d %5d %16ls",
				i+1,Record[i].score,(char far*)Record[i].name);
		DISP_put_str(5,i+4,buf);
	}else{
		screen_fill_char(1,5,i+4,25,1,14<<9|32);
	}
}


void RECORD_show( int emph )
{
	int i;

	DISP_clear();

	DISP_put_str(3,2,"Rank Floor  Name");
	DISP_put_str(3,3,"---- ----- ----------------");
	for( i = 0 ; i < Num_record ; i++ )
		show_record(i,1);

	i = 0;
	for(;;){
		if( emph >= 0 ){
			i = (i+1) % 30;
			if( i % 10 == 0 )
				show_record(emph,i/10);
		}

		if( KEY_read(1) & K_A )
			break;

		GAME_scroll_back();
	}
}


static int read_record( int n, int fd )
{
	int i;
	int score;
	unsigned sum;
	unsigned char buf[20];

	if( read(fd,buf,20) < 20 ){
		file_error("File reading error");
		return -1;
	}

	sum = 0;
	for( i = 0 ; i < 18 ; i++ )
		sum += buf[i];

	if( sum >> 8 != buf[18] || (sum&255) != buf[19] ){
		file_error("Checksum error");
		return -1;
	}

	score = (int)buf[16] << 8 | (int)buf[17];
	if( score == 0 )
		return 0;

	Record[n].score = score;
	memcpy((void far*)Record[n].name,(void far*)buf,16);

	return 1;
}


static int write_record( int n, int fd )
{
	int i;
	unsigned char buf[20];
	unsigned sum;

	memcpy((void far*)buf,(void far*)Record[n].name,16);
	buf[16] = Record[n].score >> 8;
	buf[17] = Record[n].score & 255;
	sum = 0;
	for( i = 0 ; i < 18 ; i++ )
		sum += buf[i];
	buf[18] = sum >> 8;
	buf[19] = sum & 255;
		
	if( write(fd,buf,20) < 20 ){
		file_error("File writing error");
		return -1;
	}

	return 0;
}

static int write_terminator( int fd )
{
	unsigned char buf[20];

	memset((void far*)buf,0,20);
	if( write(fd,buf,20) < 20 ){
		file_error("File writing error");
		return -1;
	}

	return 0;
}



void RECORD_init( void )
{
	int fd;

	Num_record = 0;

	fd = open(SAVEFILE,FMODE_R,0);
	if( fd < 0 )
		return;

	while( Num_record < 10 ){
		if( read_record(Num_record,fd) != 1 )
			break;
		Num_record++;
	}
	close(fd);
}


int RECORD_save( void )
{
	int fd;
	int i;

	if( Num_record == 0 )
		return 0;

#if 0
	if( (fd = creat(SAVEFILE,6,2)) != E_FS_SUCCESS ){
		file_error("File creating error");
		return -1;
	}
#endif

	fd = open(SAVEFILE,FMODE_W,0);
	if( fd < 0 ){
		file_error("File writing error");
		return -1;
	}
	for( i = 0 ; i < Num_record ; i++ ){
		if( write_record(i,fd) < 0 ){
			close(fd);
			return -1;
		}
	}
	if( write_terminator(fd) < 0 ){
		close(fd);
		return -1;
	}
	close(fd);
	fs_setinfo(SAVEFILE,SAVEINFO);
	return 0;
}


int RECORD_get_lowest_score( void )
{
	if( Num_record < 10 )
		return 0;
	else
		return Record[9].score;
}

int RECORD_get_hiscore( void )
{
	if( Num_record )
		return Record[0].score;
	else
		return 0;
}


int RECORD_add( int score, char far *name )
{
	int i;

	if( Num_record == 10 ){
		i = 9;
	}else{
		i = Num_record;
		Num_record++;
	}

	while( i > 0 && score > Record[i-1].score ){
		memcpy((void far*)(Record+i),(void far*)(Record+i-1),
					sizeof(record_t));
		i--;
	}
	Record[i].score = score;
	memcpy((void far*)&Record[i].name,(void far*)name,16);
	return i;
}
