//
// Support.c -- Support functions for Watcher.
//
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                            I N C L U D E S									*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
#include <exec/types.h>								// For UBYTE etc.
#include <clib/alib_protos.h>						// Protos for NewList() etc.
#include <clib/asl_protos.h>						// Protos for AllocAslRequestTags() etc.
#include <clib/exec_protos.h>						// Protos for FindTask() etc.
#include <clib/intuition_protos.h>				// Protos for CloseScreen() etc.
#include <clib/utility_protos.h>					// Protos for Stricmp() etc.
#include <libraries/asl.h>							// For ASL_FileRequest tag etc.
#include <pragmas/asl_pragmas.h>					// Pragmsa for asl.library.
#include <pragmas/exec_pragmas.h>				// Pragmas for exec.library.
#include <pragmas/intuition_pragmas.h>			// Pragmas for intuition.library.
#include <pragmas/utility_pragmas.h>			// Pragmas for utility.library.
#include <string.h>									// Proto for strcpy() etc.

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

#include "Watcher.h"									// For VERS define.

/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                             I M P O R T S										*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*------------*/
/* Variables: */
/*------------*/
extern struct Library			*AslBase;		// asl.library.
extern struct IntuitionBase	*IntuitionBase;// intuition.library
extern struct Library			*UtilityBase;	// utility.library.

extern struct Window				*Win;				// Watcher window.
extern struct Window				*WindowPtr;		// Our cli window.
extern UWORD chip					WaitPointer [];// Designed by C=.

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

/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                             SleepWindow()										*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
BOOL SleepWindow (struct Window *w, struct Requester *r)
{
	/*--------------------------------------*/
	/* Make resizing the window impossible. */
	/*--------------------------------------*/
	w->MinWidth		= w->Width;
	w->MinHeight	= w->Height;
	w->MaxWidth		= w->Width;
	w->MaxHeight	= w->Height;

	/*------------------------------------------------*/
	/* Initializing user supplied requster structure. */
	/*------------------------------------------------*/
	InitRequester (r);

	/*---------------------------------*/
	/* Putting up the empty requester. */
	/*---------------------------------*/
	if (Request (r, w))
	{
		/*--------------------------------------------*/
		/* Success! We also implement a busy pointer! */
		/*--------------------------------------------*/
		SetPointer (w, WaitPointer, 16, 16, -6, 0);
		return (TRUE);
	}

	/*-------------------------*/
	/* Error, we return FALSE. */
	/*-------------------------*/
	return (FALSE);
}

/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                            WakeUpWindow()										*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
void WakeUpWindow (struct Window *w, struct Requester *r)
{
	/*------------------------*/
	/* Enable resizing again. */
	/*------------------------*/
	w->MinWidth		= -1;
	w->MinHeight	= -1;
	w->MaxWidth		= 65535;
	w->MaxHeight	= 65535;

	/*----------------------------*/
	/* Clearing the busy pointer. */
	/*----------------------------*/
	ClearPointer (w);

	/*-------------------------------------------------------------------*/
	/* Removing the empty requester. This reenables input in the window. */
	/*-------------------------------------------------------------------*/
	EndRequest (r, w);
}

/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                              EmptyList()										*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
BOOL EmptyList (struct List *list)
{
	if (list->lh_TailPred == (struct Node *) list)
	{
		return (TRUE);
	}
	return (FALSE);
}

/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                              SortList()										*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
void SortList (struct List *list, short col)
{
	/*-------------*/
	/* L O C A L S */
	/*-------------*/
	struct List	tmp;
	struct Node *np, *np2;

	/*---------*/
	/* C O D E */
	/*---------*/
	/*-------------------------*/
	/* Check if list is empty. */
	/*-------------------------*/
	if (EmptyList (list))
	{
		return;
	}

	NewList (&tmp);

	while (!EmptyList (list))
	{
		np = RemHead (list);

		if (EmptyList (&tmp))
		{
			AddHead (&tmp, np);
		}
		else
		{
			if (Stricmp (&np->ln_Name [col], &tmp.lh_Head->ln_Name [col]) < 0)
			{
				AddHead (&tmp, np);
			}
			else
			{
				if (Stricmp (&np->ln_Name [col], &tmp.lh_TailPred->ln_Name [col]) > 0)
				{
					AddTail (&tmp, np);
				}
				else
				{
					for (np2 = tmp.lh_Head; np2->ln_Succ; np2 = np2->ln_Succ)
					{
						if (Stricmp (&np->ln_Name [col], &np2->ln_Name [col]) < 0)
						{
							Insert (&tmp, np, np2->ln_Pred);
							break;
						}
					}
				}
			}
		}
	}

	NewList (list);

	while (!EmptyList (&tmp))
	{
		np = RemHead (&tmp);
		AddTail (list, np);
	}
}

/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                                About()											*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
void About (void)
{
	/*-------------*/
	/* L O C A L S */
	/*-------------*/
	UBYTE *z = XGetString (M_ABOUT_REQ);

	/*---------*/
	/* C O D E */
	/*---------*/
	Inform ((Win ? Win : WindowPtr), NULL, VERS " (" DATE ") %s", z);
}

/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                               Inform()											*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
BOOL Inform (struct Window *w, STRPTR Title, STRPTR Text, APTR args, ...)
{
	/*-------------*/
	/* L O C A L S */
	/*-------------*/
	struct EasyStruct es;
	UBYTE					*z = XGetString (M_INFORMATION);

	/*---------*/
	/* C O D E */
	/*---------*/
	if (IntuitionBase)
	{
		/*-------------------*/
		/* Build EasyStruct. */
		/*-------------------*/
		es.es_StructSize		= sizeof (struct EasyStruct);
		es.es_Flags				= 0;
		es.es_Title				= (Title) ? Title : z;
		es.es_TextFormat		= Text;
		es.es_GadgetFormat	= "Okay";

		/*------------------------------------------------------*/
		/* Call EasyRequestArgs() and return it's return value. */
		/*------------------------------------------------------*/
		return ((BOOL) EasyRequestArgs (w, &es, NULL, &args));
	}
	else
	{
		/*--------------------------*/
		/* We're running below V37. */
		/*--------------------------*/
		return (FALSE);
	}
}

/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                               Inform()											*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
BOOL Ask (struct Window *w, STRPTR Title, STRPTR Text, STRPTR GadText, APTR args, ...)
{
	/*-------------*/
	/* L O C A L S */
	/*-------------*/
	struct EasyStruct es;
	UBYTE					*z = XGetString (M_INFORMATION);

	/*---------*/
	/* C O D E */
	/*---------*/
	if (IntuitionBase)
	{
		/*-------------------*/
		/* Build EasyStruct. */
		/*-------------------*/
		es.es_StructSize		= sizeof (struct EasyStruct);
		es.es_Flags				= 0;
		es.es_Title				= (Title) ? Title : z;
		es.es_TextFormat		= Text;
		es.es_GadgetFormat	= GadText;

		/*------------------------------------------------------*/
		/* Call EasyRequestArgs() and return it's return value. */
		/*------------------------------------------------------*/
		return ((BOOL) EasyRequestArgs (w, &es, NULL, &args));
	}
	else
	{
		/*--------------------------*/
		/* We're running below V37. */
		/*--------------------------*/
		return (FALSE);
	}
}

/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                            VersionSearch()									*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
BOOL VersionSearch (UBYTE *filename, LONG filelen, UBYTE *versionbuffer)
{
	/*-------------*/
	/* L O C A L S */
	/*-------------*/
	LONG count = 0;
	

	/*---------*/
	/* C O D E */
	/*---------*/
	while (count < (filelen - 5))
	{
		if ((filename [count]     == '$') &&
			 (filename [count + 1] == 'V') &&
			 (filename [count + 2] == 'E') &&
			 (filename [count + 3] == 'R') &&
			 (filename [count + 4] == ':'))
		{
			strcpy (versionbuffer, &filename [count + 6]);
			return (TRUE);
		}
		count++;
	}
	return (FALSE);
}

/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
/*                              LoadAFile()										*/
/*лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл*/
BOOL LoadAFile (UBYTE *dir, UBYTE *file, UBYTE *resultdir, UBYTE *resultfile)
{
	/*-------------*/
	/* L O C A L S */
	/*-------------*/
	struct FileRequester	*fr;

	/*---------*/
	/* C O D E */
	/*---------*/
	/*-------------------------*/
	/* Allocate memory for fr. */
	/*-------------------------*/
	if (!(fr = AllocAslRequestTags (ASL_FileRequest,
											  ASLFR_InitialFile,		file,
											  ASLFR_InitialDrawer,	dir,
											  TAG_END)))
	{
		return (FALSE);
	}

	/*-----------------------*/
	/* Put up the requester. */
	/*-----------------------*/
	if (AslRequest (fr, TAG_END))
	{
		strcpy (resultdir, fr->rf_Dir);
		strcpy (resultfile, fr->rf_File);
	}
	else
	{
		FreeAslRequest (fr);
		return (FALSE);
	}

	FreeAslRequest (fr);
	return (TRUE);
}
