/*
**	termAmigaGuide.c
**
**	AmigaGuide support routines
**
**	Copyright © 1990-1993 by Olaf `Olsen' Barthel
**		All Rights Reserved
*/

#include "termGlobal.h"

	/* Local data. */

STATIC STRPTR			 ContextList[35];
STATIC AMIGAGUIDECONTEXT	 Context;
STATIC struct NewAmigaGuide	 NewGuide;
STATIC struct Process		*GuideProcess;
STATIC LONG			 GuideContextID = CONTEXT_MAIN;
STATIC BOOLEAN			 Trouble,
				 Waiting = TRUE;

	/* GuideServer(VOID):
	 *
	 *	AmigaGuide server, handles all the signal processing.
	 */

STATIC VOID __saveds
GuideServer(VOID)
{
	if(Trouble)
	{
		Signal(ThisProcess,SIG_HANDSHAKE);

		Context = OpenAmigaGuide(&NewGuide,TAG_DONE);

		CloseAmigaGuide(Context);
	}
	else
	{
			/* Open the help text file asynchronously... */
	
		if(Context = OpenAmigaGuideAsync(&NewGuide,TAG_DONE))
		{
			ULONG	GuideMask,
				Signals;
			BYTE	Done = FALSE;
	
				/* Pick up the signal notification mask. */
	
			GuideMask = AmigaGuideSignal(Context);
	
				/* Clear the context stack. */
	
			SetAmigaGuideContext(Context,0,TAG_DONE);
	
				/* Flag the main process to continue. */
	
			Signal(ThisProcess,SIG_HANDSHAKE);
	
				/* Go into input loop. */
	
			do
			{
					/* Wait for a signal... */
	
				Signals = Wait(SIG_KILL | GuideMask);
	
					/* Are we to quit? */
	
				if(Signals & SIG_KILL)
					Done = TRUE;
	
					/* Process icoming AmigaGuide messages. */
	
				if(Signals & GuideMask)
				{
					struct AmigaGuideMsg *GuideMessage;
	
					while(GuideMessage = GetAmigaGuideMsg(Context))
						ReplyAmigaGuideMsg(GuideMessage);
				}
			}
			while(!Done);
	
				/* Close the help text file. */
	
			CloseAmigaGuide(Context);
		}
	}

		/* Lock & quit. */

	Forbid();

	GuideProcess = NULL;

	if(Waiting)
		Signal(ThisProcess,SIG_HANDSHAKE);
}

	/* GuideLaunch(LONG ContextID):
	 *
	 *	Launch the AmigaGuide help file server.
	 */

STATIC BYTE
GuideLaunch(LONG ContextID)
{
		/* Is the main program running and is this the
		 * main program to make the call?
		 */

	if(Window && SysBase -> ThisTask == ThisProcess)
	{
			/* Is the help file server already running? */

		if(!GuideProcess)
		{
			if(!AmigaGuideBase)
			{
				if(AmigaGuideBase = OpenLibrary("amigaguide.library",0))
					Trouble = (AmigaGuideBase -> lib_Version < 39);
			}

			if(AmigaGuideBase)
			{
				BYTE IsValidFile = TRUE;

					/* Do we have a valid AmigaGuide file name? */

				if(Config -> PathConfig -> HelpFile[0])
				{
					if(!GetFileSize(Config -> PathConfig -> HelpFile))
						IsValidFile = FALSE;
				}
				else
					IsValidFile = FALSE;

					/* Do we have a valid AmigaGuide file name? */

				if(!IsValidFile)
				{
						/* Don't pop up the file requester if any
						 * time-critical services are currently running!
						 */

					if(ContextID == CONTEXT_TRANSFER || ContextID == CONTEXT_DIAL)
					{
						DisplayBeep(Window -> WScreen);

						return(FALSE);
					}
					else
					{
						struct FileRequester	*FileRequest;
						UBYTE			 DummyBuffer[MAX_FILENAME_LENGTH],
									 DummyName[40];

							/* Provide a default name if necessary. */

						if(!Config -> PathConfig -> HelpFile[0])
							strcpy(Config -> PathConfig -> HelpFile,"PROGDIR:term.guide");

							/* Block the windows. */

						BlockWindows();

							/* Get file and path name. */

						strcpy(DummyBuffer,Config -> PathConfig -> HelpFile);

						if(DummyBuffer[0])
						{
							STRPTR DummyChar;

							if(FilePart(DummyBuffer) == DummyBuffer)
							{
								strcpy(DummyName,DummyBuffer);

								DummyBuffer[0] = 0;
							}
							else
							{
								strcpy(DummyName,FilePart(DummyBuffer));

								DummyChar = PathPart(DummyBuffer);

								*DummyChar = 0;
							}
						}
						else
							DummyName[0] = 0;

							/* Get the help text file name. */

						if(FileRequest = GetFile(Window,LocaleString(MSG_PATHPANEL_SELECT_HELP_FILE_TXT),DummyBuffer,DummyName,DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SELECT_TXT),TRUE))
						{
							if(GetFileSize(DummyBuffer))
							{
								strcpy(Config -> PathConfig -> HelpFile,DummyBuffer);

								IsValidFile = TRUE;
							}

							FreeAslRequest(FileRequest);
						}

							/* Release the windows... */

						ReleaseWindows();
					}
				}

					/* Do we finally have a valid file name? */

				if(IsValidFile)
				{
						/* Provide the context node names (note: language
						 * specific!).
						 */

					LocalizeString(ContextList,MSG_TERMAMIGAGUIDE_NODE_00_TXT,MSG_TERMAMIGAGUIDE_NODE_32_TXT);

					ContextList[33] = LocaleString(MSG_TERMAMIGAGUIDE_NODE_33_TXT);

						/* Clear the instance. */

					memset(&NewGuide,0,sizeof(struct NewAmigaGuide));

						/* Fill in the structure. */

					NewGuide . nag_BaseName		= "termHelp";
					NewGuide . nag_Name		= Config -> PathConfig -> HelpFile;
					NewGuide . nag_ClientPort	= "TERM_HELP";
					NewGuide . nag_Context		= ContextList;
					NewGuide . nag_Screen		= Window -> WScreen;

						/* Launch the server process and
						 * wait for reply.
						 */

					Forbid();

					Waiting = TRUE;

					if(GuideProcess = CreateNewProcTags(
						NP_Entry,	GuideServer,
						NP_Name,	"term AmigaGuide Process",
					TAG_DONE))
					{
						ClrSignal(SIG_HANDSHAKE);

						Wait(SIG_HANDSHAKE);
					}

					Waiting = FALSE;

					Permit();
				}
			}
		}

			/* Pop the main screen to the front if necessary. */

		if(GuideProcess)
		{
			ScreenToFront(Window -> WScreen);

			return(TRUE);
		}
		else
		{
			if(AmigaGuideBase)
			{
				CloseLibrary(AmigaGuideBase);

				AmigaGuideBase = NULL;
			}

			DisplayBeep(Window -> WScreen);

			return(FALSE);
		}
	}
	else
	{
		if(GuideProcess && Window)
		{
			ScreenToFront(Window -> WScreen);

			return(TRUE);
		}
		else
			return(FALSE);
	}
}

	/* GuideCleanup():
	 *
	 *	Terminate the AmigaGuide server and free the
	 *	associated resources.
	 */

VOID
GuideCleanup()
{
	if(GuideProcess)
	{
		Forbid();

		Waiting = TRUE;

		if(Trouble)
		{
			MyEasyRequest(Window,LocaleString(MSG_V36_1830),LocaleString(MSG_GLOBAL_CONTINUE_TXT));

			SendAmigaGuideCmd(Context,"QUIT",NULL);
		}
		else
			Signal(GuideProcess,SIG_KILL);

		ClrSignal(SIG_HANDSHAKE);

		Wait(SIG_HANDSHAKE);

		Permit();
	}

	if(AmigaGuideBase)
	{
		CloseLibrary(AmigaGuideBase);

		AmigaGuideBase = NULL;
	}
}

	/* GuideContext(LONG NewContextID):
	 *
	 *	Set the global AmigaGuide context.
	 */

VOID __regargs
GuideContext(LONG NewContextID)
{
	GuideContextID = NewContextID;
}

ULONG __saveds __asm
GuideSetupHook(register __a0 struct Hook *Hook,register __a1 struct LayoutHandle *Handle,register __a2 LONG GadgetID)
{
	if(GuideLaunch(GuideContextID))
	{
		SendAmigaGuideCmd(Context,NULL,
			AGA_Context,GuideContextID,
		TAG_DONE);

		return(TRUE);
	}
	else
		return(FALSE);
}

	/* GuideSetup():
	 *
	 *	Try to display the currently selected AmigaGuide
	 *	help text.
	 */

VOID
GuideSetup()
{
	if(GuideLaunch(GuideContextID))
	{
		SendAmigaGuideCmd(Context,NULL,
			AGA_Context,GuideContextID,
		TAG_DONE);
	}
}

	/* GuideDisplay(LONG ContextID):
	 *
	 *	Try to display an AmigaGuide help text.
	 */

VOID __regargs
GuideDisplay(LONG ContextID)
{
	if(GuideLaunch(ContextID))
	{
		SendAmigaGuideCmd(Context,NULL,
			AGA_Context,ContextID,
		TAG_DONE);
	}
}
