/*
**	$Id: TransferPanel.c,v 1.13 92/08/15 20:15:37 olsen Sta Locker: olsen $
**	$Revision: 1.13 $
**	$Date: 92/08/15 20:15:37 $
**
**	File transfer control panel support routines
**
**	Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
**		All Rights Reserved
*/

#include "termGlobal.h"

STATIC struct Gadget	*GadgetList;
STATIC BYTE		 LastStatus = -1;

STATIC struct IBox	 TransferBox = { -1, -1, -1, -1 };

STATIC struct Gadget *
CreateAllGadgets(struct TextBox **BoxArray,struct TextBox **BoxList,struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge)
{
	struct Gadget		*Gadget;
	struct NewGadget	 NewGadget;
	UWORD			 Counter	= 0,
				 BoxCounter	= 0;
	struct TextBox		*Box;

	SZ_SizeSetup(Screen,&UserFont,TRUE);

	*BoxList = NULL;

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

	if(Gadget = CreateContext(GadgetList))
	{
		LONG Width,Left;

		SZ_AddLeftOffset(SZ_LeftOffsetN(MSG_TRANSFERPANEL_PROTOCOL_GAD,MSG_GLOBAL_MESSAGE_TXT,MSG_TRANSFERPANEL_ERROR_LIST_GAD,MSG_TRANSFERPANEL_FILE_TXT,MSG_TRANSFERPANEL_FILE_SIZE_TXT,MSG_TRANSFERPANEL_SPACE_LEFT_TXT,MSG_TRANSFERPANEL_BYTES_TRANSFERRED_TXT,MSG_TRANSFERPANEL_BLOCKS_TRANSFERRED_TXT,MSG_TRANSFERPANEL_BLOCK_SIZE_TXT,MSG_TRANSFERPANEL_BLOCK_CHECK_TYPE_TXT,MSG_TRANSFERPANEL_ESTIMATED_TIME_TXT,MSG_TRANSFERPANEL_ELAPSED_TIME_TXT,-1));

		Width = SZ_BoxWidth(16) + INTERWIDTH + SZ_LeftOffsetN(MSG_TRANSFERPANEL_CHARACTERS_PER_SECOND_TXT,MSG_TRANSFERPANEL_CHARACTER_DELAY_TXT,MSG_TRANSFERPANEL_PACKET_DELAY_TXT,MSG_TRANSFERPANEL_PACKET_TYPE_TXT,MSG_TRANSFERPANEL_NUMBER_OF_ERRORS_TXT,MSG_TRANSFERPANEL_NUMBER_OF_TIMEOUTS_TXT,-1) + SZ_BoxWidth(16);

		if(Width > SZ_BoxWidth(50))
			SZ_SetWidth(Width);
		else
			SZ_BoxWidth(50);

		BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(BoxList,
			SZ_Lines,	1,
			SZ_AutoWidth,	TRUE,
		TAG_DONE);

		SZ_SetBoxTitles(Box,LocaleString(MSG_TRANSFERPANEL_PROTOCOL_GAD),NULL);

		BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(BoxList,
			SZ_Lines,	1,
			SZ_AutoWidth,	TRUE,
		TAG_DONE);

		SZ_SetBoxTitles(Box,LocaleString(MSG_GLOBAL_MESSAGE_TXT),NULL);

		NewGadget . ng_TextAttr		= &UserFont;
		NewGadget . ng_VisualInfo	= VisualInfo;
		NewGadget . ng_GadgetText	= LocaleString(MSG_TRANSFERPANEL_ERROR_LIST_GAD);
		NewGadget . ng_GadgetID		= Counter;
		NewGadget . ng_Flags		= PLACETEXT_LEFT;

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

			GT_Underscore,	'_',
			GTLV_ReadOnly,	TRUE,
		TAG_DONE);

		BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(BoxList,
			SZ_Lines,	3,
			SZ_AutoWidth,	TRUE,
		TAG_DONE);

		SZ_SetBoxTitles(Box,LocaleString(MSG_TRANSFERPANEL_FILE_TXT),LocaleString(MSG_TRANSFERPANEL_FILE_SIZE_TXT),LocaleString(MSG_TRANSFERPANEL_SPACE_LEFT_TXT),NULL);

		BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(BoxList,
			SZ_Lines,	4,
			SZ_Chars,	16,
			SZ_SetBelow,	TRUE,
		TAG_DONE);

		SZ_SetBoxTitles(Box,LocaleString(MSG_TRANSFERPANEL_BYTES_TRANSFERRED_TXT),LocaleString(MSG_TRANSFERPANEL_BLOCKS_TRANSFERRED_TXT),LocaleString(MSG_TRANSFERPANEL_BLOCK_SIZE_TXT),LocaleString(MSG_TRANSFERPANEL_BLOCK_CHECK_TYPE_TXT),NULL);

		Left = SZ_GetLeftEdge();

		BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(BoxList,
			SZ_Lines,	4,
			SZ_Chars,	16,
			SZ_AlignRight,	TRUE,
		TAG_DONE);

		SZ_SetBoxTitles(Box,LocaleString(MSG_TRANSFERPANEL_CHARACTERS_PER_SECOND_TXT),LocaleString(MSG_TRANSFERPANEL_CHARACTER_DELAY_TXT),LocaleString(MSG_TRANSFERPANEL_PACKET_DELAY_TXT),LocaleString(MSG_TRANSFERPANEL_PACKET_TYPE_TXT),NULL);

		BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(BoxList,
			SZ_Lines,	2,
			SZ_Chars,	16,
			SZ_UseLeft,	Left,
			SZ_AlignBottom,	TRUE,
			SZ_SetBelow,	TRUE,
		TAG_DONE);

		SZ_SetBoxTitles(Box,LocaleString(MSG_TRANSFERPANEL_ESTIMATED_TIME_TXT),LocaleString(MSG_TRANSFERPANEL_ELAPSED_TIME_TXT),NULL);

		BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(BoxList,
			SZ_Lines,	2,
			SZ_Chars,	16,
			SZ_AlignRight,	TRUE,
		TAG_DONE);

		SZ_SetBoxTitles(Box,LocaleString(MSG_TRANSFERPANEL_NUMBER_OF_ERRORS_TXT),LocaleString(MSG_TRANSFERPANEL_NUMBER_OF_TIMEOUTS_TXT),NULL);

		SZ_SetWidth((SZ_GetWindowWidth() - 3 * InterWidth) / 2);

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

		GadgetArray[Counter++] = Gadget = CreateGadget(TEXT_KIND,Gadget,&NewGadget,
			SZ_Adjust,	TRUE,
			SZ_AutoWidth,	TRUE,
			SZ_AlignLeft,	TRUE,
			SZ_AlignBottom,	TRUE,

			GTTX_Border,	TRUE,
		TAG_DONE);

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

		GadgetArray[Counter++] = Gadget = CreateGadget(TEXT_KIND,Gadget,&NewGadget,
			SZ_Adjust,	TRUE,
			SZ_AutoWidth,	TRUE,
			SZ_AlignRight,	TRUE,
			SZ_UseTop,	SZ_GetTopEdge(),

			GTTX_Border,	TRUE,
		TAG_DONE);

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

		GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
			SZ_Adjust,	TRUE,
			SZ_AutoWidth,	TRUE,
			SZ_AlignLeft,	TRUE,
			SZ_AlignBottom,	TRUE,
			SZ_SetBelow,	TRUE,
			SZ_AlignExtra,	TRUE,

			GT_Underscore,	'_',
		TAG_DONE);

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

		GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
			SZ_Adjust,	TRUE,
			SZ_AutoWidth,	TRUE,
			SZ_AlignRight,	TRUE,

			GT_Underscore,	'_',
		TAG_DONE);
	}

	return(Gadget);
}

VOID
GhostStats(struct Gadget *Gadget)
{
	STATIC ULONG __chip	 Check = 0x5555AAAA;
	struct RastPort		*RPort = TransferWindow -> RPort;
	BYTE			 FgPen = RPort -> FgPen;

	if(Config . DisableBlinking & TERMINAL_FASTER)
	{
		switch(Config . ColourMode)
		{
			case COLOUR_EIGHT:	SetAPen(RPort,7);
						break;

			case COLOUR_SIXTEEN:	SetAPen(RPort,15);
						break;

			default:		SetAPen(RPort,1);
						break;
		}
	}
	else
	{
		switch(Config . ColourMode)
		{
			case COLOUR_EIGHT:	SetAPen(RPort,4);
						break;

			case COLOUR_SIXTEEN:	SetAPen(RPort,8);
						break;

			default:		SetAPen(RPort,1);
						break;
		}
	}

	SetAfPt(RPort,(UWORD *)&Check,1);

	RectFill(RPort,Gadget -> LeftEdge + 2,Gadget -> TopEdge + 1,Gadget -> LeftEdge + Gadget -> Width - 3,Gadget -> TopEdge + Gadget -> Height - 2);

	SetAPen(RPort,FgPen);

	SetAfPt(RPort,NULL,0);
}

VOID
ShowStats(struct Gadget *Gadget,LONG Value,LONG Max)
{
	if(TransferWindow)
	{
		struct RastPort	*RPort = TransferWindow -> RPort;
		LONG		 MaxWidth = Gadget -> Width - 4,Width;

		if(Max < 1)
			Max = 0;

		if(Value > Max)
			Value = Max;

		if((Width = (MaxWidth * Value) / Max) > 0)
		{
			BYTE FgPen = RPort -> FgPen;

			if(Width != MaxWidth)
			{
				SetAPen(RPort,0);

				RectFill(RPort,Gadget -> LeftEdge + 2 + Width - 1,Gadget -> TopEdge + 1,Gadget -> LeftEdge + Gadget -> Width - 3,Gadget -> TopEdge + Gadget -> Height - 2);
			}

			if(Config . DisableBlinking & TERMINAL_FASTER)
			{
				switch(Config . ColourMode)
				{
					case COLOUR_EIGHT:	SetAPen(RPort,7);
								break;

					case COLOUR_SIXTEEN:	SetAPen(RPort,15);
								break;

					default:		SetAPen(RPort,1);
								break;
				}
			}
			else
			{
				switch(Config . ColourMode)
				{
					case COLOUR_EIGHT:	SetAPen(RPort,6);
								break;

					case COLOUR_SIXTEEN:	SetAPen(RPort,7);
								break;

					default:		SetAPen(RPort,3);
								break;
				}
			}

			RectFill(RPort,Gadget -> LeftEdge + 2,Gadget -> TopEdge + 1,Gadget -> LeftEdge + Width + 1,Gadget -> TopEdge + Gadget -> Height - 2);

			SetAPen(RPort,FgPen);
		}
		else
		{
			BYTE FgPen = RPort -> FgPen;

			SetAPen(RPort,0);

			RectFill(RPort,Gadget -> LeftEdge + 2,Gadget -> TopEdge + 1,Gadget -> LeftEdge + Gadget -> Width - 3,Gadget -> TopEdge + Gadget -> Height - 2);

			SetAPen(RPort,FgPen);
		}
	}
}

VOID __stdargs
ShowString(struct Gadget *Gadget,UBYTE *String,...)
{
	if(TransferWindow)
	{
		va_list		 VarArgs;
		WORD		 Len;
		struct RastPort	*RPort = TransferWindow -> RPort;
		BYTE		 FgPen = RPort -> FgPen,
				 DrawMode = RPort -> DrawMode;

		va_start(VarArgs,String);
		VSPrintf(SharedBuffer,String,VarArgs);
		va_end(VarArgs);

		Len = strlen(SharedBuffer);

		Move(RPort,Gadget -> LeftEdge + 2 + (Gadget -> Width - 4 - UserFontWidth * Len) / 2,Gadget -> TopEdge + 1 + (Gadget -> Height - 2 - UserFontHeight) / 2 + UserFontBase);

		if(Config . ColourMode != COLOUR_MONO && !(Config . DisableBlinking & TERMINAL_FASTER))
		{
			switch(Config . ColourMode)
			{
				case COLOUR_AMIGA:	SetAPen(RPort,2);
							break;

				case COLOUR_EIGHT:	SetAPen(RPort,7);
							break;

				case COLOUR_SIXTEEN:	SetAPen(RPort,15);
							break;
			}

			SetDrMd(RPort,JAM1);

			Text(RPort,SharedBuffer,Len);

			SetAPen(RPort,FgPen);
			SetDrMd(RPort,DrawMode);
		}
		else
		{
			SetDrMd(RPort,JAM1|COMPLEMENT);

			Text(RPort,SharedBuffer,Len);

			SetDrMd(RPort,DrawMode);
		}
	}
}

VOID __stdargs
AddTransferInfo(UBYTE *Message,...)
{
	struct Node *Node;

	if(Node = AllocVec(sizeof(struct Node) + strlen(Message) + 51,MEMF_ANY|MEMF_CLEAR))
	{
		va_list VarArgs;

		Node -> ln_Name = (UBYTE *)(Node + 1);

		va_start(VarArgs,Message);
		VSPrintf(Node -> ln_Name,Message,VarArgs);
		va_end(VarArgs);

		GT_SetGadgetAttrs(TransferGadgetArray[GAD_TRANSFER_ERROR_LIST],TransferWindow,NULL,
			GTLV_Labels,	~0,
		TAG_DONE);

		AddHead(&TransferInfoList,Node);

		GT_SetGadgetAttrs(TransferGadgetArray[GAD_TRANSFER_ERROR_LIST],TransferWindow,NULL,
			GTLV_Labels,	&TransferInfoList,
		TAG_DONE);
	}
}

VOID
RefreshTransferWindow()
{
	SZ_DrawBoxes(TransferWindow -> RPort,TransferBoxList);

	GT_RefreshWindow(TransferWindow,NULL);

	GhostStats(TransferGadgetArray[GAD_TRANSFER_PERCENT]);
	GhostStats(TransferGadgetArray[GAD_TRANSFER_TIME]);
}

BYTE
TransferPanel(UBYTE *Title)
{
	if(TransferWindow)
		return(TRUE);
	else
	{
		if(Status != STATUS_DOWNLOAD && Status != STATUS_UPLOAD)
		{
			LastStatus = Status;

			Status = STATUS_DOWNLOAD;
		}
		else
			LastStatus = -1;

		if(CreateAllGadgets(&TransferBoxArray[0],&TransferBoxList,&TransferGadgetArray[0],&GadgetList,VisualInfo,Screen -> WBorTop + Screen -> Font -> ta_YSize + 1))
		{
			TransferBox . Width	= SZ_GetWindowWidth();
			TransferBox . Height	= Screen -> WBorTop + Screen -> Font -> ta_YSize + 1;
	
			TransferBox . Left	= (Screen -> Width	- SZ_GetWindowWidth())	/ 2;
			TransferBox . Top	= (Screen -> Height	- SZ_GetWindowHeight())	/ 2;
	
			if(TransferWindow = OpenWindowTags(NULL,
				WA_Left,		TransferBox . Left,
				WA_Top,			TransferBox . Top,
				WA_Width,		SZ_GetWindowWidth(),
				WA_Height,		SZ_GetWindowHeight(),
	
				WA_DragBar,		TRUE,
				WA_DepthGadget,		TRUE,
				WA_CloseGadget,		TRUE,
				WA_RMBTrap,		TRUE,
				WA_NoCareRefresh,	TRUE,
				WA_SmartRefresh,	TRUE,
				WA_Zoom,		&TransferBox,
	
				WA_CustomScreen,	Screen,
	
				WA_IDCMP,		IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | IDCMP_NEWSIZE | BUTTONIDCMP | LISTVIEWIDCMP | TEXTIDCMP,
	
				WA_Title,		Title,
			TAG_DONE))
			{
				ULONG	IntuiLock = LockIBase(NULL);
				BYTE	Activate,Move;

				if(Config . Alert == ALERT_SCREEN || Config . Alert == ALERT_BEEP_SCREEN)
					Move = Activate = TRUE;
				else
				{
					if(IntuitionBase -> ActiveScreen == TransferWindow -> WScreen)
						Activate = TRUE;
					else
						Activate = FALSE;
				}

				UnlockIBase(IntuiLock);

				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);

				AddGList(TransferWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
				RefreshGList(GadgetList,TransferWindow,NULL,(UWORD)-1);
	
				RefreshTransferWindow();

					/* Protocol */

				SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_1],		0,LocaleString(MSG_GLOBAL_UNKNOWN_TXT));

					/* Message */

				SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_2],		0,"-");

					/* File, File size, Space left */

				SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_3],		0,"-");
				SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_3],		1,"-");
				SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_3],		2,"-");

					/* Bytes transferred, Blocks transferred, Block size, Block check type */

				SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],	0,"-");
				SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],	1,"-");
				SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],	2,"-");
				SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],	3,"-");

					/* Characters per second, Character delay, Packet delay, Packet type */

				SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],	0,"-");
				SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],	1,"-");
				SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],	2,"-");
				SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],	3,"-");

					/* Estimated time, Elapsed time. */

				SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_LEFT2],	0,"-");
				SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_LEFT2],	1,"-");

					/* Number of errors, Number of timeouts. */

				SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_RIGHT2],	0,"-");
				SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_RIGHT2],	1,"-");
	
				return(TRUE);
			}
		}

		return(FALSE);
	}
}

VOID
DeleteTransferPanel()
{
	if(FileMatch)
		MatchEnd(FileAnchor);

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

	LastStatus = -1;

	if(TransferWindow)
	{
		PopWindow();

		CloseWindow(TransferWindow);

		TransferWindow = NULL;
	}

	if(GadgetList)
	{
		FreeGadgets(GadgetList);

		GadgetList = NULL;
	}

	if(TransferBoxList)
	{
		SZ_FreeBoxes(TransferBoxList);

		TransferBoxList = NULL;
	}

	if(TransferInfoList . lh_Head -> ln_Succ)
	{
		struct Node *Node = TransferInfoList . lh_Head,*NextNode;

		while(NextNode = Node -> ln_Succ)
		{
			Remove(Node);

			FreeVec(Node);

			Node = NextNode;
		}
	}
}
