//
// Prefs.c -- Function related to Watcher preferences.
//
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                            I N C L U D E S									*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
#include <exec/types.h>								// For UBYTE etc.
#include <exec/memory.h>							// For MEMF_ANY etc.
#include <clib/alib_protos.h>						// Protos for NewList() etc.
#include <clib/dos_protos.h>						// Protos for Read() etc.
#include <clib/exec_protos.h>						// Protos for CreateMsgPort() etc.
#include <dos/notify.h>								// For file notification.
#include <pragmas/dos_pragmas.h>					// Pragmas for dos.library.
#include <pragmas/exec_pragmas.h>				// Pragmas for exec.library.
#include <string.h>									// Protos for strcpy() etc.
#include <workbench/workbench.h>					// For NO_ICON_POSITION etc.

#include "/include/Catalog.h"						// V37 compatible locale.
#define CATCOMP_NUMBERS
#include "/include/Watcher_strings.h"			// All strings used in Watcher.

#include "/include/Prefs.h"						// For struct WPrefs.

/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                             I M P O R T S										*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*------------*/
/* Variables: */
/*------------*/
extern struct DosLibrary		*DOSBase;			// dos.library.
extern struct WPrefs				*WPrefs;				// Watcher preferences struct.
extern struct Window				*WindowPtr;			// Our cli window.
extern BPTR							PrefFile;			// Preference file.
extern struct MsgPort			*NotifyPort;		// Prefs notification.
extern struct List				*NotifyList;		// List of nodes of notifications.
extern struct NotifyNode		*NotifyNode;		// Notification node.
extern struct NotifyRequest	*NotifyReq;			// Notification request.
extern BOOL							mem_pool_ok;		// Can we use V39 memory pools?
extern APTR							mem_pool;			// Pointer to our memory pool.
extern UBYTE						*ENVARCPrefsName;	// "ENVARC:Watcher.prefs".
extern UBYTE						*ENVPrefsName;		// "ENV:Watcher.prefs".

/*------------*/
/* Functions: */
/*------------*/
extern BOOL	Inform			(struct Window *w, STRPTR Title, STRPTR Text, APTR args, ...);
extern void	FreeAllNodes	(struct List *l);

/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                              P R O T O S										*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
void	UsePrefsDefaults	(void);
BOOL	AddNotification	(UBYTE *fname);

/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                              ReadPrefs()										*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
BOOL ReadPrefs (UBYTE *fname, BOOL Notify)
{
	/*-------------*/
	/* L O C A L S */
	/*-------------*/
	BPTR PrefFile;										// Preference file handle.

	/*---------*/
	/* C O D E */
	/*---------*/
	/*----------------------------*/
	/* Open the preferences file. */
	/*----------------------------*/
	if (!(PrefFile = Open (fname, MODE_OLDFILE)))
	{
		return (FALSE);
	}
	else
	{
		/*---------------------------*/
		/* Read the preference file. */
		/*---------------------------*/
		if (Read (PrefFile, WPrefs, sizeof (struct WPrefs)) != sizeof (struct WPrefs))
		{
			UBYTE *aa;
			UBYTE *bb;

			/*------------------------------------------*/
			/* Check that this is a Watcher.prefs file. */
			/*------------------------------------------*/
			if (WPrefs->wp_PrefsIdentifier != 87808270)
			{
				aa = XGetString (M_WARNING);
				bb = XGetString (M_NOT_A_WATCHERPREFS_FILE);
				Inform (NULL, aa, bb, NULL);
			}
			else
			{
				aa = XGetString (M_WARNING);
				bb = XGetString (M_OLD_WATCHER_PREFS);
				Inform (NULL, aa, bb, NULL);
			}
			UsePrefsDefaults ();
		}

		/*----------------------------*/
		/* Close the preference file. */
		/*----------------------------*/
		Close (PrefFile);

		/*-----------------------------*/
		/* Setup Notification on file. */
		/*-----------------------------*/
		if (Notify)
		{
			AddNotification (fname);
		}
	}
	return (TRUE);
}

/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                          UsePrefsDefaults()									*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
void UsePrefsDefaults (void)
{
	WPrefs->wp_PrefsIdentifier			= 87808270;
	strcpy (WPrefs->wp_VolNameStrGad, "SYS:-a");
	WPrefs->wp_Total						= TRUE;
	WPrefs->wp_Fast						= FALSE;
	WPrefs->wp_Chip						= FALSE;
	WPrefs->wp_Largest					= FALSE;
	WPrefs->wp_LargestFast				= FALSE;
	WPrefs->wp_LargestChip				= FALSE;
	WPrefs->wp_DayOfWeek					= TRUE;
	WPrefs->wp_Date						= TRUE;
	WPrefs->wp_Time						= TRUE;
	WPrefs->wp_WinLeftEdge				= 0;
	WPrefs->wp_WinTopEdge				= 12;
	WPrefs->wp_WinWidth					= 640;
	WPrefs->wp_UpdateSec					= 1;
	WPrefs->wp_UpdateMic					= 0;
	WPrefs->wp_NoJumpGadget				= FALSE;
	WPrefs->wp_Cpu							= FALSE;
	strcpy (WPrefs->wp_PubScreen, "Workbench");
	strcpy (WPrefs->wp_GuideFile, "Watcher.guide");
	WPrefs->wp_VolumeFreeDirection	= FALSE;
	strcpy ((UBYTE *) WPrefs->wp_VolumeFreeDirectionInd, " ^v");
	strcpy ((UBYTE *) WPrefs->wp_VolAlertStrGad, "SYS:-k500");
	WPrefs->wp_AppInfoAutoStart		= TRUE;
	WPrefs->wp_AppInfoLeftEdge			= 0;
	WPrefs->wp_AppInfoTopEdge			= 0;
	strcpy (WPrefs->wp_Language, "english");
	WPrefs->wp_LanguageNum				= 1;
	WPrefs->wp_TimeFormat24				= TRUE;
	WPrefs->wp_DateFormat				= 0;
}

/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                       SetupPrefsNotification()								*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
BOOL SetupPrefsNotification (void)
{
	/*-------------*/
	/* L O C A L S */
	/*-------------*/
	BOOL rc = TRUE;

	/*---------*/
	/* C O D E */
	/*---------*/
	/*--------------------------------------------*/
	/* Create message port for file notification. */
	/*--------------------------------------------*/
	if (!(NotifyPort = CreateMsgPort ()))
	{
		rc = FALSE;
		goto ErrExit;
	}

	/*-------------------------------*/
	/* Allocate memory for our list. */
	/*-------------------------------*/
	if (mem_pool_ok)
	{
		if (!(NotifyList = AllocPooled (mem_pool, sizeof (struct List))))
		{
			rc = FALSE;
			goto ErrExit;
		}
	}
	else
	{
		if (!(NotifyList = AllocVec (sizeof (struct List), MEMF_ANY | MEMF_PUBLIC)))
		{
			rc = FALSE;
			goto ErrExit;
		}
	}

	/*------------*/
	/* Init list. */
	/*------------*/
	NewList (NotifyList);

	return (rc);

 ErrExit:

	if (NotifyPort)
	{
		DeleteMsgPort (NotifyPort);
	}

	if (NotifyList)
	{
		if (!mem_pool_ok)
		{
			FreeVec (NotifyList);
		}
	}
	return (rc);
}

/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                           AddNotification()									*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
BOOL AddNotification (UBYTE *fname)
{
	/*-------------*/
	/* L O C A L S */
	/*-------------*/
	BOOL rc = TRUE;

	/*---------*/
	/* C O D E */
	/*---------*/
	/*---------------------------------*/
	/* Allocate memory for NotifyNode. */
	/*---------------------------------*/
	if (mem_pool_ok)
	{
		if (!(NotifyNode = AllocPooled (mem_pool, sizeof (struct NotifyNode))))
		{
			rc = FALSE;
			goto ErrExit;
		}
	}
	else
	{
		if (!(NotifyNode = AllocVec (sizeof (struct NotifyNode), MEMF_ANY | MEMF_CLEAR)))
		{
			rc = FALSE;
			goto ErrExit;
		}
	}

	/*-------------------*/
	/* Setup NotifyNode. */
	/*-------------------*/
	NotifyNode->nn_Node.ln_Name = fname;

	/*------------------*/
	/* Setup NotifyReq. */
	/*------------------*/
	NotifyReq									= &(NotifyNode->nn_NotifyRequest);
	NotifyReq->nr_Name						= NotifyNode->nn_Node.ln_Name;
	NotifyReq->nr_Flags						= NRF_SEND_MESSAGE | NRF_WAIT_REPLY;
	NotifyReq->nr_stuff.nr_Msg.nr_Port	= NotifyPort;
	NotifyReq->nr_UserData					= (ULONG) NotifyNode;

	/*-----------------------------*/
	/* Begin notification on file. */
	/*-----------------------------*/
	if (StartNotify (NotifyReq) != DOSTRUE)
	{
		rc = FALSE;
		goto ErrExit;
	}

	/*-----------------------------------------------*/
	/* Add the successfull notification to our list. */
	/*-----------------------------------------------*/
	AddTail (NotifyList, (struct Node *) NotifyNode);

	return (rc);

ErrExit:

	if (NotifyNode)
	{
		if (!mem_pool_ok)
		{
			FreeVec (NotifyList);
		}
	}
	return (rc);
}

/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                       RemovePrefsNotification()								*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
void RemovePrefsNotification (void)
{
	/*-------------*/
	/* L O C A L S */
	/*-------------*/
	struct NotifyNode	*nnode, *nextnode;

	/*---------*/
	/* C O D E */
	/*---------*/
	nnode = (struct NotifyNode *) NotifyList->lh_Head;
	while (nextnode = (struct NotifyNode *) nnode->nn_Node.ln_Succ)
	{
		NotifyReq = &(nnode->nn_NotifyRequest);
		EndNotify (NotifyReq);
		Remove ((struct Node *) nnode);
		if (!mem_pool_ok)
		{
			FreeVec (nnode);
		}
		nnode = nextnode;
	}

	if (NotifyList)
	{
		if (!mem_pool_ok)
		{
			FreeVec (NotifyList);
		}
	}

	if (NotifyPort)
	{
		DeleteMsgPort (NotifyPort);
	}
}
