/*
**	termUploadQueue.c
**
**	Upload queue user interface.
**
**	Copyright © 1990-1994 by Olaf `Olsen' Barthel
**		All Rights Reserved
*/

#include "termGlobal.h"

enum	{	GAD_LIST=1000,GAD_NAME,
		GAD_ADD,GAD_REMOVE,GAD_CLEAR,GAD_HIDE,
		GAD_ADD_FILES
	};

enum	{	APP_ICON=1,APP_WINDOW=2 };

STATIC struct List	*TransferList;
STATIC struct Node	*TransferNode;
STATIC LONG		 TransferOffset,
			 TransferCount;
STATIC struct MsgPort	*TransferPort;

STATIC struct Process	*TransferProcess;

	/* QueuePanel(struct Window *Window):
	 *
	 *	Create the user interface for the queue panel.
	 */

STATIC LayoutHandle *
QueuePanel(struct Window *Window)
{
	LayoutHandle *Handle;

	TransferNode	= NULL;
	TransferOffset	= -1;
	TransferCount	= GetListSize(TransferList);

	if(Handle = LT_CreateHandleTags(Window ? Window -> WScreen : NULL,
		LH_LocaleHook,	&LocaleHook,
	TAG_DONE))
	{
		LT_New(Handle,
			LA_Type,	VERTICAL_KIND,
		TAG_DONE);
		{
			LT_New(Handle,
				LA_Type,	VERTICAL_KIND,
			TAG_DONE);
			{
				LT_New(Handle,
					LA_Type,	LISTVIEW_KIND,
					LA_LabelID,	MSG_UPLOADQUEUE_FILES_TO_UPLOAD_TXT,
					LA_LabelPlace,	PLACE_ABOVE,
					LA_Chars,	30,
					LA_Lines,	10,
					LA_ID,		GAD_LIST,
					LALV_CursorKey,	TRUE,
					LALV_MaxGrowY,	20,
					LALV_MaxGrowX,	50,
					GTLV_Labels,	TransferList,

					Kick30 ? LALV_Link : TAG_IGNORE,NIL_LINK,
				TAG_DONE);

				LT_New(Handle,
					LA_Type,	STRING_KIND,
					LA_ID,		GAD_NAME,
					GTST_MaxChars,	255,
					LAST_Picker,	TRUE,
				TAG_DONE);

				LT_EndGroup(Handle);
			}

			LT_New(Handle,
				LA_Type,	HORIZONTAL_KIND,
				LA_LabelID,	MSG_V36_0043,
				LA_SameSize,	TRUE,
			TAG_DONE);
			{
				LT_New(Handle,
					LA_Type,	BUTTON_KIND,
					LA_LabelID,	MSG_ADD_SEVERAL_FILES_TXT,
					LA_ID,		GAD_ADD_FILES,
				TAG_DONE);

				LT_New(Handle,
					LA_Type,	BUTTON_KIND,
					LA_LabelID,	MSG_UPLOADQUEUE_ADD_TXT,
					LA_ID,		GAD_ADD,
				TAG_DONE);

				LT_New(Handle,
					LA_Type,	BUTTON_KIND,
					LA_LabelID,	MSG_UPLOADQUEUE_REMOVE_TXT,
					LA_ID,		GAD_REMOVE,
					GA_Disabled,	TRUE,
				TAG_DONE);

				LT_New(Handle,
					LA_Type,	BUTTON_KIND,
					LA_LabelID,	MSG_UPLOADQUEUE_CLEAR_TXT,
					LA_ID,		GAD_CLEAR,
					GA_Disabled,	!TransferCount,
				TAG_DONE);

				LT_EndGroup(Handle);
			}

			LT_New(Handle,
				LA_Type,	VERTICAL_KIND,
			TAG_DONE);
			{
				LT_New(Handle,LA_Type,XBAR_KIND,LAXB_FullSize,TRUE,TAG_DONE);

				LT_EndGroup(Handle);
			}

			LT_New(Handle,LA_Type,HORIZONTAL_KIND,
				LAGR_SameSize,	TRUE,
			TAG_DONE);
			{
				LT_New(Handle,
					LA_Type,	BUTTON_KIND,
					LA_LabelID,	MSG_UPLOADQUEUE_BINARY_UPLOAD_TXT,
					LA_ID,		UPLOAD_BINARY,
					LABT_ExtraFat,	TRUE,
					LABT_ReturnKey,	TRUE,
					GA_Disabled,	!TransferCount,
				TAG_DONE);

				LT_New(Handle,
					LA_Type,	BUTTON_KIND,
					LA_LabelID,	MSG_UPLOADQUEUE_TEXT_UPLOAD_TXT,
					LA_ID,		UPLOAD_TEXT,
					GA_Disabled,	!TransferCount,
				TAG_DONE);

				LT_New(Handle,
					LA_Type,	BUTTON_KIND,
					LA_LabelID,	MSG_UPLOADQUEUE_HIDE_TXT,
					LA_ID,		GAD_HIDE,
					LABT_EscKey,	TRUE,
				TAG_DONE);

				LT_EndGroup(Handle);
			}

			LT_EndGroup(Handle);
		}

		if(LT_Layout(Handle,LocaleString(MSG_UPLOADQUEUE_FILE_UPLOAD_LIST_TXT),NULL,0,0,IDCMP_CLOSEWINDOW,0,
			WA_DepthGadget,		TRUE,
			WA_CloseGadget,		TRUE,
			WA_DragBar,		TRUE,
			WA_RMBTrap,		TRUE,
			WA_Activate,		TRUE,
			LAWN_BelowMouse,	TRUE,
		TAG_DONE))
			return(Handle);

		LT_DeleteHandle(Handle);
	}

	return(NULL);
}

	/* HandleQueueWindow(LayoutHandle *Handle):
	 *
	 *	Process queue panel messages.
	 */

STATIC LONG __regargs
HandleQueueWindow(LayoutHandle *Handle)
{
	struct IntuiMessage	*Message;
	ULONG			 MsgClass,
				 MsgQualifier;
	UWORD			 MsgCode;
	struct Gadget		*MsgGadget;

	struct Node		*Node;

	struct Window		*Window = Handle -> Window;
	LONG			 Result = 0;

	UBYTE		 	 DummyBuffer[MAX_FILENAME_LENGTH],
				*DummyChar;
	struct FileRequester	*FileRequest;

	while(Message = (struct IntuiMessage *)GT_GetIMsg(Window -> UserPort))
	{
		MsgClass	= Message -> Class;
		MsgQualifier	= Message -> Qualifier;
		MsgCode		= Message -> Code;
		MsgGadget	= (struct Gadget *)Message -> IAddress;

		GT_ReplyIMsg(Message);

		LT_HandleInput(Handle,MsgQualifier,&MsgClass,&MsgCode,&MsgGadget);

		if(MsgClass == IDCMP_CLOSEWINDOW)
			Result = GAD_HIDE;

		if(MsgClass == IDCMP_IDCMPUPDATE && MsgGadget -> GadgetID == GAD_NAME)
		{
			LT_LockWindow(Window);

			SplitFileName(LT_GetString(Handle,GAD_NAME),&DummyChar,DummyBuffer);

			if(FileRequest = GetFile(Window,LocaleString(MSG_UPLOADQUEUE_SELECT_FILE_TXT),DummyBuffer,DummyChar,DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SELECT_TXT),FALSE))
			{
				LT_SetAttributes(Handle,GAD_NAME,
					GTST_String,	DummyBuffer,
				TAG_DONE);
			}

			LT_UnlockWindow(Window);

			LT_Activate(Handle,GAD_NAME);
		}

		if(MsgClass == IDCMP_GADGETUP)
		{
			switch(MsgGadget -> GadgetID)
			{
				case GAD_ADD_FILES:

					LT_LockWindow(Window);

					if(!GetCurrentDirName(DummyBuffer,MAX_FILENAME_LENGTH))
						DummyBuffer[0] = 0;

					if(FileRequest = AllocAslRequestTags(ASL_FileRequest,
						ASL_Window,	Window,
						ASL_Hail,	LocaleString(MSG_ADD_FILES_TITLE_TXT),
						ASL_FuncFlags,	FILF_MULTISELECT,
						ASL_OKText,	LocaleString(MSG_ADD_GAD),
						ASL_CancelText,	LocaleString(MSG_DONE_GAD),
						ASL_Dir,	DummyBuffer,
						ASLFR_TextAttr,	&UserFont,
					TAG_DONE))
					{
						LONG i;

						LT_SetAttributes(Handle,GAD_LIST,
							GTLV_Labels,	~0,
						TAG_DONE);

						while(AslRequestTags(FileRequest,TAG_DONE))
						{
							for(i = 0 ; i < FileRequest -> rf_NumArgs ; i++)
							{
								if(FileRequest -> fr_ArgList[i] . wa_Lock)
								{
									if(!NameFromLock(FileRequest -> fr_ArgList[i] . wa_Lock,DummyBuffer,MAX_FILENAME_LENGTH))
										DummyBuffer[0] = 0;
								}
								else
									strcpy(DummyBuffer,FileRequest -> fr_Drawer);

								if(FileRequest -> fr_ArgList[i] . wa_Name)
								{
									if(!AddPart(DummyBuffer,FileRequest -> fr_ArgList[i] . wa_Name,MAX_FILENAME_LENGTH))
										DummyBuffer[0] = 0;
								}

								if(DummyBuffer[0])
								{
									if(Node = (struct Node *)AllocVecPooled(sizeof(struct Node) + 256,MEMF_ANY))
									{
										Node -> ln_Name = (STRPTR)(Node + 1);

										strcpy(Node -> ln_Name,DummyBuffer);

										AddTail(TransferList,Node);

										TransferNode = Node;
										TransferOffset = TransferCount++;
									}
								}
							}

							LT_SetAttributes(Handle,GAD_LIST,
								GTLV_Labels,	TransferList,
								GTLV_Selected,	TransferOffset,
							TAG_DONE);
						}

						LT_SetAttributes(Handle,GAD_LIST,
							GTLV_Labels,	TransferList,
							GTLV_Selected,	TransferOffset,
						TAG_DONE);

						if(TransferCount)
						{
							LT_SetAttributes(Handle,GAD_NAME,
								GTST_String,	"",
							TAG_DONE);

							LT_SetAttributes(Handle,GAD_REMOVE,
								GA_Disabled,	FALSE,
							TAG_DONE);

							LT_SetAttributes(Handle,UPLOAD_BINARY,
								GA_Disabled,	FALSE,
							TAG_DONE);

							LT_SetAttributes(Handle,UPLOAD_TEXT,
								GA_Disabled,	FALSE,
							TAG_DONE);

							LT_SetAttributes(Handle,GAD_CLEAR,
								GA_Disabled,	FALSE,
							TAG_DONE);
						}

						FreeAslRequest(FileRequest);
					}
						
					LT_UnlockWindow(Window);
					break;

				case GAD_ADD:

					if(Node = (struct Node *)AllocVecPooled(sizeof(struct Node) + 256,MEMF_ANY))
					{
						Node -> ln_Name = (STRPTR)(Node + 1);

						Node -> ln_Name[0] = 0;

						LT_SetAttributes(Handle,GAD_LIST,
							GTLV_Labels,	~0,
						TAG_DONE);

						AddTail(TransferList,Node);

						LT_SetAttributes(Handle,GAD_LIST,
							GTLV_Labels,	TransferList,
							GTLV_Selected,	TransferOffset = TransferCount++,
						TAG_DONE);

						LT_SetAttributes(Handle,GAD_NAME,
							GTST_String,	"",
						TAG_DONE);

						LT_SetAttributes(Handle,GAD_REMOVE,
							GA_Disabled,	FALSE,
						TAG_DONE);

						LT_SetAttributes(Handle,UPLOAD_BINARY,
							GA_Disabled,	FALSE,
						TAG_DONE);

						LT_SetAttributes(Handle,UPLOAD_TEXT,
							GA_Disabled,	FALSE,
						TAG_DONE);

						LT_SetAttributes(Handle,GAD_CLEAR,
							GA_Disabled,	FALSE,
						TAG_DONE);

						TransferNode = Node;

						LT_Activate(Handle,GAD_NAME);
					}
					else
						DisplayBeep(Window -> WScreen);

					break;

				case GAD_REMOVE:

					if(TransferNode)
					{
						LT_SetAttributes(Handle,GAD_LIST,
							GTLV_Labels,	~0,
						TAG_DONE);

						if(--TransferCount)
						{
							if(TransferNode -> ln_Succ -> ln_Succ)
								Node = TransferNode -> ln_Succ;
							else
							{
								if(TransferNode -> ln_Pred -> ln_Pred)
								{
									Node = TransferNode -> ln_Pred;

									TransferOffset--;
								}
								else
								{
									TransferOffset = -1;

									Node = NULL;
								}
							}
						}
						else
						{
							TransferOffset = -1;

							Node = NULL;
						}

						Remove(TransferNode);

						FreeVecPooled(TransferNode);

						TransferNode = Node;

						LT_SetAttributes(Handle,GAD_LIST,
							GTLV_Labels,	TransferList,
							GTLV_Selected,	TransferOffset,
						TAG_DONE);

						if(!TransferCount)
						{
							LT_SetAttributes(Handle,GAD_REMOVE,
								GA_Disabled,	TRUE,
							TAG_DONE);

							LT_SetAttributes(Handle,GAD_NAME,
								GTST_String,	"",
							TAG_DONE);

							LT_SetAttributes(Handle,GAD_CLEAR,
								GA_Disabled,	TRUE,
							TAG_DONE);

							LT_SetAttributes(Handle,UPLOAD_BINARY,
								GA_Disabled,	TRUE,
							TAG_DONE);

							LT_SetAttributes(Handle,UPLOAD_TEXT,
								GA_Disabled,	TRUE,
							TAG_DONE);
						}
						else
						{
							LT_SetAttributes(Handle,GAD_NAME,
								GTST_String,	TransferNode -> ln_Name,
							TAG_DONE);
						}
					}

					break;

				case GAD_LIST:

					if(TransferNode = (struct Node *)GetListNode(MsgCode,TransferList))
					{
						TransferOffset = MsgCode;

						LT_SetAttributes(Handle,GAD_NAME,
							GTST_String,	TransferNode -> ln_Name,
						TAG_DONE);

						LT_SetAttributes(Handle,GAD_REMOVE,
							GA_Disabled,	FALSE,
						TAG_DONE);
					}

					break;

				case GAD_NAME:

					if(TransferNode)
					{
						LT_SetAttributes(Handle,GAD_LIST,
							GTLV_Labels,	~0,
						TAG_DONE);

						strcpy(TransferNode -> ln_Name,LT_GetString(Handle,GAD_NAME));

						LT_SetAttributes(Handle,GAD_LIST,
							GTLV_Labels,	TransferList,
							GTLV_Selected,	~0,
						TAG_DONE);
					}
					else
					{
						if(Node = (struct Node *)AllocVecPooled(sizeof(struct Node) + 256,MEMF_ANY))
						{
							Node -> ln_Name = (STRPTR)(Node + 1);

							strcpy(Node -> ln_Name,LT_GetString(Handle,GAD_NAME));

							LT_SetAttributes(Handle,GAD_LIST,
								GTLV_Labels,	~0,
							TAG_DONE);

							AddTail(TransferList,Node);

							TransferCount++;

							LT_SetAttributes(Handle,UPLOAD_BINARY,
								GA_Disabled,	FALSE,
							TAG_DONE);

							LT_SetAttributes(Handle,UPLOAD_TEXT,
								GA_Disabled,	FALSE,
							TAG_DONE);

							LT_SetAttributes(Handle,GAD_CLEAR,
								GA_Disabled,	FALSE,
							TAG_DONE);

							LT_SetAttributes(Handle,GAD_LIST,
								GTLV_Labels,		TransferList,
								GTLV_Selected,		~0,
								GTLV_MakeVisible,	TransferCount - 1,
							TAG_DONE);
						}
					}

					LT_SetAttributes(Handle,GAD_REMOVE,
						GA_Disabled,	TRUE,
					TAG_DONE);

					LT_SetAttributes(Handle,GAD_NAME,
						GTST_String,	"",
					TAG_DONE);

					TransferNode	= NULL;
					TransferOffset	= -1;

					break;

				case GAD_CLEAR:

					LT_SetAttributes(Handle,GAD_LIST,
						GTLV_Labels,	~0,
					TAG_DONE);

					TransferCount	= 0;
					TransferOffset	= -1;
					TransferNode	= NULL;

					FreeList(TransferList);

					LT_SetAttributes(Handle,GAD_REMOVE,
						GA_Disabled,	TRUE,
					TAG_DONE);

					LT_SetAttributes(Handle,GAD_NAME,
						GTST_String,	"",
					TAG_DONE);

					LT_SetAttributes(Handle,GAD_CLEAR,
						GA_Disabled,	TRUE,
					TAG_DONE);

					LT_SetAttributes(Handle,UPLOAD_BINARY,
						GA_Disabled,	TRUE,
					TAG_DONE);

					LT_SetAttributes(Handle,UPLOAD_TEXT,
						GA_Disabled,	TRUE,
					TAG_DONE);

					LT_SetAttributes(Handle,GAD_LIST,
						GTLV_Labels,	TransferList,
						GTLV_Selected,	~0,
					TAG_DONE);

					break;

				case UPLOAD_BINARY:
				case UPLOAD_TEXT:
				case GAD_HIDE:

					Result = MsgGadget -> GadgetID;
					break;
			}
		}
	}

	return(Result);
}

	/* QueueClientDestructor(struct DataMsg *Item):
	 *
	 *	Local msgitem destructor.
	 */

STATIC VOID __stdargs
QueueClientDestructor(struct DataMsg *Item)
{
	Signal(TransferProcess,SIG_HANDSHAKE);
}

	/* QueueEntry(VOID):
	 *
	 *	The entry point for the queue process.
	 */

STATIC VOID __saveds
QueueEntry(VOID)
{
	if(TransferList = (struct List *)AllocVecPooled(sizeof(struct List),MEMF_ANY))
	{
		if(TransferPort = CreateMsgPort())
		{
			struct MsgPort		*AppPort;
			struct AppIcon		*AppIcon;
			struct AppWindow	*AppWindow;
			APTR			 OldPtr;

			NewList(TransferList);

			TransferNode	= NULL;
			TransferOffset	= -1;

			if(AppPort = CreateMsgPort())
			{
				ULONG			 Signals;
				BOOLEAN			 Done = FALSE;
				LayoutHandle		*Handle;
				struct Window		*LocalWindow;
				ULONG			 WindowMask,
							 TransferMask;
				struct AppMessage	*AppMessage;
				struct DiskObject	*LoadedIcon = NULL;

				if(WorkbenchBase)
				{
					if(IconBase)
						LoadedIcon = GetDiskObject("PROGDIR:term_DropIcon");

					AppIcon = AddAppIconA(APP_ICON,NULL,LocaleString(MSG_UPLOADQUEUE_TERM_UPLOAD_LIST_TXT),AppPort,NULL,LoadedIcon ? LoadedIcon : &DropIcon,NULL);
				}
				else
					AppIcon = NULL;

				AppWindow	= NULL;
				WindowMask	= NULL;
				Handle		= NULL;
				LocalWindow	= NULL;
				TransferMask	= PORTMASK(TransferPort);

				TransferProcess = (struct Process *)FindTask(NULL);

				OldPtr = TransferProcess -> pr_WindowPtr;

				Signal(ThisProcess,SIG_HANDSHAKE);

				do
				{
					Signals = Wait(SIG_KILL | SIG_SHOW | SIG_HIDE | SIG_GOAWAY | WindowMask | TransferMask | PORTMASK(AppPort));

					if(Signals & TransferMask)
					{
						struct Message *Message;

						while(Message = GetMsg(TransferPort))
						{
							if(Message -> mn_Node . ln_Name == (APTR)1)
							{
								Message -> mn_Node . ln_Name = NULL;

								if(TransferList -> lh_Head -> ln_Succ)
								{
									struct List *List;

									if(Handle)
									{
										LT_SetAttributes(Handle,GAD_LIST,
											GTLV_Labels,	~0,
										TAG_DONE);
									}

									if(List = (struct List *)AllocVecPooled(sizeof(struct List),MEMF_ANY))
									{
										struct Node *Node,*Next;

										NewList(List);

										for(Node = TransferList -> lh_Head ; Next = Node -> ln_Succ ; Node = Next)
										{
											Remove(Node);

											AddTail(List,Node);
										}

										Message -> mn_Node . ln_Name = (STRPTR)List;
									}

									if(Handle)
									{
										TransferCount = GetListSize(TransferList);
	
										TransferOffset	= -1;
										TransferNode	= NULL;
	
										LT_SetAttributes(Handle,GAD_REMOVE,
											GA_Disabled,	TRUE,
										TAG_DONE);
	
										LT_SetAttributes(Handle,GAD_NAME,
											GTST_String,	"",
										TAG_DONE);
	
										LT_SetAttributes(Handle,GAD_CLEAR,
											GA_Disabled,	!TransferCount,
										TAG_DONE);
	
										LT_SetAttributes(Handle,UPLOAD_BINARY,
											GA_Disabled,	!TransferCount,
										TAG_DONE);
	
										LT_SetAttributes(Handle,UPLOAD_TEXT,
											GA_Disabled,	!TransferCount,
										TAG_DONE);
	
										LT_SetAttributes(Handle,GAD_LIST,
											GTLV_Labels,	TransferList,
										TAG_DONE);
									}
								}

								ReplyMsg(Message);

								continue;
							}

								// Check to see if there is anything in the list?

							if(Message -> mn_Node . ln_Name == (APTR)~0)
							{
								if(TransferList -> lh_Head -> ln_Succ)
									Message -> mn_Node . ln_Name = (APTR)TRUE;
								else
									Message -> mn_Node . ln_Name = (APTR)FALSE;

								ReplyMsg(Message);
							}
							else
							{
								UBYTE		Type = (UBYTE)Message -> mn_Node . ln_Name[0];
								struct DataMsg	Msg;

								ReplyMsg(Message);

								InitMsgItem(&Msg,QueueClientDestructor);

								Msg . Type = DATAMSGTYPE_UPLOAD;
								Msg . Data = (UBYTE *)TransferList;
								Msg . Size = Type;

								if(Handle)
								{
									LT_SetAttributes(Handle,GAD_LIST,
										GTLV_Labels,	~0,
									TAG_DONE);

									LT_LockWindow(LocalWindow);
								}

								Forbid();

								PutMsgItem(SpecialQueue,(struct MsgItem *)&Msg);

								ClrSignal(SIG_HANDSHAKE);

								Wait(SIG_HANDSHAKE);

								Permit();

								if(Handle)
								{
									TransferCount = GetListSize(TransferList);

									TransferOffset	= -1;
									TransferNode	= NULL;

									LT_SetAttributes(Handle,GAD_REMOVE,
										GA_Disabled,	TRUE,
									TAG_DONE);

									LT_SetAttributes(Handle,GAD_NAME,
										GTST_String,	"",
									TAG_DONE);

									LT_SetAttributes(Handle,GAD_CLEAR,
										GA_Disabled,	!TransferCount,
									TAG_DONE);

									LT_SetAttributes(Handle,UPLOAD_BINARY,
										GA_Disabled,	!TransferCount,
									TAG_DONE);

									LT_SetAttributes(Handle,UPLOAD_TEXT,
										GA_Disabled,	!TransferCount,
									TAG_DONE);

									LT_SetAttributes(Handle,GAD_LIST,
										GTLV_Labels,	TransferList,
									TAG_DONE);

									LT_UnlockWindow(LocalWindow);
								}
							}
						}
					}

					if(Signals & SIG_HIDE)
					{
						if(AppWindow)
						{
							RemoveAppWindow(AppWindow);

							AppWindow = NULL;
						}

						if(Handle)
						{
							LT_DeleteHandle(Handle);

							Handle = NULL;
						}

						WindowMask	= NULL;
						LocalWindow	= NULL;

						TransferProcess -> pr_WindowPtr = OldPtr;

						Signal(ThisProcess,SIG_HANDSHAKE);
					}

					if(Signals & SIG_GOAWAY)
					{
						if(Handle)
						{
							if(LocalWindow -> WScreen == Screen)
							{
								if(AppWindow)
								{
									RemoveAppWindow(AppWindow);

									AppWindow = NULL;
								}

								LT_DeleteHandle(Handle);

								Handle		= NULL;
								WindowMask	= NULL;
								LocalWindow	= NULL;

								TransferProcess -> pr_WindowPtr = OldPtr;
							}
						}

						Signal(ThisProcess,SIG_HANDSHAKE);
					}

					if(Signals & SIG_KILL)
						break;

					if(Signals & SIG_SHOW)
					{
						if(!Handle)
						{
							Forbid();

							if(Handle = QueuePanel(Window))
							{
								Permit();

								if(WorkbenchBase)
									AppWindow = AddAppWindowA(APP_WINDOW,NULL,Handle -> Window,AppPort,NULL);
								else
									AppWindow = NULL;

								LocalWindow	= Handle -> Window;
								WindowMask	= PORTMASK(LocalWindow -> UserPort);

								TransferProcess -> pr_WindowPtr = LocalWindow;
							}
							else
								Permit();
						}

						if(Handle)
							LT_ShowWindow(Handle,TRUE);
					}

					if(Signals & WindowMask)
					{
						struct DataMsg	Msg;
						LONG		Type;

						switch(Type = HandleQueueWindow(Handle))
						{
							case GAD_HIDE:

								if(AppWindow)
								{
									RemoveAppWindow(AppWindow);

									AppWindow = NULL;
								}

								if(Handle)
								{
									LT_DeleteHandle(Handle);

									Handle = NULL;
								}

								TransferProcess -> pr_WindowPtr = OldPtr;

								WindowMask	= NULL;
								LocalWindow	= NULL;

								break;

							case UPLOAD_BINARY:
							case UPLOAD_TEXT:

								InitMsgItem(&Msg,QueueClientDestructor);

								Msg . Type = DATAMSGTYPE_UPLOAD;
								Msg . Data = (UBYTE *)TransferList;
								Msg . Size = Type;

								if(Handle)
								{
									LT_SetAttributes(Handle,GAD_LIST,
										GTLV_Labels,	~0,
									TAG_DONE);

									LT_LockWindow(LocalWindow);
								}

								Forbid();

								PutMsgItem(SpecialQueue,(struct MsgItem *)&Msg);

								ClrSignal(SIG_HANDSHAKE);

								Wait(SIG_HANDSHAKE);

								Permit();

								if(Handle)
								{
									TransferCount = GetListSize(TransferList);

									TransferOffset	= -1;
									TransferNode	= NULL;

									LT_SetAttributes(Handle,GAD_REMOVE,
										GA_Disabled,	TRUE,
									TAG_DONE);

									LT_SetAttributes(Handle,GAD_NAME,
										GTST_String,	"",
									TAG_DONE);

									LT_SetAttributes(Handle,GAD_CLEAR,
										GA_Disabled,	!TransferCount,
									TAG_DONE);

									LT_SetAttributes(Handle,UPLOAD_BINARY,
										GA_Disabled,	!TransferCount,
									TAG_DONE);

									LT_SetAttributes(Handle,UPLOAD_TEXT,
										GA_Disabled,	!TransferCount,
									TAG_DONE);

									LT_SetAttributes(Handle,GAD_LIST,
										GTLV_Labels,	TransferList,
									TAG_DONE);

									LT_UnlockWindow(LocalWindow);
								}

								break;
						}
					}

					if(Signals & PORTMASK(AppPort))
					{
						while(AppMessage = (struct AppMessage *)GetMsg(AppPort))
						{
							if(AppMessage -> am_Type == AMTYPE_APPWINDOW && Handle)
							{
								UBYTE	DummyBuffer[MAX_FILENAME_LENGTH];
								BPTR	OldDir,FileLock;
								LONG	i;

								TransferProcess -> pr_WindowPtr = (APTR)-1;

								LT_SetAttributes(Handle,GAD_LIST,
									GTLV_Labels,	~0,
								TAG_DONE);

								for(i = 0 ; i < AppMessage -> am_NumArgs ; i++)
								{
									if(AppMessage -> am_ArgList[i] . wa_Name)
									{
										OldDir = CurrentDir(AppMessage -> am_ArgList[i] . wa_Lock);

										if(GetFileSize(AppMessage -> am_ArgList[i] . wa_Name))
										{
											if(FileLock = Lock(AppMessage -> am_ArgList[i] . wa_Name,ACCESS_READ))
											{
												if(NameFromLock(FileLock,DummyBuffer,MAX_FILENAME_LENGTH))
												{
													struct Node *Node;

													if(Node = (struct Node *)AllocVecPooled(sizeof(struct Node) + 256,MEMF_ANY))
													{
														Node -> ln_Name = (STRPTR)(Node + 1);

														strcpy(Node -> ln_Name,DummyBuffer);

														AddTail(TransferList,Node);

														TransferCount++;
													}
												}

												UnLock(FileLock);
											}
										}

										CurrentDir(OldDir);
									}
								}

								TransferProcess -> pr_WindowPtr = LocalWindow;

								LT_SetAttributes(Handle,GAD_LIST,
									GTLV_Labels,	TransferList,
								TAG_DONE);

								LT_SetAttributes(Handle,GAD_CLEAR,
									GA_Disabled,	!TransferCount,
								TAG_DONE);

								LT_SetAttributes(Handle,UPLOAD_BINARY,
									GA_Disabled,	!TransferCount,
								TAG_DONE);

								LT_SetAttributes(Handle,UPLOAD_TEXT,
									GA_Disabled,	!TransferCount,
								TAG_DONE);
							}

							if(AppMessage -> am_Type == AMTYPE_APPICON)
							{
								if(AppMessage -> am_NumArgs)
								{
									UBYTE	DummyBuffer[MAX_FILENAME_LENGTH];
									BPTR	OldDir,FileLock;
									LONG	i;

									TransferProcess -> pr_WindowPtr = (APTR)-1;

									if(Handle)
									{
										LT_SetAttributes(Handle,GAD_LIST,
											GTLV_Labels,	~0,
										TAG_DONE);
									}

									for(i = 0 ; i < AppMessage -> am_NumArgs ; i++)
									{
										if(AppMessage -> am_ArgList[i] . wa_Name)
										{
											OldDir = CurrentDir(AppMessage -> am_ArgList[i] . wa_Lock);

											if(GetFileSize(AppMessage -> am_ArgList[i] . wa_Name))
											{
												if(FileLock = Lock(AppMessage -> am_ArgList[i] . wa_Name,ACCESS_READ))
												{
													if(NameFromLock(FileLock,DummyBuffer,MAX_FILENAME_LENGTH))
													{
														struct Node *Node;

														if(Node = (struct Node *)AllocVecPooled(sizeof(struct Node) + 256,MEMF_ANY))
														{
															Node -> ln_Name = (STRPTR)(Node + 1);

															strcpy(Node -> ln_Name,DummyBuffer);

															AddTail(TransferList,Node);

															TransferCount++;
														}
													}

													UnLock(FileLock);
												}
											}

											CurrentDir(OldDir);
										}
									}

									if(Handle)
									{
										TransferProcess -> pr_WindowPtr = LocalWindow;

										LT_SetAttributes(Handle,GAD_LIST,
											GTLV_Labels,	TransferList,
										TAG_DONE);

										LT_SetAttributes(Handle,GAD_CLEAR,
											GA_Disabled,	!TransferCount,
										TAG_DONE);

										LT_SetAttributes(Handle,UPLOAD_BINARY,
											GA_Disabled,	!TransferCount,
										TAG_DONE);

										LT_SetAttributes(Handle,UPLOAD_TEXT,
											GA_Disabled,	!TransferCount,
										TAG_DONE);
									}
									else
										TransferProcess -> pr_WindowPtr = OldPtr;
								}
								else
								{
									if(!Handle)
									{
										if(Handle = QueuePanel(NULL))
										{
											AppWindow = AddAppWindowA(APP_WINDOW,NULL,Handle -> Window,AppPort,NULL);

											LocalWindow = Handle -> Window;

											WindowMask = PORTMASK(LocalWindow -> UserPort);

											TransferProcess -> pr_WindowPtr = LocalWindow;
										}
									}
								}
							}

							ReplyMsg(AppMessage);
						}
					}
				}
				while(!Done);

				if(AppIcon)
					RemoveAppIcon(AppIcon);

				if(AppWindow)
					RemoveAppWindow(AppWindow);

				if(LoadedIcon)
					FreeDiskObject(LoadedIcon);

				if(Handle)
					LT_DeleteHandle(Handle);

				while(AppMessage = (struct AppMessage *)GetMsg(AppPort))
					ReplyMsg(AppMessage);
			}

			DeleteMsgPort(TransferPort);
		}

		DeleteList(TransferList);

		TransferList = NULL;
	}

	Forbid();

	TransferProcess = NULL;

	Signal(ThisProcess,SIG_HANDSHAKE);
}

	/* CloseQueueWindow():
	 *
	 *	Close the queue window, wherever it may be.
	 */

VOID
CloseQueueWindow()
{
	if(TransferProcess)
	{
		Forbid();

		ClrSignal(SIG_HANDSHAKE);

		Signal(TransferProcess,SIG_GOAWAY);

		Wait(SIG_HANDSHAKE);

		Permit();
	}
}

	/* DeleteQueueProcess():
	 *
	 *	Terminate the queue handler process.
	 */

VOID
DeleteQueueProcess()
{
	if(TransferProcess)
	{
		Forbid();

		ClrSignal(SIG_HANDSHAKE);

		Signal(TransferProcess,SIG_KILL);

		Wait(SIG_HANDSHAKE);

		Permit();
	}
}

	/* CreateQueueProcess():
	 *
	 *	Create the queue handler process, if it's still around
	 *	bring it to the front.
	 */

BOOLEAN
CreateQueueProcess()
{
	if(!TransferProcess)
	{
		Forbid();

		if(CreateNewProcTags(
			NP_Entry,	QueueEntry,
			NP_Name,	"term Upload process",
			NP_Priority,	SysBase -> ThisTask -> tc_Node . ln_Pri,
			NP_StackSize,	6144,
			NP_WindowPtr,	NULL,
		TAG_DONE))
		{
			ClrSignal(SIG_HANDSHAKE);

			Wait(SIG_HANDSHAKE);
		}

		Permit();
	}
	else
		Signal(TransferProcess,SIG_SHOW);

	return((BOOLEAN)(TransferProcess != NULL));
}

	/* GetUploadList():
	 *
	 *	Copy the current upload list and return it.
	 */

struct List *
GetUploadList()
{
	if(TransferProcess)
	{
		struct Message __aligned Message;
		struct MsgPort __aligned ReplyPort;
	
		InitSinglePort(&ReplyPort);
	
		Message . mn_Node . ln_Name	= (STRPTR)1;
		Message . mn_ReplyPort		= &ReplyPort;
		Message . mn_Length		= sizeof(struct Message);
	
		Forbid();
	
		PutMsg(TransferPort,&Message);
	
		ClrSignal(SIG_HANDSHAKE);
	
		Wait(SIG_HANDSHAKE);
	
		Permit();

		return((struct List *)Message . mn_Node . ln_Name);
	}
	else
		return(NULL);
}

	/* CheckUpload():
	 *
	 *	Check if there is anything in the upload list.
	 */

BOOLEAN
CheckUpload()
{
	BOOLEAN Result = FALSE;

	if(TransferProcess)
	{
		struct Message __aligned Message;
		struct MsgPort __aligned ReplyPort;

		InitSinglePort(&ReplyPort);

		Message . mn_Node . ln_Name	= (APTR)~0;
		Message . mn_ReplyPort		= &ReplyPort;
		Message . mn_Length		= sizeof(struct Message);

		Forbid();

		PutMsg(TransferPort,&Message);

		ClrSignal(SIG_HANDSHAKE);

		Wait(SIG_HANDSHAKE);

		Permit();

		Result = (UBYTE)Message . mn_Node . ln_Name;
	}

	return(Result);
}

	/* StartUpload(UBYTE Type):
	 *
	 *	Start an upload the standard way.
	 */

VOID __stdargs
StartUpload(UBYTE Type)
{
	if(TransferProcess)
	{
		struct Message __aligned Message;
		struct MsgPort __aligned ReplyPort;

		InitSinglePort(&ReplyPort);

		Message . mn_Node . ln_Name	= &Type;
		Message . mn_ReplyPort		= &ReplyPort;
		Message . mn_Length		= sizeof(struct Message);

		Forbid();

		PutMsg(TransferPort,&Message);

		ClrSignal(SIG_HANDSHAKE);

		Wait(SIG_HANDSHAKE);

		Permit();
	}
}
