 /*
 * Variables controlling Yak settings.
 * Routines for initialisation at startup.
 */

#include <exec/types.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <libraries/commodities.h>
#include <proto/dos.h>
#include <string.h>

#include "yak.h"
#include "popup.h"

/* local prototypes */
static BOOL __regargs FWriteLong(BPTR fh, LONG n);
static BOOL __regargs FReadLong(BPTR fh, LONG *n);
static BOOL __regargs FWriteString(BPTR fh, char *buf);
static BOOL __regargs FReadString(BPTR fh, char *buf);

#define DEF_POPCOMMAND	"NewShell CON:0/178//78/AmigaShell/CLOSE"
char	PopCommand[POPLEN+1] = DEF_POPCOMMAND;	/* used for PopCLI */

#define DEF_DATEFORMAT  "%e %B %Y"
char	DateFormat[DATELEN+1] = DEF_DATEFORMAT;	/* used for InsertDate */

#define DEF_VOLUME	48
LONG	click_volume = DEF_VOLUME;		/* used for keyclick */

#define DEF_BLANKSECS	300
LONG	blanksecs = DEF_BLANKSECS;
LONG	blanktimeout;
LONG	blankcount;				/* countdown to blank-time */

#define DEF_MBLANKSECS	5
LONG	mouseblank = MB_SPRITES;
LONG	mblanksecs = DEF_MBLANKSECS;
LONG	mblanktimeout;
LONG	mblankcount;			/* countdown to mouse-blank-time */

TOGGLEDATA toggles[] = {		/* -1 means UNUSED */
	TRUE,	GDX_CTFCheck,
	TRUE,	GDX_CTBCheck,
	TRUE,	GDX_AutoCheck,
	FALSE,	GDX_KeyActCheck,
	TRUE,	GDX_ScrCycleCheck,
	FALSE,	GDX_AutoPopCheck,
	FALSE,	GDX_RMBActCheck,
	FALSE,	-1,
	TRUE,	-1,
	FALSE,	GDX_WildStarCheck,
	TRUE,	GDX_ScrActCheck
};

HOTKEYDATA hk[NUM_HOTKEYS] = {
	{ HK_POPKEY,	NULL, "RCommand help" },
	{ HK_CLOSEKEY,	NULL, "control esc" },
	{ HK_ZIPKEY,	NULL, "control z" },
	{ HK_SHRINKKEY,	NULL, "lcommand [" },
	{ HK_ZOOMKEY,	NULL, "lcommand ]" },
	{ HK_WORKBENCH,	NULL, "lcommand w" },
	{ HK_POPPALKEY,	NULL, "lcommand p" },
	{ HK_POPCLI,	NULL, "lcommand esc" },
	{ HK_INSDATE,	NULL, "lcommand d" },
	{ HK_CYCLEWIN,	NULL, "lcommand k" },
	{ HK_CYCLESCR,	NULL, "lcommand n" },
	{ HK_CENTERSCR,	NULL, "lcommand c" },
	{ HK_SCRTOBACK,	NULL, "lcommand m" },	/* special */
	{ HK_BLANK,	NULL, "lcommand del" }
};

PATTERNDATA patterns[NUM_PATTERNS] = {
	{ "#?", NULL },			/* autoactivation screens */
	{ "#?", NULL },			/* click screens */
	{ "~(Workbench)", NULL },	/* autopop windows */
	{ "~(Workbench)", NULL }	/* click windows */
};

/* 1.3 format
 * Routines to load/save config file for Yak.
 * Should handle config files in upward-compatible manner.
 * File format:
 * 
 * 	LONG ID
 * 	LONG NUM_TOGGLES
 * 	BOOL toggles
 * 	LONG NUM_HOTKEYS
 * 	STR hotkey1 '\n'
 * 		:
 * 	STR hotkeyN '\n'
 * 	LONG NUM_PATTERNS
 *	STR pattern1 '\n'
 * 		:
 *	STR patternN '\n'
 * 	STR popcommand '\n'
 *	STR datefmt '\n'
 * 	LONG click_volume, blanksecs
 *	LONG mblanksecs			**ADDED @ v1.3b
 *	LONG mouseblank			**ADDED @ v1.3e
 */

#define CONFIG_ID	0x594b3133	/* YK13 */

/* write a LONG to a file (in binary format) - returns success*/
static BOOL __regargs
FWriteLong(BPTR fh, LONG n)
{
	return (BOOL)(FWrite(fh, (UBYTE *)&n, sizeof(LONG), 1) == 1);
}

/* read a LONG to a file (in binary format) - returns success */
static BOOL __regargs
FReadLong(BPTR fh, LONG *n)
{
	return (BOOL)(FRead(fh, (UBYTE *)n, sizeof(LONG), 1) == 1);
}

/* write a string to a file (in binary format) - returns success*/
/* '\n' is appended */
static BOOL __regargs
FWriteString(BPTR fh, char *buf)
{
	FPuts(fh, buf);
	FPutC(fh, '\n');
	return (BOOL)(IoErr() == 0);
}

/* read a string to a file (in binary format) - returns success */
/* '\n' is stripped and buf null-terminated; assumes dest large enough */
static BOOL __regargs
FReadString(BPTR fh, char *buf)
{
	char tbuf[512];

	FGets(fh, tbuf, 512);
	tbuf[strlen(tbuf)-1] = '\0';	/* '\n' --> '\0' */
	strcpy(buf, tbuf);
	return (BOOL)(IoErr() == 0);
}

/* save current settings to config file */
void __regargs
SaveSettings(char *file)
{
	BPTR	fh;
	UWORD	i;

	if (fh = Open(file, MODE_NEWFILE))
	{
		FWriteLong(fh, CONFIG_ID);

		/* toggles */
		FWriteLong(fh, NUM_TOGGLES);
		for (i = 0; i < NUM_TOGGLES; i++)
			FWrite(fh, (UBYTE *)&toggles[i].pos, sizeof(BOOL), 1);

		/* hotkeys */
		FWriteLong(fh, NUM_HOTKEYS);
		for (i = 0; i < NUM_HOTKEYS; i++)
			FWriteString(fh, hk[i].key);

		/* patterns */
		FWriteLong(fh, NUM_PATTERNS);
		for (i = 0; i < NUM_PATTERNS; i++)
			FWriteString(fh, patterns[i].patstr);

		/* miscellaneous */
		FWriteString(fh, PopCommand);
		FWriteString(fh, DateFormat);
		FWriteLong(fh, click_volume);
		FWriteLong(fh, blanksecs);
		FWriteLong(fh, mblanksecs);

		FWriteLong(fh, mouseblank);

		Close(fh);
	}
	if (IoErr() != 0) PostError("Error writing config file\n");
}

/* load current settings from file */
void __regargs
LoadSettings(char *file)
{
	BPTR	fh;
	UWORD	i;
	LONG	n;

	if (fh = Open(file, MODE_OLDFILE))
	{
		FReadLong(fh, &n);
		if (n == CONFIG_ID)
		{
			/* toggles */
			FReadLong(fh, &n);
			for (i = 0; i < n; i++)
				FRead(fh, (UBYTE *)&toggles[i].pos, sizeof(BOOL), 1);

			/* hotkeys */
			FReadLong(fh, &n);
			for (i = 0; i < n; i++)
				FReadString(fh, hk[i].key);

			/* patterns */
			FReadLong(fh, &n);
			for (i = 0; i < n; i++)
				FReadString(fh, patterns[i].patstr);

			/* miscellaneous */
			FReadString(fh, PopCommand);
			FReadString(fh, DateFormat);
			FReadLong(fh, &click_volume);
			FReadLong(fh, &blanksecs);
			if (!FReadLong(fh, &mblanksecs))	/* none there */
				mblanksecs = DEF_MBLANKSECS;
			if (!FReadLong(fh, &mouseblank))	/* none there */
				mouseblank = MB_SPRITES;
		}
		else PostError("Invalid config file\n");
		Close(fh);
	}

	/* set-up hotkeys */
	for (i = 0; i < NUM_HOTKEYS; i++)
		AddHotKey(NULL, i);

	/* set-up patterns */
	for (i = 0; i < NUM_PATTERNS; i++)
		InitPattern(NULL, i);

	if (wildstar)
		WILDSTARON;
	else
		wildstar = ((struct RootNode *)(DOSBase->dl_Root))->rn_Flags & RNF_WILDSTAR;
	blankcount = blanktimeout = 10*blanksecs;
	mblankcount = mblanktimeout = 10*mblanksecs;
}
