/*
**	SerialPanel.c
**
**	Editing panel for serial configuration
**
**	Copyright © 1990-1994 by Olaf `Olsen' Barthel
**		All Rights Reserved
*/

#include "termGlobal.h"

enum	{	GAD_BAUD=1000,GAD_DATABITS,GAD_PARITY,GAD_STOPBITS,GAD_HANDSHAKING,GAD_DUPLEX,GAD_BUFFERSIZE,GAD_BREAKLENGTH,
		GAD_STRIP,GAD_HIGHSPEED,GAD_CHECK_CARRIER,GAD_SHARED,GAD_XON_XOFF,GAD_PASSTHROUGH,
		GAD_DEVICE,GAD_SELECT,GAD_UNIT,GAD_QUANTUM,GAD_USE_OWNDEVUNIT,
		GAD_SATISFY_ODU,GAD_USE,GAD_CANCEL,GAD_DEFAULT
	};

STATIC LONG Sizes[] =
{
	16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288
};

STATIC LONG __saveds
ShowBaud(struct Gadget *SomeGadget,WORD Level)
{
	return(BaudRates[Level]);
}

STATIC LONG __saveds
ShowSize(struct Gadget *SomeGadget,WORD Level)
{
	return(Sizes[Level]);
}

STATIC LONG __saveds __asm
RateHookFunc(register __a2 LONG Current,register __a1 LONG Command)
{
	LONG Index;

	if(Current < BaudRates[0])
		Current = BaudRates[Index = 0];
	else
	{
		if(Current > BaudRates[NumBaudRates - 1])
			Current = BaudRates[Index = NumBaudRates - 1];
		else
		{
			LONG i;

			Index = -1;

			for(i = 0 ; i < NumBaudRates ; i++)
			{
				if(Current == BaudRates[i])
				{
					switch(Command)
					{
						case INCREMENTERMSG_DECREMENT:

							if(i > 0)
								return(BaudRates[i - 1]);
							else
								return(Current);

						case INCREMENTERMSG_INCREMENT:

							if(i < NumBaudRates - 1)
								return(BaudRates[i + 1]);
							else
								return(Current);

						default:

							return(Current);
					}
				}
			}

			if(Index == -1)
			{
				if(Command == INCREMENTERMSG_DECREMENT)
				{
					for(i = 0 ; i < NumBaudRates ; i++)
					{
						if(BaudRates[i] <= Current)
							Index = i;
					}

					if(BaudRates[Index] < Current || !Index)
						return(BaudRates[Index]);
					else
						return(BaudRates[Index - 1]);
				}
				else
				{
					for(i = NumBaudRates - 1 ; i >= 0 ; i--)
					{
						if(BaudRates[i] >= Current)
							Index = i;
					}

					if(Command == INCREMENTERMSG_INITIAL)
					{
						if(Index == -1)
							return(Current);
						else
							return(BaudRates[Index]);
					}
					else
					{
						if(BaudRates[Index] > Current || Index == NumBaudRates - 1)
							return(BaudRates[Index]);
						else
							return(BaudRates[Index + 1]);
					}
				}
			}
		}
	}

	if(Index == -1 || (Command != INCREMENTERMSG_DECREMENT && Command != INCREMENTERMSG_INCREMENT))
		return(Current);
	else
	{
		if(Command == INCREMENTERMSG_DECREMENT)
		{
			if(Index > 0)
				return(BaudRates[Index - 1]);
			else
				return(BaudRates[Index]);
		}
		else
		{
			if(Index < NumBaudRates - 1)
				return(BaudRates[Index + 1]);
			else
				return(BaudRates[Index]);
		}
	}
}

BYTE __regargs
SerialPanel(struct Configuration *Config,BYTE *Default)
{
	STATIC struct Hook IncrementerHook =
	{
		{NULL},
		(HOOKFUNC)RateHookFunc
	};

	struct LayoutHandle	*Handle;
	BYTE			 Cancel = FALSE;

	SaveConfig(Config,PrivateConfig);

	if(Handle = LT_CreateHandleTags(Window -> WScreen,
		LH_LocaleHook,	&LocaleHook,
	TAG_DONE))
	{
		struct Window	*PanelWindow;
		LONG		 Rate,Size,Quantum,Bits,StopBits,i;

		for(i = 0 ; i < NumBaudRates ; i++)
		{
			if(Config -> SerialConfig -> BaudRate == BaudRates[i])
			{
				Rate = i;

				break;
			}
		}

		for(i = 4 ; i < sizeof(Sizes) / sizeof(LONG) ; i++)
		{
			if(Config -> SerialConfig -> SerialBufferSize == Sizes[i])
			{
				Size = i;

				break;
			}
		}

		for(i = 0 ; i < sizeof(Sizes) / sizeof(LONG) ; i++)
		{
			if(Config -> SerialConfig -> Quantum == Sizes[i])
			{
				Quantum = i;

				break;
			}
		}

		if(Config -> SerialConfig -> HighSpeed)
		{
			Config -> SerialConfig -> BitsPerChar	= 8;
			Config -> SerialConfig -> StopBits	= 1;
			Config -> SerialConfig -> Parity	= PARITY_NONE;
		}

		LT_New(Handle,
			LA_Type,	VERTICAL_KIND,
		TAG_DONE);
		{
			LT_New(Handle,
				LA_Type,	HORIZONTAL_KIND,
				LA_LabelID,	MSG_V36_0171,
			TAG_DONE);
			{
				LT_New(Handle,
/*					LA_LabelID,	MSG_V36_0171,*/
					LA_Type,	VERTICAL_KIND,
				TAG_DONE);
				{
/*
					LT_New(Handle,
						LA_Type,		SliderType,
						LA_LabelID,		MSG_SERIALPANEL_BAUD_RATE_GAD,
						LA_LONG,		&Rate,
						GTSL_Min,		0,
						GTSL_Max,		NumBaudRates - 1,
						GTSL_DispFunc,		ShowBaud,
						GTSL_LevelFormat,	LocaleBase ? "%7lD" : "%7ld",
					TAG_DONE);
*/

					LT_New(Handle,
						LA_Type,		INTEGER_KIND,
						LA_LabelID,		MSG_SERIALPANEL_BAUD_RATE_GAD,
						LA_LONG,		&Config -> SerialConfig -> BaudRate,
						LA_ID,			GAD_BAUD,
						GTIN_MaxChars,		8,
						LAIN_Min,		0,
						LAIN_UseIncrementers,	TRUE,
						LAIN_IncrementerHook,	&IncrementerHook,
					TAG_DONE);

					Bits = Config -> SerialConfig -> BitsPerChar - 7;

					LT_New(Handle,
						LA_Type,		CYCLE_KIND,
						LA_ID,			GAD_DATABITS,
						LA_LabelID,		MSG_SERIALPANEL_BITS_PER_CHAR_GAD,
						LA_LONG,		&Bits,
						GA_Disabled,		Config -> SerialConfig -> HighSpeed,
						LACY_FirstLabel,	MSG_SERIALPANEL_SEVEN_BITS_TXT,
						LACY_LastLabel,		MSG_SERIALPANEL_EIGHT_BITS_TXT,
					TAG_DONE);

					LT_New(Handle,
						LA_Type,		CYCLE_KIND,
						LA_ID,			GAD_PARITY,
						LA_LabelID,		MSG_SERIALPANEL_PARITY_GAD,
						LA_BYTE,		&Config -> SerialConfig -> Parity,
						GA_Disabled,		Config -> SerialConfig -> HighSpeed,
						LACY_FirstLabel,	MSG_SERIALPANEL_NO_PARITY_TXT,
						LACY_LastLabel,		MSG_SERIALPANEL_SPACE_TXT,
					TAG_DONE);

					StopBits = Config -> SerialConfig -> StopBits - 1;

					LT_New(Handle,
						LA_Type,		CYCLE_KIND,
						LA_ID,			GAD_STOPBITS,
						LA_LabelID,		MSG_SERIALPANEL_STOP_BITS_GAD,
						LA_LONG,		&StopBits,
						GA_Disabled,		Config -> SerialConfig -> HighSpeed,
						LACY_FirstLabel,	MSG_SERIALPANEL_ONE_BIT_TXT,
						LACY_LastLabel,		MSG_SERIALPANEL_TWO_BITS_TXT,
					TAG_DONE);

					LT_New(Handle,
						LA_Type,		CYCLE_KIND,
						LA_LabelID,		MSG_SERIALPANEL_HANDSHAKING_GAD,
						LA_BYTE,		&Config -> SerialConfig -> HandshakingProtocol,
						LACY_FirstLabel,	MSG_SERIALPANEL_HANDSHAKING_NONE_TXT,
						LACY_LastLabel,		MSG_SERIALPANEL_HANDSHAKING_RTS_CTS_DSR_TXT,
					TAG_DONE);

					LT_New(Handle,
						LA_Type,		CYCLE_KIND,
						LA_LabelID,		MSG_SERIALPANEL_DUPLEX_GAD,
						LA_BYTE,		&Config -> SerialConfig -> Duplex,
						LACY_FirstLabel,	MSG_SERIALPANEL_DUPLEX_FULL_TXT,
						LACY_LastLabel,		MSG_SERIALPANEL_DUPLEX_HALF_TXT,
					TAG_DONE);

					LT_New(Handle,
						LA_Type,		SliderType,
						LA_LabelID,		MSG_SERIALPANEL_BUFFER_SIZE_GAD,
						LA_LONG,		&Size,
						GTSL_Min,		4,
						GTSL_Max,		(sizeof(Sizes) / sizeof(LONG)) - 1,
						GTSL_DispFunc,		ShowSize,
						GTSL_LevelFormat,	LocaleBase ? "%7lD" : "%7ld",
					TAG_DONE);

					LT_New(Handle,
						LA_Type,		INTEGER_KIND,
						LA_LabelID,		MSG_SERIALPANEL_BREAK_LENGTH_GAD,
						LA_LONG,		&Config -> SerialConfig -> BreakLength,
						GTIN_MaxChars,		8,
					TAG_DONE);

					LT_EndGroup(Handle);
				}

				LT_New(Handle,
					LA_Type,VERTICAL_KIND,
				TAG_DONE);
				{
					LT_New(Handle,
						LA_Type,YBAR_KIND,
					TAG_DONE);

					LT_EndGroup(Handle);
				}

				LT_New(Handle,
/*					LA_LabelID,	MSG_V36_0176,*/
					LA_Type,	VERTICAL_KIND,
				TAG_DONE);
				{
					LT_New(Handle,
						LA_Type,		CHECKBOX_KIND,
						LA_LabelID,		MSG_SERIALPANEL_STRIP_BIT_8_GAD,
						LA_BYTE,		&Config -> SerialConfig -> StripBit8,
					TAG_DONE);

					LT_New(Handle,
						LA_Type,		CHECKBOX_KIND,
						LA_LabelID,		MSG_SERIALPANEL_SHARED_ACCESS_GAD,
						LA_BYTE,		&Config -> SerialConfig -> Shared,
					TAG_DONE);

					LT_New(Handle,
						LA_Type,		CHECKBOX_KIND,
						LA_LabelID,		MSG_SERIALPANEL_XON_XOFF_GAD,
						LA_BYTE,		&Config -> SerialConfig -> xONxOFF,
					TAG_DONE);

					LT_New(Handle,
						LA_Type,		CHECKBOX_KIND,
						LA_LabelID,		MSG_SERIALPANEL_PASS_XON_XOFF_THROUGH_GAD,
						LA_BYTE,		&Config -> SerialConfig -> PassThrough,
					TAG_DONE);

					LT_New(Handle,
						LA_Type,		CHECKBOX_KIND,
						LA_LabelID,		MSG_SERIALPANEL_CHECK_CARRIER_GAD,
						LA_BYTE,		&Config -> SerialConfig -> CheckCarrier,
					TAG_DONE);

					LT_New(Handle,
						LA_Type,		CHECKBOX_KIND,
						LA_LabelID,		MSG_SERIALPANEL_HIGH_SPEED_MODE_GAD,
						LA_BYTE,		&Config -> SerialConfig -> HighSpeed,
						LA_ID,			GAD_HIGHSPEED,
					TAG_DONE);

					LT_New(Handle,
						LA_Type,		SliderType,
						LA_LabelID,		MSG_SERIALPANEL_QUANTUM_GAD,
						LA_LONG,		&Quantum,
						LA_Chars,		6,
						GTSL_Min,		0,
						GTSL_Max,		(sizeof(Sizes) / sizeof(LONG)) - 1,
						GTSL_Level,		Quantum,
						GTSL_DispFunc,		ShowSize,
						GTSL_LevelFormat,	LocaleBase ? "%7lD" : "%7ld",
					TAG_DONE);

					LT_EndGroup(Handle);
				}

				LT_EndGroup(Handle);
			}

			LT_New(Handle,
				LA_LabelID,	MSG_ODU_SUPPORT_TXT,
				LA_Type,	VERTICAL_KIND,
			TAG_DONE);
			{
				LT_New(Handle,
					LA_Type,	VERTICAL_KIND,
				TAG_DONE);
				{
					LT_New(Handle,
						LA_Type,		CHECKBOX_KIND,
						LA_LabelID,		MSG_SERIALPANEL_USE_OWNDEVUNIT_TXT,
						LA_BYTE,		&Config -> SerialConfig -> UseOwnDevUnit,
						LA_ID,			GAD_USE_OWNDEVUNIT,
					TAG_DONE);

					LT_EndGroup(Handle);
				}

				LT_New(Handle,
					LA_Type,	VERTICAL_KIND,
				TAG_DONE);
				{
					LT_New(Handle,
						LA_Type,		CYCLE_KIND,
						LA_LabelID,		MSG_SATISFY_ODU_TXT,
						LA_BYTE,		&Config -> SerialConfig -> SatisfyODURequests,
						LA_ID,			GAD_SATISFY_ODU,
						LACY_FirstLabel,	MSG_SATISFY_ODU_MODE1_TXT,
						LACY_LastLabel,		MSG_SATISFY_ODU_MODE3_TXT,
						GA_Disabled,		!Config -> SerialConfig -> UseOwnDevUnit,
					TAG_DONE);

					LT_EndGroup(Handle);
				}

				LT_EndGroup(Handle);
			}

			LT_New(Handle,
				LA_LabelID,	MSG_V36_0179,
				LA_Type,	VERTICAL_KIND,
			TAG_DONE);
			{
				LT_New(Handle,
					LA_Type,		STRING_KIND,
					LA_LabelID,		MSG_SERIALPANEL_SERIAL_DEVICE_GAD,
					LA_Chars,		20,
					LA_STRPTR,		Config -> SerialConfig -> SerialDevice,
					GTST_MaxChars,		255,
					LAST_Picker,		TRUE,
					LA_ID,			GAD_DEVICE,
				TAG_DONE);

				LT_New(Handle,
					LA_Type,		INTEGER_KIND,
					LA_LabelID,		MSG_SERIALPANEL_DEVICE_UNIT_NUMBER_GAD,
					LA_LONG,		&Config -> SerialConfig -> UnitNumber,
					LA_ID,			GAD_UNIT,
					LAIN_UseIncrementers,	TRUE,
					GTIN_MaxChars,		8,
				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,
				LAGR_Spread,	TRUE,
			TAG_DONE);
			{
				LT_New(Handle,
					LA_Type,	BUTTON_KIND,
					LA_LabelID,	MSG_GLOBAL_USE_GAD,
					LA_ID,		GAD_USE,
					LABT_ReturnKey,	TRUE,
					LABT_ExtraFat,	TRUE,
				TAG_DONE);

				if(Default)
				{
					LT_New(Handle,
						LA_Type,	BUTTON_KIND,
						LA_LabelID,	MSG_GLOBAL_DEFAULT_GAD,
						LA_ID,		GAD_DEFAULT,
						LABT_ExtraFat,	TRUE,
					TAG_DONE);
				}

				LT_New(Handle,
					LA_Type,	BUTTON_KIND,
					LA_LabelID,	MSG_GLOBAL_CANCEL_GAD,
					LA_ID,		GAD_CANCEL,
					LABT_EscKey,	TRUE,
					LABT_ExtraFat,	TRUE,
				TAG_DONE);

				LT_EndGroup(Handle);
			}

			LT_EndGroup(Handle);
		}

		if(PanelWindow = LT_Layout(Handle,LocaleString(MSG_SERIALPANEL_SERIAL_PREFERENCES_TXT),NULL,0,0,IDCMP_CLOSEWINDOW,0,
			LAWN_HelpHook,		&GuideHook,
			LAWN_Parent,		Window,
			WA_DepthGadget,		TRUE,
			WA_CloseGadget,		TRUE,
			WA_DragBar,		TRUE,
			WA_RMBTrap,		TRUE,
			WA_Activate,		TRUE,
		TAG_DONE))
		{
			UBYTE			 DummyBuffer[MAX_FILENAME_LENGTH];
			struct IntuiMessage	*Message;
			BOOLEAN			 Done = FALSE;
			ULONG			 MsgClass,
						 MsgQualifier;
			UWORD			 MsgCode;
			struct Gadget		*MsgGadget;

			GuideContext(CONTEXT_SERIAL);

			PushWindow(PanelWindow);

			LT_ShowWindow(Handle,TRUE);

			do
			{
				if(Wait(PORTMASK(PanelWindow -> UserPort) | SIG_BREAK) & SIG_BREAK)
				{
					SaveConfig(PrivateConfig,Config);

					break;
				}

				while(Message = (struct IntuiMessage *)GT_GetIMsg(PanelWindow -> 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)
					{
						SaveConfig(PrivateConfig,Config);

						Done = TRUE;
					}

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

								LT_SetAttributes(Handle,GAD_SATISFY_ODU,
									GA_Disabled,!MsgCode,
								TAG_DONE);

								break;

							case GAD_HIGHSPEED:

								if(MsgCode)
								{
									LT_SetAttributes(Handle,GAD_PARITY,
										GA_Disabled,	TRUE,
										GTCY_Active,	PARITY_NONE,
									TAG_DONE);

									LT_SetAttributes(Handle,GAD_STOPBITS,
										GA_Disabled,	TRUE,
										GTCY_Active,	0,
									TAG_DONE);

									LT_SetAttributes(Handle,GAD_DATABITS,
										GA_Disabled,	TRUE,
										GTCY_Active,	1,
									TAG_DONE);
								}
								else
								{
									LT_SetAttributes(Handle,GAD_PARITY,
										GA_Disabled,	FALSE,
									TAG_DONE);

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

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

								break;

							case GAD_USE:

/*								Config -> SerialConfig -> BaudRate = BaudRates[Rate];*/
								Config -> SerialConfig -> SerialBufferSize = Sizes[Size];
								Config -> SerialConfig -> Quantum = Sizes[Quantum];
								Config -> SerialConfig -> BitsPerChar = Bits + 7;
								Config -> SerialConfig -> StopBits = StopBits + 1;

								Done = TRUE;
								break;

							case GAD_CANCEL:

								SaveConfig(PrivateConfig,Config);

								Cancel = Done = TRUE;
								break;

							case GAD_DEFAULT:

								*Default = TRUE;

								Done = TRUE;
								break;
						}
					}

					if(MsgClass == IDCMP_IDCMPUPDATE && MsgGadget -> GadgetID == GAD_DEVICE)
					{
						LT_LockWindow(PanelWindow);

						strcpy(DummyBuffer,(STRPTR)LT_GetAttributes(Handle,GAD_DEVICE));
						strcpy(SharedBuffer,DummyBuffer);

						if(PickFile(PanelWindow,"Devs:","#?.device",LocaleString(MSG_SERIALPANEL_SELECT_DEVICE_TXT),SharedBuffer,NT_DEVICE))
						{
							if(Stricmp(DummyBuffer,SharedBuffer))
								LT_SetAttributes(Handle,GAD_DEVICE,GTST_String,SharedBuffer,TAG_DONE);
						}

						LT_UnlockWindow(PanelWindow);

						LT_ShowWindow(Handle,TRUE);
					}
				}
			}
			while(!Done);

			PopWindow();
		}

		LT_DeleteHandle(Handle);
	}

	if(Default)
		return((BYTE)(!Cancel));
	else
		return((BYTE)memcmp(PrivateConfig -> SerialConfig,Config -> SerialConfig,sizeof(struct SerialSettings)));
}
