/*
**	$Id: TransferPanel.c,v 1.8 92/05/01 12:51:55 olsen Sta Locker: olsen $
**	$Revision: 1.8 $
**	$Date: 92/05/01 12:51:55 $
**
**	File transfer control panel support routines
**
**	Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
**		All Rights Reserved
*/

#include "termGlobal.h"

struct TwoStrings
{
	STRPTR	Left,
		Right;
};

STATIC struct TwoStrings *TransferStrings;

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

STATIC WORD		 PositionX = -1,
			 PositionY = -1;

STATIC UBYTE		 LineOffsets[] = {  0, 8,16, 0,30,38,46,54, 0,67,75 };

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

#define WIDTH		564
#define HEIGHT		198

#define ORIGIN_X	10
#define ORIGIN_Y	(14+50)

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

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

	if(Gadget = CreateContext(GadgetList))
	{
		NewGadget . ng_TextAttr		= &DefaultFont;
		NewGadget . ng_VisualInfo	= VisualInfo;
		NewGadget . ng_Width		= (WIDTH - 30) >> 1;
		NewGadget . ng_Height		= 12;
		NewGadget . ng_GadgetText	= LocaleString(MSG_TRANSFERPANEL_ABORT_ENTIRE_TRANSFER_GAD);
		NewGadget . ng_GadgetID		= Counter;
		NewGadget . ng_Flags		= 0;
		NewGadget . ng_LeftEdge		= 10;
		NewGadget . ng_TopEdge		= HEIGHT - 3 - NewGadget . ng_Height;

		GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
			GT_Underscore,	'_',
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_TRANSFERPANEL_SKIP_CURRENT_FILE_GAD);
		NewGadget . ng_GadgetID		= Counter;
		NewGadget . ng_LeftEdge		= WIDTH - 10 - NewGadget . ng_Width;

		GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
			GT_Underscore,	'_',
		TAG_DONE);

		NewGadget . ng_Height		= 12;
		NewGadget . ng_GadgetText	= LocaleString(MSG_TRANSFERPANEL_DATA_TRANSFERRED_GAD);
		NewGadget . ng_GadgetID		= Counter;
		NewGadget . ng_Flags		= PLACETEXT_ABOVE;
		NewGadget . ng_LeftEdge		= 10;
		NewGadget . ng_TopEdge		= HEIGHT - 3 - NewGadget . ng_Height - 16;

		GadgetArray[Counter++] = Gadget = CreateGadget(TEXT_KIND,Gadget,&NewGadget,
			GTTX_Border,	TRUE,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_TRANSFERPANEL_TIME_TO_GO_GAD);
		NewGadget . ng_GadgetID		= Counter;
		NewGadget . ng_LeftEdge		= WIDTH - 10 - NewGadget . ng_Width;

		GadgetArray[Counter++] = Gadget = CreateGadget(TEXT_KIND,Gadget,&NewGadget,
			GTTX_Border,	TRUE,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_TRANSFERPANEL_PROTOCOL_GAD);
		NewGadget . ng_GadgetID		= Counter;
		NewGadget . ng_TopEdge		= 1 + TopEdge;
		NewGadget . ng_LeftEdge		= 10 + 88 + 64;
		NewGadget . ng_Height		= 12;
		NewGadget . ng_Width		= WIDTH - 20 - 88 - 64;
		NewGadget . ng_Flags		= PLACETEXT_LEFT;

		GadgetArray[Counter++] = Gadget = CreateGadget(TEXT_KIND,Gadget,&NewGadget,
			GTTX_Text,	LocaleString(MSG_GLOBAL_UNKNOWN_TXT),
			GTTX_Border,	TRUE,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_GLOBAL_MESSAGE_TXT);
		NewGadget . ng_GadgetID		= Counter;
		NewGadget . ng_TopEdge		= NewGadget . ng_TopEdge + NewGadget . ng_Height + 2;

		GadgetArray[Counter++] = Gadget = CreateGadget(TEXT_KIND,Gadget,&NewGadget,
			GTTX_Text,	LocaleString(MSG_TRANSFERPANEL_NO_MESSAGE_TXT),
			GTTX_Border,	TRUE,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_TRANSFERPANEL_ERROR_LIST_GAD);
		NewGadget . ng_GadgetID		= Counter;
		NewGadget . ng_TopEdge		= NewGadget . ng_TopEdge + NewGadget . ng_Height + 2;
		NewGadget . ng_Height		= 20;

		GadgetArray[Counter++] = Gadget = CreateGadget(LISTVIEW_KIND,Gadget,&NewGadget,
			GT_Underscore,	'_',
			GTLV_ReadOnly,	TRUE,
		TAG_DONE);
	}

	return(Gadget);
}

VOID __stdargs
TransferInfo(WORD X,WORD Y,BYTE *String,...)
{
	if(String && TransferWindow)
	{
		va_list	VarArgs;
		WORD	Len;

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

		if(!strncmp(String,"%10ld ",6))
		{
			strcat(SharedBuffer,"                                   ");

			SharedBuffer[47] = 0;

			Len = 47;
		}
		else
		{
			if(!Stricmp(String,"%ld") || !Stricmp(String,"%10ld") || !Stricmp(String,"`%lc'"))
			{
				strcat(SharedBuffer,"              ");

				SharedBuffer[11] = 0;

				Len = 11;
			}
			else
				Len = 50;
		}

		Move(TransferWindow -> RPort,ORIGIN_X + 4 + X * 8,ORIGIN_Y + 6 + LineOffsets[Y]);
		Text(TransferWindow -> RPort,SharedBuffer,strlen(SharedBuffer));

		if(X == 19)
		{
			if(TransferStrings[Y] . Left)
				strcpy(TransferStrings[Y] . Left,SharedBuffer);
			else
			{
				if(TransferStrings[Y] . Left = AllocVec(Len + 1,MEMF_ANY))
					strcpy(TransferStrings[Y] . Left,SharedBuffer);
			}
		}
		else
		{
			if(TransferStrings[Y] . Right)
				strcpy(TransferStrings[Y] . Right,SharedBuffer);
			else
			{
				if(TransferStrings[Y] . Right = AllocVec(Len + 1,MEMF_ANY))
					strcpy(TransferStrings[Y] . Right,SharedBuffer);
			}
		}
	}
}

STATIC VOID __stdargs
TransferText(WORD Y,UBYTE *String,...)
{
	va_list	VarArgs;

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

	Move(TransferWindow -> RPort,ORIGIN_X,ORIGIN_Y + 6 + LineOffsets[Y]);
	Text(TransferWindow -> RPort,SharedBuffer,strlen(SharedBuffer));
}

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;

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

		Len = strlen(SharedBuffer);

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

		if(Config . ColourMode != COLOUR_MONO && !(Config . DisableBlinking & TERMINAL_FASTER))
		{
			BYTE FgPen = RPort -> FgPen,DrawMode = RPort -> DrawMode;

			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
			Text(RPort,SharedBuffer,Len);
	}
}

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[6],TransferWindow,NULL,
			GTLV_Labels,	~0,
		TAG_DONE);

		AddHead(&TransferInfoList,Node);

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

VOID
RefreshTransferWindow()
{
	WORD i;

	DrawBevelBox(TransferWindow -> RPort,162, 62,392,28,
		GTBB_Recessed,	TRUE,
		GT_VisualInfo,	VisualInfo,
	TAG_DONE);

	DrawBevelBox(TransferWindow -> RPort,162, 92,112,35,
		GTBB_Recessed,	TRUE,
		GT_VisualInfo,	VisualInfo,
	TAG_DONE);

	DrawBevelBox(TransferWindow -> RPort,162,129,112,20,
		GTBB_Recessed,	TRUE,
		GT_VisualInfo,	VisualInfo,
	TAG_DONE);

	DrawBevelBox(TransferWindow -> RPort,441, 92,112,35,
		GTBB_Recessed,	TRUE,
		GT_VisualInfo,	VisualInfo,
	TAG_DONE);

	DrawBevelBox(TransferWindow -> RPort,441,129,112,20,
		GTBB_Recessed,	TRUE,
		GT_VisualInfo,	VisualInfo,
	TAG_DONE);

	switch(Config . ColourMode)
	{
		case COLOUR_EIGHT:	SetAPen(TransferWindow -> RPort,7);
					break;

		case COLOUR_SIXTEEN:	SetAPen(TransferWindow -> RPort,15);
					break;

		default:		SetAPen(TransferWindow -> RPort,1);
					break;
	}

	SetDrMd(TransferWindow -> RPort,JAM1);

	TransferText( 0,LocaleString(MSG_TRANSFERPANEL_FILE_TXT));
	TransferText( 1,LocaleString(MSG_TRANSFERPANEL_FILE_SIZE_TXT));
	TransferText( 2,LocaleString(MSG_TRANSFERPANEL_SPACE_LEFT_TXT));

	TransferText( 4,LocaleString(MSG_TRANSFERPANEL_BYTES_TRANSFERRED_CHARACTERS_PER_SECOND_TXT));
	TransferText( 5,LocaleString(MSG_TRANSFERPANEL_BLOCKS_TRANSFERRED_CHARACTER_DELAY_TXT));
	TransferText( 6,LocaleString(MSG_TRANSFERPANEL_BLOCK_SIZE_PACKET_DELAY_TXT));
	TransferText( 7,LocaleString(MSG_TRANSFERPANEL_BLOCK_CHECK_TYPE_PACKET_TYPE_TXT));

	TransferText( 9,LocaleString(MSG_TRANSFERPANEL_ESTIMATED_TIME_NUMBER_OF_ERRORS_TXT));
	TransferText(10,LocaleString(MSG_TRANSFERPANEL_ELAPSED_TIME_NUMBER_OF_TIMEOUTS_TXT));

	SetBPen(TransferWindow -> RPort,0);
	SetDrMd(TransferWindow -> RPort,JAM2);

	GT_RefreshWindow(TransferWindow,NULL);

	GhostStats(TransferGadgetArray[2]);
	GhostStats(TransferGadgetArray[3]);

	for(i = 0 ; i < 11 ; i++)
	{
		if(TransferStrings[i] . Left)
		{
			Move(TransferWindow -> RPort,ORIGIN_X + 4 + 19 * 8,ORIGIN_Y + 6 + LineOffsets[i]);
			Text(TransferWindow -> RPort,TransferStrings[i] . Left,strlen(TransferStrings[i] . Left));
		}

		if(TransferStrings[i] . Right)
		{
			Move(TransferWindow -> RPort,ORIGIN_X + 4 + 54 * 8,ORIGIN_Y + 6 + LineOffsets[i]);
			Text(TransferWindow -> RPort,TransferStrings[i] . Right,strlen(TransferStrings[i] . Right));
		}
	}
}

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(TransferStrings = (struct TwoStrings *)AllocVec(sizeof(struct TwoStrings) * 11,MEMF_ANY | MEMF_CLEAR))
		{
			if(CreateAllGadgets(&TransferGadgetArray[0],&GadgetList,VisualInfo,Screen -> WBorTop + Screen -> Font -> ta_YSize + 1))
			{
				if(PositionX == -1)
				{
					PositionX = (Screen -> Width - WIDTH) >> 1;
					PositionY = (Screen -> Height - HEIGHT) >> 1;
	
					TransferBox . Width	= WIDTH;
					TransferBox . Height	= 11;
				}
	
				TransferBox . Left	= PositionX;
				TransferBox . Top	= PositionY;
	
				if(TransferWindow = OpenWindowTags(NULL,
					WA_Width,		WIDTH,
					WA_Height,		HEIGHT,
	
					WA_Left,		PositionX,
					WA_Top,			PositionY,
	
					WA_Activate,		TRUE,
					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))
				{
					PushWindow(TransferWindow);
	
					AddGList(TransferWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
					RefreshGList(GadgetList,TransferWindow,NULL,(UWORD)-1);
	
					RefreshTransferWindow();
	
					TransferInfo(19, 0,"-");
					TransferInfo(19, 1,"-");
					TransferInfo(19, 2,"-");
	
					TransferInfo(19, 4,"-");
					TransferInfo(54, 4,"-");
					TransferInfo(19, 5,"-");
					TransferInfo(54, 5,"-");
					TransferInfo(19, 6,"-");
					TransferInfo(54, 6,"-");
					TransferInfo(19, 7,"-");
					TransferInfo(54, 7,"-");
	
					TransferInfo(19, 9,"-");
					TransferInfo(54, 9,"-");
					TransferInfo(19,10,"-");
					TransferInfo(54,10,"-");
	
					return(TRUE);
				}
			}
		}

		return(FALSE);
	}
}

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

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

	LastStatus = -1;

	if(TransferWindow)
	{
		PositionX = TransferWindow -> LeftEdge;
		PositionY = TransferWindow -> TopEdge;

		if(GadgetList)
			RemoveGList(TransferWindow,GadgetList,(UWORD)-1);

		PopWindow();

		CloseWindow(TransferWindow);

		TransferWindow = NULL;
	}

	if(GadgetList)
	{
		FreeGadgets(GadgetList);

		GadgetList = 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;
		}
	}

	if(TransferStrings)
	{
		WORD i;

		for(i = 0 ; i < 11 ; i++)
		{
			if(TransferStrings[i] . Left)
				FreeVec(TransferStrings[i] . Left);

			if(TransferStrings[i] . Right)
				FreeVec(TransferStrings[i] . Right);
		}

		FreeVec(TransferStrings);

		TransferStrings = NULL;
	}
}
