/*
**	termPickScreen.c
**
**	Simplified public screen selection routine
**
**	Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
**		All Rights Reserved
*/

#include "termGlobal.h"

enum	{	GAD_LIST,GAD_USE,GAD_CANCEL };

	/* CreateAllGadgets():
	 *
	 *	Get them gadgets goin'.
	 */

STATIC struct Gadget *
CreateAllGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,struct List *List,STRPTR Current,LONG *Index)
{
	struct Gadget		*Gadget;
	struct NewGadget	 NewGadget;
	UWORD			 Counter = 0;
	struct Node		*Node,
				*Next;
	BYTE			 GotIt = FALSE;

	*Index = 0;

	Node = List -> lh_Head;

	while(!GotIt && (Next = Node -> ln_Succ))
	{
		if(!strcmp(Node -> ln_Name,Current))
			GotIt = TRUE;
		else
			(*Index)++;

		Node = Next;
	}

	if(!GotIt)
		*Index = ~0;

	SZ_SizeSetup(Window -> WScreen,&UserFont,TRUE);

	memset(&NewGadget,0,sizeof(struct NewGadget));

	if(Gadget = CreateContext(GadgetList))
	{
		WORD ButtonWidth,ListWidth;

		SZ_ResetMaxWidth();

		SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_GLOBAL_USE_GAD),0,NULL);
		SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_GLOBAL_CANCEL_GAD),0,NULL);

		ButtonWidth = SZ_ResetMaxWidth();

		SZ_UpdateMaxWidth(LISTVIEW_KIND,NULL,40,NULL);

		ListWidth = SZ_ResetMaxWidth();

		if(ListWidth < 2 * ButtonWidth + InterWidth)
			ListWidth = 2 * ButtonWidth + InterWidth;
		else
			ButtonWidth = (ListWidth - InterWidth) / 2;

		SZ_SetWidth(ListWidth);

		NewGadget . ng_GadgetText	= LocaleString(MSG_TERMPICKSCREEN_SCREEN_LIST_GAD);
		NewGadget . ng_GadgetID		= Counter;
		NewGadget . ng_Flags		= PLACETEXT_ABOVE;

		GadgetArray[Counter++] = Gadget = CreateGadget(LISTVIEW_KIND,Gadget,&NewGadget,
			SZ_Adjust,		TRUE,
			SZ_AutoWidth,		TRUE,
			SZ_Lines,		10,
			SZ_InterHeight,		0,

			GTLV_Labels,		List,
			GTLV_ShowSelected,	NULL,
			GTLV_Selected,		*Index,
		TAG_DONE);

		SZ_SetWidth(ButtonWidth);

		NewGadget . ng_GadgetText	= LocaleString(MSG_GLOBAL_USE_GAD);
		NewGadget . ng_GadgetID		= Counter;
		NewGadget . ng_Flags		= 0;

		GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
			SZ_Adjust,	TRUE,
			SZ_AutoWidth,	TRUE,
			SZ_AlignExtra,	TRUE,
			SZ_AlignLeft,	TRUE,
			SZ_AlignBottom,	TRUE,
			SZ_GroupCount,	2,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_GLOBAL_CANCEL_GAD);
		NewGadget . ng_GadgetID		= Counter;

		GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
			SZ_Adjust,	TRUE,
			SZ_AutoWidth,	TRUE,
			SZ_GroupNext,	TRUE,
		TAG_DONE);
	}

	return(Gadget);
}

	/* BuildScreenList():
	 *
	 *	Build a private copy of the public screen list.
	 */

STATIC struct List *
BuildScreenList(VOID)
{
	struct List *List,*PubScreenList;

		/* Get the list body. */

	if(List = (struct List *)AllocVec(sizeof(struct List),MEMF_ANY))
	{
		NewList(List);

			/* Get access to the public screen list. */

		if(PubScreenList = LockPubScreenList())
		{
			struct Node *Next,*Node;

			Node = PubScreenList -> lh_Head;

				/* Scan the list. */

			while(Next = Node -> ln_Succ)
			{
					/* Don't include the current `term' public
					 * screen name in it.
					 */

				if(strcmp(Node -> ln_Name,TermIDString))
				{
					struct Node *New = CreateNode(Node -> ln_Name);

						/* Got a new node? */

					if(New)
						AddTail(List,New);
				}

				Node = Next;
			}

			UnlockPubScreenList();
		}

			/* In case the list happens to remain empty,
			 * include the Workbench screen in it.
			 */

		if(!List -> lh_Head -> ln_Succ)
		{
			struct Node *New = CreateNode("Workbench");

			if(New)
				AddTail(List,New);
			else
			{
				FreeVec(List);

				List = NULL;
			}
		}
	}

	return(List);
}

	/* PickScreen(STRPTR Name):
	 *
	 *	Your nice public screen selection routine.
	 */

BYTE
PickScreen(STRPTR Name)
{
	struct List	*ScreenList;
	BYTE		 Result = FALSE;

	if(ScreenList = BuildScreenList())
	{
		struct Window	*PanelWindow;
		struct Gadget	*GadgetList = NULL;
		struct Gadget	*GadgetArray[GAD_CANCEL + 1];
		LONG		 Index;

		if(CreateAllGadgets(GadgetArray,&GadgetList,ScreenList,Name,&Index))
		{
			if(PanelWindow = OpenWindowTags(NULL,
				WA_Left,		GetScreenLeft(Window) + (GetScreenWidth(Window) - SZ_GetWindowWidth()) / 2,
				WA_Top,			GetScreenTop(Window) + (GetScreenHeight(Window) - SZ_GetWindowHeight())	/ 2,
				WA_Width,		SZ_GetWindowWidth(),
				WA_Height,		SZ_GetWindowHeight(),

				WA_Activate,		TRUE,
				WA_DragBar,		TRUE,
				WA_DepthGadget,		TRUE,
				WA_RMBTrap,		TRUE,
				WA_CloseGadget,		TRUE,
				WA_CustomScreen,	Window -> WScreen,
				WA_NoCareRefresh,	TRUE,

				WA_IDCMP,		IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | IDCMP_ACTIVEWINDOW | LISTVIEWIDCMP | BUTTONIDCMP,

				WA_Title,		LocaleString(MSG_TERMPICKSCREEN_SCREENS_TXT),
			TAG_DONE))
			{
				struct IntuiMessage	*Massage;
				ULONG			 IClass,Code;
				struct Gadget		*Gadget;
				BYTE			 Terminated = FALSE;

				PushWindow(PanelWindow);

				AddGList(PanelWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
				RefreshGList(GadgetList,PanelWindow,NULL,(UWORD)-1);
				GT_RefreshWindow(PanelWindow,NULL);

				if(Index != ~0)
				{
					GT_SetGadgetAttrs(GadgetArray[GAD_LIST],PanelWindow,NULL,
						GTLV_Top,		Index,
						GTLV_MakeVisible,	Index,
					TAG_DONE);
				}

				ClrSignal(SIG_BREAK);

				while(!Terminated)
				{
					if(Wait(PORTMASK(PanelWindow -> UserPort) | SIG_BREAK) & SIG_BREAK)
						break;

					while(!Terminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(PanelWindow -> UserPort)))
					{
						IClass	= Massage -> Class;
						Code	= Massage -> Code;
						Gadget	= (struct Gadget *)Massage -> IAddress;

						GT_ReplyIMsg(Massage);

						KeySelect(GadgetArray,GAD_CANCEL,Code,PanelWindow,&Gadget,&IClass,&Code);

						if(IClass == IDCMP_CLOSEWINDOW)
							Terminated = TRUE;

						if(IClass == IDCMP_GADGETUP)
						{
							switch(Gadget -> GadgetID)
							{
								case GAD_USE:

									if(Index != ~0)
									{
										struct Node *Node;

										if(Node = GetListNode(Index,ScreenList))
										{
											strcpy(Name,Node -> ln_Name);

											Result = TRUE;
										}
									}

									Terminated = TRUE;
									break;

								case GAD_CANCEL:

									Terminated = TRUE;
									break;

								case GAD_LIST:

									Index = Code;
									break;
							}
						}
					}
				}

				RemoveGList(PanelWindow,GadgetList,(UWORD)-1);

				PopWindow();

				CloseWindow(PanelWindow);
			}
		}

		FreeGadgets(GadgetList);

		FreeList(ScreenList);

		FreeVec(ScreenList);
	}
	else
		DisplayBeep(Window -> WScreen);

	return(Result);
}
