/* log.c:
 * This file deals with "wrong guess" logging, and "usefiles".
 * Both are read in at startup, and written out when the program quits.
 *
 * For usefile usage, we are using the pseudo-OO design of encapsulating
 * details in this file. So for this case, static globals are a GOOD THING.
 * It makes it seem like we have an implicit "usefile" object, that can
 * only be accessed through member functions listed in log.h
 */

#include <stdio.h>
#include <Xatom.h>
#include <Xos.h>
#include <Intrinsic.h>
#include <StringDefs.h>
#include <Xfuncs.h>
#include <Shell.h>
#include <Xaw/Command.h>

#include "defs.h"
#include "externs.h"
#include "game.h"
#include "badguess.h"
#include "options.h"

static char logfilename[200];

Boolean useKanji[MAXTRANSLATIONSALLOWED];

/* initlog()
 *    Checks for existance of logfile, and reads in previously missed
 *      count from that if possible.
 */
void 
initlog()
{
	FILE *oldlogfile;
	char inbuf[100];

	GetXtrmString("logfile", "Logfile", logfilename);

	if (access(logfilename, R_OK) != 0)
		return;
	oldlogfile = fopen(logfilename, "r");
	if (oldlogfile == NULL) {
		printf("kdrill: Error... cannot open file %s\n", logfilename);
		return;
	}
	else {
		printf("Reading in %s for previously missed kanji\n",
		       logfilename);
	}

	numberincorrect = 0;
	while (fgets(inbuf, 99, oldlogfile) != NULL) {
		int kindex;
		kindex = xtoi(inbuf);
		if (kindex < MAXTRANSLATIONSALLOWED) {
			if (translations[kindex] != NULL) {
				translations[kindex]->incorrect += 1;
				if (translations[kindex]->incorrect == 1)
					numberincorrect += 1;
				AdjustBadCache(translations[kindex]);
			}
		}
	}
	printf("Restored a total of %d incorrect kanji\n", numberincorrect);
	TallyWrong();
	fclose(oldlogfile);

}

/*
 * This is a callback for the "Log" button, but can be called with
 * NULL arguments, and IS, at the end of the program.
 *
 * MakeLog dumps our error log out to the logfile.
 * Do it in a vaguely "usefile"-compatible format, in case the player
 * wants _repeated_ drilling on the chars missed.
 */
void 
MakeLog(Widget w, XtPointer client_data, XtPointer call_data)
{
	int kcounter;
	char statbuf[200];
	int errors = 0;
	FILE *logfile;

	if (numberincorrect == 0) {
		sprintf(statbuf, "Clearing log file \"%.190s\"", logfilename);
		setstatus(statbuf);
		/* DEUBG: print same message to stdout*/
		printf("%s\n", statbuf);

		unlink(logfilename);
		return;
	}

	logfile = fopen(logfilename, "w");
	if (logfile == NULL) {
		if (numberincorrect > 0) {
			sprintf(statbuf, "Error.. cannot open \"%.190s\"",
				logfilename);
			setstatus(statbuf);
		}
		return;
	}
	for (kcounter = lowestkanji; kcounter <= highestkanji; kcounter++) {
		if (translations[kcounter] == NULL)
			continue;
		if (translations[kcounter]->incorrect > 0) {
			int loop = translations[kcounter]->incorrect;
			while (loop-- > 0) {
				fprintf(logfile, "%x \n", kcounter);
			}
			errors++;
		}

	}

	fclose(logfile);
	if (errors > 0) {
		sprintf(statbuf, "Saved %d kanji to \"%.190s\"", errors, logfilename);
		setstatus(statbuf);
		printf("%s\n", statbuf);
	}
}


/***********************************************
 * Now the Usefile section                     *
 ***********************************************/

int usefilecount = 0;

int 
NumInUsefile()
{
	return usefilecount;
}
/* If you're nice, use "False" or "True" as val */
void 
SetUseKanji(int kindex, int val)
{
	int oldval = useKanji[kindex];
	useKanji[kindex] = val;

	if (oldval == 0 && val == 1)
		usefilecount++;

	if (oldval == 1 && val == 0)
		usefilecount--;

}
int 
InUsefile(int kindex)
{
	return useKanji[kindex];
}

/* Save "usefile" entries, if appropriate */
void 
SaveUsefile()
{
	int kcount = 0;
	char statbuf[200];
	FILE *fptr;

	if(usefilecount <=0) {
		unlink(usefilename);
		return;
	}
	
	if (usefilecount < HAVE_AT_LEAST) {
		sprintf(statbuf, "WARNING: too few entries for usefile. Still saving to \"%.190s\"",
			usefilename);
	}

	fptr = fopen(usefilename, "w");
	if (fptr == NULL) {
		sprintf(statbuf, "Error.. cannot open \"%.190s\"",
			logfilename);
		setstatus(statbuf);
		perror(statbuf);
		return;
	}

	for (kcount = lowestkanji; kcount <= highestkanji; kcount++) {
		if (InUsefile(kcount) == 0)
			continue;
		fprintf(fptr, "%x\n", kcount);
	}

	fclose(fptr);
}


/* getusefile:
 *    Subroutine for initusefile().
 *      sets global FILE*usefile.
 *      If possible, will get it from the user's home directory,
 *      otherwise, tries current directory
 *      This is NOT an exported routine: initusefile() is
 */
FILE *
getusefile()
{
	FILE *fptr;
	char fullname[100];

	GetXtrmString("usefile", "Usefile", usefilename);

#ifdef DEBUG
	puts("");
	printf("usefile from resources is \"%s\"\n", usefilename);
#endif

	/*if(usefilename == NULL) return NULL; */
	fullname[0] = '\0';
	if (strncmp(usefilename, "~/", 2) == 0) {
		sprintf(fullname, "%s%s", homedir, &usefilename[1]);
		strcpy(usefilename, fullname);
	}

	if ((fptr = fopen(usefilename, "r")) == NULL) {
		printf("Usefile %s does not exist. Using entire dictionary...\n",
		       usefilename);
	}
	else {
		printf("using \"%s\" to abridge dictionary\n", usefilename);
		if (!useUsefile)
			puts("(-nousefile option used. Will not abridge, unless option is changed)");
	}
	return fptr;
}

/* inituse:
 *    revamped from 2.9.3 version.
 *      Read in the "usefile", which should consist of
 *      a list of hex SJIS indexes.
 *      This sets useKanji[] appropriately.
 *
 *      by default, zero out all entries.
 *      Then set only entries mentioned in file to 1 instead of 0
 *
 *      Note that whether or not to pay attention to useKanji[], is
 *      a separate variable, useUsefile
 */

void 
initusefile()
{
	FILE *fptr;
	char inbuf[100];
	int count = 0;


	/*first set all to UNREADABLE, for now */
	bzero(useKanji, sizeof(Boolean[MAXTRANSLATIONSALLOWED]));

	fptr = getusefile();

	if (fptr == NULL) {
		useUsefile = False;
		SetXtrmBoolean("nousefile", True);
		UpdateUsefileL();
		return;
	}

	while (fgets(inbuf, 99, fptr) != NULL) {
		int usechar;
		usechar = xtoi(inbuf);
		if (usechar < MAXTRANSLATIONSALLOWED) {
			SetUseKanji(usechar, True);
			count++;
		}
	}
	printf("read %d entries in usefile\n", count);
	if ((count < HAVE_AT_LEAST) && useUsefile) {
		printf("Warning: Usefile exists with less than %d kanji.\n",
		       HAVE_AT_LEAST);
	}

}
