
#include <stdio.h>
#include "quiz.h"

#define WORDS_FILE		"words.thai"
#define SENTENCE_FILE	"sentences.thai"

static char words_file[ 30 ];
static char sentence_file[ 30 ];


extern FILE *fopen ();
extern char *malloc ();


int
load_phrases ()
{
	if ( find ( WORDS_FILE , words_file )
	&&   find ( SENTENCE_FILE , sentence_file )
	&&   load ( words_file , &word_head , "word" )
	&&   load ( sentence_file , &sentence_head , "sentence" ) )
		return ( TRUE );
	return ( FALSE );
}


static int
load ( filename , head , desc )
char *filename;
struct thai_phrase *head;
char *desc;
{
	FILE *fp;
	int loaded;
	int num_loaded;
	int status;

	num_loaded = 0;
	fp = fopen ( filename , "r" );
	if ( fp == NULL ) {
		printf ( "Failed to open '%s'\n" , filename );
		return ( FALSE );
	}
	loaded = TRUE;
	while ( ( status = read_phrase ( fp , &scan ) ) == 1 ) {
		if ( !add_phrase ( head , &scan ) ) {
			loaded = FALSE;
			break;
		}
		num_loaded++;
	}
	if ( status < 0 ) {
		loaded = FALSE;
		printf ( "Read error in '%s', near line number %d\n" ,
			filename , num_loaded * 4 );
	}
	fclose ( fp );
	printf ( "Loaded %d %ss\n" , num_loaded , desc );
	return ( loaded );
}


unload_phrases ()
{
	unload ( words_file , &word_head , "word" );
	unload ( sentence_file , &sentence_head , "sentence" );
}


static
unload ( filename , head , desc )
char *filename;
struct thai_phrase *head;
char *desc;
{
	FILE *fp;
	struct thai_phrase *p;
	int num_saved;

	if ( file_changed ) {
		fp = fopen ( filename , "w" );
		if ( fp == NULL )
			return;
		num_saved = 0;
		for ( p = head->next; p != NULL; p = p->next ) {
			write_phrase ( fp , p );
			num_saved++;
		}
		printf ( "Saved %d %ss\n" , num_saved , desc );
		fclose ( fp );
	}
	/* not needed if C compiler auto-frees all malloc()s
	while ( head->next != NULL )
		del_phrase ( head , head->next );
	*/
}


int
add_phrase ( head , phrase )
struct thai_phrase *head , *phrase;
{
	struct thai_phrase *p;

	p = (struct thai_phrase *) malloc ( sizeof ( struct thai_phrase ) );
	if ( p == NULL )
		return ( FALSE );
	p->thai = strsave ( phrase->thai );
	p->phonetic = strsave ( phrase->phonetic );
	p->english = strsave ( phrase->english );
	if ( p->thai == NULL  ||  p->phonetic == NULL  ||  p->english == NULL )
		return ( FALSE );
	p->right = 0;
	p->wrong = 0;
	p->prev = head;
	p->next = head->next;
	if ( head->next != NULL )
		head->next->prev = p;
	head->next = p;
	return ( TRUE );
}


del_phrase ( head , phrase )
struct thai_phrase *head , *phrase;
{
	struct thai_phrase *p;

	for ( p = head->next; p != NULL; p = p->next ) {
		if ( p == phrase ) {
			if ( p->next != NULL )
				p->next->prev = p->prev;
			if ( p->prev != NULL )
				p->prev->next = p->next;
			free ( p->thai );
			free ( p->phonetic );
			free ( p->english );
			free ( p );
			return;
		}
	}
}


replace_phrase ( old , new )
struct thai_phrase *old , *new;
{
	if ( new->thai != NULL  &&  new->thai[0] != '\0' ) {
		if ( old->thai != NULL )
			free ( old->thai );
		old->thai = strsave ( new->thai );
	}
	if ( new->phonetic != NULL  &&  new->phonetic[0] != '\0' ) {
		if ( old->phonetic != NULL )
			free ( old->phonetic );
		old->phonetic = strsave ( new->phonetic );
	}
	if ( new->english != NULL  &&  new->english[0] != '\0' ) {
		if ( old->english != NULL )
			free ( old->english );
		old->english = strsave ( new->english );
	}
}


/* 1 means OK, 0 means EOF, -1 means error */
static int
read_phrase ( fp , phrase )
FILE *fp;
struct thai_phrase *phrase;
{
	char buf[ MAX_STRING ];

	if ( fgets ( phrase->thai , MAX_STRING , fp ) == NULL )
		return ( 0 );		/* EOF */
	rmlast ( phrase->thai );
	if ( fgets ( phrase->phonetic , MAX_STRING , fp ) == NULL )
		return ( -1 );		/* unexpected EOF */
	rmlast ( phrase->phonetic );
	if ( fgets ( phrase->english , MAX_STRING , fp ) == NULL )
		return ( -1 );		/* unexpected EOF */
	rmlast ( phrase->english );
	if ( fgets ( buf , MAX_STRING , fp ) == NULL )
		return ( -1 );		/* unexpected EOF */
	if ( sscanf ( buf , "%d %d" , &phrase->right , &phrase->wrong ) != 2 )
		return ( -1 );		/* illegal syntax */
	return ( 1 );			/* OK */
}


static
rmlast ( str )
char *str;
{
	int len;

	len = strlen ( str );
	if ( len < 1 )
		return;
	if ( str[ len - 1 ] == '\n' )
		str[ len - 1 ] = '\0';
}


static
write_phrase ( fp , phrase )
FILE *fp;
struct thai_phrase *phrase;
{
	fprintf ( fp , "%s\n%s\n%s\n%d %d\n" ,
		phrase->thai , phrase->phonetic , phrase->english ,
		phrase->right , phrase->wrong );
}


static
find ( filename , path )
char *filename , *path;
{
	/* try the current directory */

	strcpy ( path , filename );
	if ( access ( path , 4 ) >= 0 )
		return ( TRUE );

	/* try a subdirectory called Thai */

	strcpy ( path , "thai/" );
	strcat ( path , filename );
	if ( access ( path , 4 ) >= 0 )
		return ( TRUE );

	/* try the disk root directory */

	strcpy ( path , ":" );
	strcat ( path , filename );
	if ( access ( path , 4 ) >= 0 )
		return ( TRUE );

	/* if mounted, try thai: */

	if ( Assigned ( "Thai" ) ) {
		strcpy ( path , "Thai:" );
		strcat ( path , filename );
		if ( access ( path , 4 ) >= 0 )
			return ( TRUE );
	}

	/* ugg */

	printf ( stderr , "Failed to find '%s'\n" , filename );
	return ( FALSE );
}
