/*
**	ASCIIPanel.c
**
**	User interface for built-in ASCII transfer routines
**
**	Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
**		All Rights Reserved
*/

#include "termGlobal.h"

enum	{	GAD_BYTES,GAD_LINES,GAD_INFORMATION,GAD_CHARDELAY,GAD_LINEDELAY,GAD_PACING,GAD_QUIET_TRANSFER,
		GAD_ABORT,GAD_SKIP };

STATIC STRPTR		 PacingMode[7];
STATIC struct Gadget	*GadgetList = NULL,
			*GadgetArray[GAD_SKIP + 1];
STATIC struct List	 MessageList;
STATIC LONG		 MessageCount;

STATIC STRPTR __saveds
ShowTime(struct Gadget *SomeGadget,WORD Level)
{
	return(LocaleSeconds(Level));
}

STATIC struct Gadget *
CreateAllGadgets(BYTE Send)
{
	struct Gadget		*Gadget;
	struct NewGadget	 NewGadget;
	UWORD			 Counter = 0;

	LocalizeString(PacingMode,MSG_ASCIIPANEL_DIRECT_TXT,MSG_ASCIIPANEL_KEYDELAY_TXT);

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

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

	if(Gadget = CreateContext(&GadgetList))
	{
		LONG Width;

		if(Send)
			SZ_AddLeftOffset(SZ_LeftOffsetDelta(MSG_ASCIIPANEL_CHAR_DELAY_GAD,MSG_ASCIIPANEL_INFORMATION_GAD));
		else
			SZ_AddLeftOffset(SZ_LeftOffsetDelta(MSG_ASCIIPANEL_BYTES_GAD,MSG_ASCIIPANEL_INFORMATION_GAD));

		SZ_ResetMaxWidth();

		SZ_UpdateMaxWidth(CYCLE_KIND,NULL,0,PacingMode);
		SZ_UpdateMaxWidth(TEXT_KIND,NULL,10,NULL);
		SZ_UpdateMaxWidth(LISTVIEW_KIND,NULL,40,NULL);

		Width = SZ_ResetMaxWidth();

		if(Width < 108)
			Width = 108;

		SZ_SetWidth(Width);

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

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

			GTTX_Text,		"-",
			GTTX_Border,		TRUE,
		TAG_DONE);

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

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

			GTTX_Text,		"-",
			GTTX_Border,		TRUE,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_ASCIIPANEL_INFORMATION_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,	4,

			GTLV_ReadOnly,	TRUE,
		TAG_DONE);

		if(Send)
		{
			NewGadget . ng_GadgetText	= LocaleString(MSG_ASCIIPANEL_CHAR_DELAY_GAD);
			NewGadget . ng_GadgetID		= Counter;

			GadgetArray[Counter++] = Gadget = CreateGadget(SLIDER_KIND,Gadget,&NewGadget,
				SZ_Adjust,		TRUE,
				SZ_AutoWidth,		TRUE,
				SZ_AlignExtra,		TRUE,

				GTSL_Min,		0,
				GTSL_Max,		10 * 100,
				GTSL_Level,		Config -> ClipConfig -> CharDelay,
				GTSL_MaxLevelLen,	7,
				GTSL_LevelFormat,	"%s s",
				GTSL_DispFunc,		ShowTime,
				PGA_Freedom,		LORIENT_HORIZ,
				GA_Immediate,		TRUE,
				GA_RelVerify,		TRUE,
			TAG_DONE);

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

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

				GTSL_Min,		0,
				GTSL_Max,		10 * 100,
				GTSL_Level,		Config -> ClipConfig -> LineDelay,
				GTSL_MaxLevelLen,	7,
				GTSL_LevelFormat,	"%s s",
				GTSL_DispFunc,		ShowTime,
				PGA_Freedom,		LORIENT_HORIZ,
				GA_Immediate,		TRUE,
				GA_RelVerify,		TRUE,
			TAG_DONE);

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

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

				GTCY_Labels,	PacingMode,
				GTCY_Active,	Config -> ClipConfig -> PacingMode,
			TAG_DONE);

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

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

				GTCB_Checked,	Config -> TransferConfig -> QuietTransfer,
			TAG_DONE);
		}
		else
			Counter = GAD_ABORT;

		if(Send)
		{
			SZ_SetWidth((SZ_GetWindowWidth() - 3 * InterWidth) / 2);

			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_AlignExtra,	TRUE,
				SZ_Adjust,	TRUE,
				SZ_AutoWidth,	TRUE,
				SZ_AlignLeft,	TRUE,
				SZ_AlignBottom,	TRUE,
			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,
			TAG_DONE);
		}
		else
		{
			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_AlignExtra,	TRUE,
				SZ_Adjust,	TRUE,
				SZ_AutoWidth,	TRUE,
				SZ_AlignBottom,	TRUE,
			TAG_DONE);
		}
	}

	return(Gadget);
}

VOID
DeleteASCIIWindow(struct Window *Window,BYTE WaitForIt)
{
	if(WaitForIt)
	{
		BYTE Done;
		WORD i;

		for(i = GAD_CHARDELAY ; i <= GAD_SKIP ; i++)
		{
			if(i != GAD_ABORT && GadgetArray[i])
			{
				GT_SetGadgetAttrs(GadgetArray[i],Window,NULL,
					GA_Disabled,TRUE,
				TAG_DONE);
			}
		}

		do
		{
			if(!(Done = HandleASCIIWindow(Window)))
				WaitPort(Window -> UserPort);
		}
		while(!Done);
	}

	if(GadgetList)
	{
		RemoveGList(Window,GadgetList,(UWORD)-1);

		FreeGadgets(GadgetList);

		GadgetList = NULL;
	}

	FreeList(&MessageList);

	PopWindow();

	CloseWindow(Window);
}

struct Window *
CreateASCIIWindow(BYTE Send)
{
	NewList(&MessageList);

	MessageCount = 0;

	memset(GadgetArray,0,sizeof(GadgetArray));

	GadgetList = NULL;

	if(CreateAllGadgets(Send))
	{
		struct Window *PanelWindow;

		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_DepthGadget,	TRUE,
			WA_CloseGadget,	TRUE,
			WA_CustomScreen,Window -> WScreen,

			WA_IDCMP,	IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | TEXTIDCMP | SLIDERIDCMP | BUTTONIDCMP | CYCLEIDCMP,
			WA_Title,	Send ? LocaleString(MSG_ASCIIPANEL_SENDING_TXT) : LocaleString(MSG_ASCIIPANEL_RECEIVING_TXT),
		TAG_DONE))
		{
			ULONG	IntuiLock = LockIBase(NULL);
			BYTE	Activate,Move;

			GuideContext(CONTEXT_ASCII);

			if(Config -> TerminalConfig -> AlertMode == ALERT_SCREEN || Config -> TerminalConfig -> AlertMode == ALERT_BEEP_SCREEN)
				Move = Activate = TRUE;
			else
			{
				if(IntuitionBase -> ActiveScreen == PanelWindow -> WScreen)
					Activate = TRUE;
				else
					Activate = FALSE;
			}

			UnlockIBase(IntuiLock);

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

				WindowToFront(PanelWindow);

				ScreenToFront(PanelWindow -> WScreen);
			}

			if(Activate)
				ActivateWindow(PanelWindow);

			PushWindow(PanelWindow);

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

			return(PanelWindow);
		}
	}

	FreeGadgets(GadgetList);

	GadgetList = NULL;

	return(NULL);
}

VOID __stdargs
AddASCIIMessage(struct Window *Window,STRPTR Message,...)
{
	STATIC UBYTE TempBuffer[256];

	struct Node	*Node;
	va_list		 VarArgs;

	va_start(VarArgs,Message);
	VSPrintf(TempBuffer,Message,VarArgs);
	va_end(VarArgs);

	if(Node = CreateNode(TempBuffer))
	{
		GT_SetGadgetAttrs(GadgetArray[GAD_INFORMATION],Window,NULL,
			GTLV_Labels,~0,
		TAG_DONE);

		AddTail(&MessageList,Node);

		GT_SetGadgetAttrs(GadgetArray[GAD_INFORMATION],Window,NULL,
			GTLV_Labels,		&MessageList,
			GTLV_Top,		MessageCount,
			GTLV_MakeVisible,	MessageCount,
		TAG_DONE);

		MessageCount++;
	}
}

VOID __regargs
UpdateASCIIWindow(struct Window *Window,LONG Bytes,LONG MaxBytes,LONG Lines)
{
	if(Bytes != -1)
	{
		if(MaxBytes)
		{
			LONG Percent = (100 * Bytes) / MaxBytes;

			if(Percent > 100)
				Percent = 100;

			if(LocaleBase)
				SPrintf(SharedBuffer,"%lD (%ld%%)",Bytes,Percent);
			else
				SPrintf(SharedBuffer,"%ld (%ld%%)",Bytes,Percent);
		}
		else
			SPrintf(SharedBuffer,ConvNumber,Bytes);

		GT_SetGadgetAttrs(GadgetArray[GAD_BYTES],Window,NULL,
			GTTX_Text,SharedBuffer,
		TAG_DONE);
	}

	if(Lines != -1)
	{
		SPrintf(SharedBuffer,ConvNumber,Lines);

		GT_SetGadgetAttrs(GadgetArray[GAD_LINES],Window,NULL,
			GTTX_Text,SharedBuffer,
		TAG_DONE);
	}
}

BYTE
HandleASCIIWindow(struct Window *Window)
{
	struct IntuiMessage	*Massage;
	ULONG			 IClass,Code;
	struct Gadget		*Gadget;

	while(Massage = (struct IntuiMessage *)GT_GetIMsg(Window -> UserPort))
	{
		IClass	= Massage -> Class;
		Code	= Massage -> Code;
		Gadget	= (struct Gadget *)Massage -> IAddress;

		GT_ReplyIMsg(Massage);

		KeySelect(GadgetArray,GAD_SKIP,Code,Window,&Gadget,&IClass,&Code);

		if(IClass == IDCMP_CLOSEWINDOW)
			return(1);

		if(IClass == IDCMP_MOUSEMOVE)
		{
			switch(Gadget -> GadgetID)
			{
				case GAD_CHARDELAY:

					Config -> ClipConfig -> CharDelay = Code;

					SendSetup();

					ConfigChanged = TRUE;

					break;

				case GAD_LINEDELAY:

					Config -> ClipConfig -> LineDelay = Code;

					SendSetup();

					ConfigChanged = TRUE;

					break;
			}
		}

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

					Config -> ClipConfig -> PacingMode = Code;

					SendSetup();

					ConfigChanged = TRUE;

					break;

				case GAD_CHARDELAY:

					Config -> ClipConfig -> CharDelay = Code;

					SendSetup();

					ConfigChanged = TRUE;

					break;

				case GAD_LINEDELAY:

					Config -> ClipConfig -> LineDelay = Code;

					SendSetup();

					ConfigChanged = TRUE;

					break;

				case GAD_QUIET_TRANSFER:

					Config -> TransferConfig -> QuietTransfer = SZ_GetChecked(Gadget);

					ConfigChanged = TRUE;

					break;

				case GAD_ABORT:

					return(1);

				case GAD_SKIP:

					return(2);
			}
		}
	}

	return(0);
}
