/*
**	TransferPanel.c
**
**	File transfer control panel support routines
**
**	Copyright © 1990-1996 by Olaf `Olsen' Barthel
**		All Rights Reserved
**
**	:ts=4
*/

#ifndef _GLOBAL_H
#include "Global.h"
#endif

STATIC BYTE LastStatus			= -1;
STATIC LONG TransferInfoCount	= 0;

STATIC ULONG __saveds __asm
TransferListViewRender(REG(a0) struct Hook *Hook,REG(a1) struct LVDrawMsg *Msg,REG(a2) struct Node *Node)
{
		/* We only know how to redraw lines. */

	if(Msg->lvdm_MethodID == LV_DRAW)
	{
		struct RastPort	*RPort	= Msg->lvdm_RastPort;
		LONG			 Left	= Msg->lvdm_Bounds.MinX,
						 Top	= Msg->lvdm_Bounds.MinY,
						 Width	= Msg->lvdm_Bounds.MaxX - Msg->lvdm_Bounds.MinX + 1,
						 Height	= Msg->lvdm_Bounds.MaxY - Msg->lvdm_Bounds.MinY + 1,
						 FgPen,BgPen,
						 Len,LabelLen;
		STRPTR			 String = Node->ln_Name;
		UWORD			*Pens;

		Pens = Msg->lvdm_DrawInfo->dri_Pens;

			/* Determine the rendering pens. */

		if(Msg->lvdm_State == LVR_SELECTED)
		{
			FgPen = FILLTEXTPEN;
			BgPen = FILLPEN;
		}
		else
		{
			FgPen = TEXTPEN;
			BgPen = BACKGROUNDPEN;
		}

		FgPen = Pens[FgPen];
		BgPen = Pens[BgPen];

		SetABPenDrMd(RPort,BgPen,BgPen,JAM2);
		RectFill(RPort,Left,Top,Left + 1,Top + Height - 1);

		Left	+= 2;
		Width	-= 2;

			/* Is this an error message? */

		if(*String++ == '*' && BgPen != Pens[HIGHLIGHTTEXTPEN])
			FgPen = Pens[HIGHLIGHTTEXTPEN];

			/* Determine length of vanilla name. */

		LabelLen = strlen(String);

			/* Try to make it fit. */

		while(LabelLen > 0 && (Len = TextLength(RPort,String,LabelLen)) > Width)
			LabelLen--;

			/* Print the vanilla name if possible. */

		if(LabelLen)
		{
			SetAPen(RPort,FgPen);

			PlaceText(RPort,Left,Top,String,LabelLen);

			Left	+= Len;
			Width	-= Len;
		}

			/* Fill the area to follow the vanilla name. */

		if(Width > 0)
		{
			SetAPen(RPort,BgPen);
			FillBox(RPort,Left,Top,Width,Height);
		}

			/* If the item happens to be disabled, draw the cross-hatch
			 * pattern across it.
			 */

		ListViewStateFill(Msg);

		return(LVCB_OK);
	}
	else
		return(LVCB_UNKNOWN);
}

	/* AddTransferInfo(STRPTR Message,...):
	 *
	 *	Add another entry to the transfer information list.
	 */

VOID __stdargs
AddTransferInfo(BOOL Error,STRPTR Message,...)
{
	STATIC UBYTE __far TempBuffer[256];

	struct Node	*Node;
	va_list		 VarArgs;

	if(Kick30)
	{
		va_start(VarArgs,Message);
		VSPrintf(&TempBuffer[1],Message,VarArgs);
		va_end(VarArgs);

		if(Error)
			TempBuffer[0] = '*';
		else
			TempBuffer[0] = ' ';
	}
	else
	{
		va_start(VarArgs,Message);
		VSPrintf(TempBuffer,Message,VarArgs);
		va_end(VarArgs);
	}

	if(Node = CreateNode(TempBuffer))
	{
		LT_SetAttributes(TransferHandle,GAD_TRANSFER_INFORMATION_LIST,
			GTLV_Labels,	~0,
		TAG_DONE);

		if(TransferInfoCount == 100)
		{
			FreeVecPooled(RemHead(&TransferInfoList));

			TransferInfoCount = 99;
		}

		AddTail(&TransferInfoList,Node);

		LT_SetAttributes(TransferHandle,GAD_TRANSFER_INFORMATION_LIST,
			GTLV_Labels,		&TransferInfoList,
			GTLV_Top,			TransferInfoCount,
			GTLV_MakeVisible,	TransferInfoCount,
		TAG_DONE);

		TransferInfoCount++;
	}
}

	/* TransferPanel(STRPTR Title):
	 *
	 *	Open the transfer window.
	 */

BOOL
TransferPanel(STRPTR Title)
{
	if(TransferWindow)
		return(TRUE);
	else
	{
		STATIC struct Hook ListViewHook =
		{
			{NULL},
			(HOOKFUNC)TransferListViewRender
		};

		TransferFailed = TransferAborted = FALSE;

		if(Status != STATUS_DOWNLOAD && Status != STATUS_UPLOAD)
		{
			LastStatus = Status;

			Status = STATUS_DOWNLOAD;
		}
		else
			LastStatus = -1;

		if(Window)
			TransferHandle = LT_CreateHandleTags(Window->WScreen,LH_LocaleHook,&LocaleHook,TAG_DONE);
		else
			TransferHandle = LT_CreateHandleTags(NULL,LH_LocaleHook,&LocaleHook,TAG_DONE);

		if(TransferHandle)
		{
			STATIC LONG LabelGroups[5][2] =
			{
				MSG_TRANSFERPANEL_FILE_TXT,
					MSG_TRANSFERPANEL_COMPLETION_TIME_TXT,

				MSG_TRANSFERPANEL_FILE_SIZE_TXT,
					MSG_TRANSFERPANEL_BLOCKS_TRANSFERRED_TXT,

				MSG_TRANSFERPANEL_ESTIMATED_TIME_TXT,
					MSG_TRANSFERPANEL_ELAPSED_TIME_TXT,

				MSG_TRANSFERPANEL_CHARACTERS_PER_SECOND_TXT,
					MSG_TRANSFERPANEL_BLOCK_SIZE_TXT,

				MSG_TRANSFERPANEL_NUMBER_OF_ERRORS_TXT,
					MSG_TRANSFERPANEL_NUMBER_OF_TIMEOUTS_TXT,
			};

			struct IBox Bounds;
			LONG len,max,i,j;

			max = LT_LabelChars(TransferHandle,LocaleString(MSG_TRANSFERPANEL_PROTOCOL_TXT));
			len = LT_LabelChars(TransferHandle,LocaleString(MSG_TRANSFERPANEL_INFORMATION_GAD));

			if(len > max)
				max = len;

			for(i = 0 ; i < 5 ; i++)
			{
				for(j = LabelGroups[i][0] ; j <= LabelGroups[i][1] ; j++)
				{
					len = LT_LabelChars(TransferHandle,LocaleString(j));

					if(len > max)
						max = len;
				}
			}

			LT_New(TransferHandle,
				LA_Type,VERTICAL_KIND,
			TAG_DONE);
			{
				LT_New(TransferHandle,
					LA_Type,VERTICAL_KIND,
				TAG_DONE);
				{
					LT_New(TransferHandle,
						LA_Type,VERTICAL_KIND,
					TAG_DONE);
					{
						UBYTE	LocalBuffer[60];
						WORD	Len;

						strcpy(LocalBuffer,FilePart(LastXprLibrary));

						if((Len = strlen(LocalBuffer)) > 3)
						{
							UBYTE	ProtocolBuffer[60];
							WORD	i;

							strcpy(ProtocolBuffer,&LocalBuffer[3]);

							for(i = 0 ; i < Len - 3 ; i++)
							{
								if(ProtocolBuffer[i] == '.')
								{
									ProtocolBuffer[i] = 0;

									break;
								}
							}

							ProtocolBuffer[0] = ToUpper(ProtocolBuffer[0]);

							SPrintf(LocalBuffer,"[%s]",ProtocolBuffer);
						}
						else
							strcpy(LocalBuffer,"-");

						LT_New(TransferHandle,
							LA_Type,			TEXT_KIND,
							LA_LabelID,			MSG_TRANSFERPANEL_PROTOCOL_TXT,
							LA_LabelChars,		max,
							LA_Chars,			50,
							LA_ID,				GAD_TRANSFER_PROTOCOL,
							GTTX_Text,			LocalBuffer,
							GTTX_CopyText,		TRUE,
							GTTX_Border,		TRUE,
						TAG_DONE);

						LT_New(TransferHandle,
							LA_Type,			LISTVIEW_KIND,
							LA_LabelID,			MSG_TRANSFERPANEL_INFORMATION_GAD,
							LA_LabelChars,		max,
							LA_LabelPlace,		PLACE_LEFT,
							LA_ID,				GAD_TRANSFER_INFORMATION_LIST,
							LA_Chars,			50,
							LA_Lines,			2,
							LALV_MaxGrowY,		10,
							LALV_CursorKey,		TRUE,
							GTLV_ReadOnly,		TRUE,
							GTLV_CallBack,		&ListViewHook,
							GTLV_MaxPen,		MAX(TransferHandle->DrawInfo->dri_Pens[BLOCKPEN],MAX(TransferHandle->DrawInfo->dri_Pens[TEXTPEN],MAX(TransferHandle->DrawInfo->dri_Pens[BACKGROUNDPEN],MAX(TransferHandle->DrawInfo->dri_Pens[FILLTEXTPEN],MAX(TransferHandle->DrawInfo->dri_Pens[FILLPEN],TransferHandle->DrawInfo->dri_Pens[HIGHLIGHTTEXTPEN]))))),
						TAG_DONE);

						LT_New(TransferHandle,
							LA_Type,			XBAR_KIND,
						TAG_DONE);

						LT_New(TransferHandle,
							LA_Type,			BOX_KIND,
							LA_ID,				GAD_TRANSFER_FILE,
							LA_Chars,			50,
							LA_LabelChars,		max,
							LABX_FirstLabel,	MSG_TRANSFERPANEL_FILE_TXT,
							LABX_LastLabel,		MSG_TRANSFERPANEL_COMPLETION_TIME_TXT,
							LABX_ReserveSpace,	TRUE,
						TAG_DONE);

						LT_New(TransferHandle,
							LA_Type,			XBAR_KIND,
						TAG_DONE);

						LT_EndGroup(TransferHandle);
					}

					LT_New(TransferHandle,
						LA_Type,HORIZONTAL_KIND,
					TAG_DONE);
					{
						LT_New(TransferHandle,
							LA_Type,VERTICAL_KIND,
						TAG_DONE);
						{
							LT_New(TransferHandle,
								LA_Type,			BOX_KIND,
								LA_ID,				GAD_TRANSFER_SIZE,
								LA_LabelChars,		max,
								LA_Chars,			15,
								LABX_FirstLabel,	MSG_TRANSFERPANEL_FILE_SIZE_TXT,
								LABX_LastLabel,		MSG_TRANSFERPANEL_BLOCKS_TRANSFERRED_TXT,
								LABX_ReserveSpace,	TRUE,
							TAG_DONE);

							LT_New(TransferHandle,
								LA_Type,			BOX_KIND,
								LA_LabelChars,		max,
								LA_ID,				GAD_TRANSFER_TOTALTIME,
								LABX_FirstLabel,	MSG_TRANSFERPANEL_ESTIMATED_TIME_TXT,
								LABX_LastLabel,		MSG_TRANSFERPANEL_ELAPSED_TIME_TXT,
								LABX_ReserveSpace,	TRUE,
							TAG_DONE);

							LT_EndGroup(TransferHandle);
						}

						LT_New(TransferHandle,
							LA_Type,				VERTICAL_KIND,
							LAGR_LastAttributes,	TRUE,
						TAG_DONE);
						{
							LT_New(TransferHandle,
								LA_Type,			BOX_KIND,
								LA_ID,				GAD_TRANSFER_SECONDS,
								LA_LabelChars,		max,
								LA_Chars,			15,
								LABX_FirstLabel,	MSG_TRANSFERPANEL_CHARACTERS_PER_SECOND_TXT,
								LABX_LastLabel,		MSG_TRANSFERPANEL_BLOCK_SIZE_TXT,
								LABX_ReserveSpace,	TRUE,
							TAG_DONE);

							LT_New(TransferHandle,
								LA_Type,			BOX_KIND,
								LA_ID,				GAD_TRANSFER_ERRORS,
								LA_LabelChars,		max,
								LABX_FirstLabel,	MSG_TRANSFERPANEL_NUMBER_OF_ERRORS_TXT,
								LABX_LastLabel,		MSG_TRANSFERPANEL_NUMBER_OF_TIMEOUTS_TXT,
								LABX_ReserveSpace,	TRUE,
							TAG_DONE);

							LT_EndGroup(TransferHandle);
						}

						LT_EndGroup(TransferHandle);
					}

					LT_New(TransferHandle,
						LA_Type,HORIZONTAL_KIND,
					TAG_DONE);
					{
						LT_New(TransferHandle,
							LA_Type,XBAR_KIND,
						TAG_DONE);

						LT_EndGroup(TransferHandle);
					}

					LT_New(TransferHandle,
						LA_Type,		HORIZONTAL_KIND,
						LAGR_SameSize,	TRUE,
						LAGR_Spread,	TRUE,
					TAG_DONE);
					{
						LONG len1,len2,max;

						len1 = 4 + strlen(LocaleString(MSG_TRANSFERPANEL_DATA_TRANSFERRED_GAD)) + 1;
						len2 = 8 + strlen(LocaleString(MSG_TRANSFERPANEL_TIME_TO_GO_GAD)) + 1;

						if(len1 > len2)
							max = len1;
						else
							max = len2;

						if(max < 30)
							max = 30;

						LT_New(TransferHandle,
							LA_Type,		GAUGE_KIND,
							LA_Chars,		max,
							LA_LabelPlace,	PLACE_IN,
							LA_ID,			GAD_TRANSFER_PERCENT,
							LAGA_NoTicks,	TRUE,
							LAGA_InfoLength,len1,
						TAG_DONE);

						LT_New(TransferHandle,
							LA_Type,		GAUGE_KIND,
							LA_LabelPlace,	PLACE_IN,
							LA_ID,			GAD_TRANSFER_TIME,
							LAGA_NoTicks,	TRUE,
							LAGA_InfoLength,len2,
						TAG_DONE);

						LT_EndGroup(TransferHandle);
					}

					LT_EndGroup(TransferHandle);
				}

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

					LT_EndGroup(TransferHandle);
				}

				LT_New(TransferHandle,LA_Type,HORIZONTAL_KIND,
					LAGR_Spread,TRUE,
				TAG_DONE);
				{
					LT_New(TransferHandle,
						LA_Type,		BUTTON_KIND,
						LA_LabelID,		MSG_TRANSFERPANEL_SKIP_CURRENT_FILE_GAD,
						LA_ID,			GAD_TRANSFER_SKIP,
						LABT_ExtraFat,	TRUE,
					TAG_DONE);

					LT_New(TransferHandle,
						LA_Type,		BUTTON_KIND,
						LA_LabelID,		MSG_TRANSFERPANEL_ABORT_CURRENT_FILE_GAD,
						LA_ID,			GAD_TRANSFER_ABORT_FILE,
						LABT_ExtraFat,	TRUE,
					TAG_DONE);

					LT_New(TransferHandle,
						LA_Type,		BUTTON_KIND,
						LA_LabelID,		MSG_TRANSFERPANEL_ABORT_ENTIRE_TRANSFER_GAD,
						LA_ID,			GAD_TRANSFER_ABORT,
						LABT_EscKey,	TRUE,
						LABT_ExtraFat,	TRUE,
					TAG_DONE);

					LT_EndGroup(TransferHandle);
				}

				LT_EndGroup(TransferHandle);
			}

			TransferZoomed = FALSE;

			if(Window)
			{
				Bounds.Left	= WindowLeft + Window->LeftEdge;
				Bounds.Top	= WindowTop + Window->TopEdge;
			}
			else
			{
				Bounds.Left	= WindowLeft;
				Bounds.Top	= WindowTop;
			}

			Bounds.Width	= WindowWidth;
			Bounds.Height	= WindowHeight;

			if(TransferWindow = LT_Layout(TransferHandle,TransferWindowTitle = Title,&Bounds,0,0,IDCMP_CLOSEWINDOW,0,
				LAWN_HelpHook,		&GuideHook,
//				LAWN_Parent,		Window,
				WA_DepthGadget,		TRUE,
				WA_CloseGadget,		TRUE,
				WA_DragBar,			TRUE,
				WA_RMBTrap,			TRUE,
				LAWN_Zoom,			TRUE,
			TAG_DONE))
			{
				BOOL	Activate,Move;
				LONG	i;

				GuideContext(CONTEXT_TRANSFER);

				if(Config->MiscConfig->AlertMode == ALERT_SCREEN || Config->MiscConfig->AlertMode == ALERT_BEEP_SCREEN)
					Move = Activate = TRUE;
				else
				{
					ULONG IntuiLock = LockIBase(NULL);

					Activate = Move = FALSE;

					if(IntuitionBase->ActiveScreen == Screen)
						Activate = TRUE;
					else
					{
						if(IntuitionBase->ActiveWindow && IntuitionBase->ActiveWindow->UserPort && IntuitionBase->ActiveWindow->UserPort->mp_Flags == PA_SIGNAL && IntuitionBase->ActiveWindow->UserPort->mp_SigTask == FindTask(NULL))
							Activate = TRUE;
					}

					UnlockIBase(IntuiLock);
				}

				if(Config->TransferConfig->TransferNotification == XFERNOTIFY_NEVER || Config->TransferConfig->TransferNotification == XFERNOTIFY_END)
					Move = Activate = FALSE;

				if(Move)
				{
					if(TransferWindow->WScreen->LeftEdge > 0)
					{
						if(TransferWindow->WScreen->TopEdge > 0)
							MoveScreen(TransferWindow->WScreen,-TransferWindow->WScreen->LeftEdge,-TransferWindow->WScreen->TopEdge);
						else
							MoveScreen(TransferWindow->WScreen,-TransferWindow->WScreen->LeftEdge,0);
					}
					else
					{
						if(TransferWindow->WScreen->TopEdge > 0)
							MoveScreen(TransferWindow->WScreen,0,-TransferWindow->WScreen->TopEdge);
					}

					WindowToFront(TransferWindow);

					ScreenToFront(TransferWindow->WScreen);
				}

				if(Activate)
					ActivateWindow(TransferWindow);

				PushWindow(TransferWindow);

				for(i = 0 ; i < 6 ; i++)
				{
					if(i < 4)
					{
						if(i < 2)
						{
							LT_SetAttributes(TransferHandle,GAD_TRANSFER_TOTALTIME,
								LABX_Index,	i,
								LABX_Text,	"-",
							TAG_DONE);

							LT_SetAttributes(TransferHandle,GAD_TRANSFER_ERRORS,
								LABX_Index,	i,
								LABX_Text,	"-",
							TAG_DONE);
						}

						LT_SetAttributes(TransferHandle,GAD_TRANSFER_FILE,
							LABX_Index,	i,
							LABX_Text,	"-",
						TAG_DONE);
					}

					LT_SetAttributes(TransferHandle,GAD_TRANSFER_SIZE,
						LABX_Index,	i,
						LABX_Text,	"-",
					TAG_DONE);

					LT_SetAttributes(TransferHandle,GAD_TRANSFER_SECONDS,
						LABX_Index,	i,
						LABX_Text,	"-",
					TAG_DONE);
				}

				return(TRUE);
			}

			LT_DeleteHandle(TransferHandle);

			TransferHandle = NULL;
		}
	}

	return(FALSE);
}

	/* DeleteTransferPanel(BOOL WaitForPrompt):
	 *
	 *	Close the transfer window.
	 */

VOID
DeleteTransferPanel(BOOL WaitForPrompt)
{
		/* Can any pending garbage. */

	if(TransferError)
		FlushSerialRead();

		/* Wait for user to close the window? */

	if(WaitForPrompt && TransferHandle)
	{
		struct IntuiMessage	*Message;
		BOOL				 Done = FALSE;
		ULONG				 MsgClass,
							 MsgQualifier;
		UWORD				 MsgCode;
		struct Gadget		*MsgGadget;

		LT_SetAttributes(TransferHandle,GAD_TRANSFER_SKIP,
			GA_Disabled,	TRUE,
		TAG_DONE);

		LT_SetAttributes(TransferHandle,GAD_TRANSFER_ABORT_FILE,
			GA_Disabled,	TRUE,
		TAG_DONE);

		do
		{
			if(Wait(PORTMASK(TransferWindow->UserPort) | SIG_BREAK) & SIG_BREAK)
				break;

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

				GT_ReplyIMsg(Message);

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

				if(MsgClass == IDCMP_CLOSEWINDOW || (MsgClass == IDCMP_GADGETUP && MsgGadget->GadgetID == GAD_TRANSFER_ABORT))
					Done = TRUE;
			}
		}
		while(!Done);
	}

	TransferAbortState = 0;
	TransferAbortCount = 0;

	TransferError = FALSE;

	if(FileTransferInfo)
	{
		FreeFileTransferInfo(FileTransferInfo);

		FileTransferInfo = NULL;
	}

	if(LastStatus != -1)
		Status = LastStatus;

	LastStatus = -1;

	if(TransferHandle)
	{
		LT_DeleteHandle(TransferHandle);

		TransferHandle = NULL;
	}

	if(TransferInfoList.lh_Head->ln_Succ)
	{
		FreeList(&TransferInfoList);

		TransferInfoCount = 0;
	}

	TransferWindow = NULL;

	ReleaseWindows();
}
