/*
**	TranslationPanel.c
**
**	Character code translation editing panel
**
**	Copyright © 1990-1995 by Olaf `Olsen' Barthel
**		All Rights Reserved
*/

#include "termGlobal.h"

enum	{	GAD_PAGE=1,GAD_USE,GAD_DEFAULT,GAD_LOAD,GAD_SAVE,GAD_CANCEL,GAD_CLOSE,
		GAD_CHAR=700
	};

STATIC BOOLEAN __regargs
CodePanel(struct Window *Window,UBYTE CharCode,struct TranslationEntry **SendTable,struct TranslationEntry **ReceiveTable)
{
	struct LayoutHandle	*Handle;
	BOOLEAN			 Result = FALSE;

	if(Handle = LT_CreateHandleTags(Window -> WScreen,
		LH_LocaleHook,	&LocaleHook,
	TAG_DONE))
	{
		struct Window	*PanelWindow;
		UBYTE		 SendBuffer[256],
				 ReceiveBuffer[256];

		if(SendTable[CharCode])
			TranslateBack(SendTable[CharCode] -> String,SendTable[CharCode] -> Len,SendBuffer);
		else
			SendBuffer[0] = 0;

		if(ReceiveTable[CharCode])
			TranslateBack(ReceiveTable[CharCode] -> String,ReceiveTable[CharCode] -> Len,ReceiveBuffer);
		else
			ReceiveBuffer[0] = 0;

		LT_New(Handle,
			LA_Type,	VERTICAL_KIND,
		TAG_DONE);
		{
			UBYTE	OctalBuffer[6],HexBuffer[6],BinBuffer[10];
			WORD	i,Code;

			OctalBuffer[0] = '0';

			for(Code = CharCode, i = 0 ; i < 3 ; i++)
			{
				OctalBuffer[2 - i + 1] = '0' + (Code & 7);

				Code = Code >> 3;
			}

			OctalBuffer[4] = 0;

			SPrintf(HexBuffer,"$%02lx",CharCode);

			BinBuffer[0] = '%';

			for(Code = CharCode, i = 0 ; i < 8 ; i++)
			{
				BinBuffer[7 - i + 1] = '0' + (Code & 1);

				Code = Code >> 1;
			}

			BinBuffer[9] = 0;

			if(CharCodes[CharCode][0] == '1' && CharCodes[CharCode][1])
				SPrintf(SharedBuffer,LocaleString(MSG_V36_1772),CharCodes[CharCode]);
			else
				SPrintf(SharedBuffer,LocaleString(MSG_V36_1773),CharCode,CharCodes[CharCode]);

			SPrintf(SharedBuffer + strlen(SharedBuffer)," · %s · %s · %s",HexBuffer,OctalBuffer,BinBuffer);

			LT_New(Handle,
				LA_Type,	VERTICAL_KIND,
				LA_LabelText,	SharedBuffer,
			TAG_DONE);
			{
				LT_New(Handle,
					LA_Type,		STRING_KIND,
					LA_LabelID,		MSG_TRANSLATIONPANEL_SEND_CODE_AS_GAD,
					LA_STRPTR,		SendBuffer,
					LA_Chars,		30,
					STRINGA_Justification,	GACT_STRINGCENTER,
					GTST_MaxChars,		255,
				TAG_DONE);

				LT_New(Handle,
					LA_Type,		STRING_KIND,
					LA_LabelID,		MSG_TRANSLATIONPANEL_RECEIVE_CODE_AS_GAD,
					LA_STRPTR,		ReceiveBuffer,
					STRINGA_Justification,	GACT_STRINGCENTER,
					GTST_MaxChars,		255,
				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);

				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_Build(Handle,
			LAWN_TitleID,		MSG_TRANSLATIONPANEL_CHARACTER_CODE_TRANSLATION_TXT,
			LAWN_IDCMP,		IDCMP_CLOSEWINDOW,
			LAWN_HelpHook,		&GuideHook,
			LAWN_Parent,		Window,
			WA_DepthGadget,		TRUE,
			WA_CloseGadget,		TRUE,
			WA_DragBar,		TRUE,
			WA_RMBTrap,		TRUE,
			WA_Activate,		TRUE,
			WA_SimpleRefresh,	TRUE,
		TAG_DONE))
		{
			struct IntuiMessage	*Message;
			BOOLEAN			 Done = FALSE;
			ULONG			 MsgClass;
			struct Gadget		*MsgGadget;

			LT_ShowWindow(Handle,TRUE);

			GuideContext(CONTEXT_TRANSLATION);

			PushWindow(PanelWindow);

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

				while(Message = (struct IntuiMessage *)LT_GetIMsg(Handle))
				{
					MsgClass	= Message -> Class;
					MsgGadget	= (struct Gadget *)Message -> IAddress;

					LT_ReplyIMsg(Message);

					if(MsgClass == IDCMP_CLOSEWINDOW)
						Done = TRUE;

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

								LT_UpdateStrings(Handle);

								if(SendBuffer[0])
								{
									struct TranslationEntry *Entry = AllocTranslationEntry(SendBuffer);

									if(Entry)
									{
										if(SendTable[CharCode])
											FreeTranslationEntry(SendTable[CharCode]);

										SendTable[CharCode] = Entry;

										Result = TRUE;
									}
								}
								else
								{
									if(SendTable[CharCode])
										FreeTranslationEntry(SendTable[CharCode]);

									SendTable[CharCode] = NULL;

									Result = TRUE;
								}

								if(ReceiveBuffer[0])
								{
									struct TranslationEntry *Entry = AllocTranslationEntry(ReceiveBuffer);

									if(Entry)
									{
										if(ReceiveTable[CharCode])
											FreeTranslationEntry(ReceiveTable[CharCode]);

										ReceiveTable[CharCode] = Entry;

										Result = TRUE;
									}
								}
								else
								{
									if(ReceiveTable[CharCode])
										FreeTranslationEntry(ReceiveTable[CharCode]);

									ReceiveTable[CharCode] = NULL;

									Result = TRUE;
								}

								Done = TRUE;
								break;

							case GAD_CANCEL:

								Done = TRUE;
								break;
						}
					}
				}
			}
			while(!Done);

			PopWindow();
		}

		LT_DeleteHandle(Handle);
	}

	return(Result);
}

BOOLEAN __regargs
TranslationPanel(struct TranslationEntry ***SendTablePtr,struct TranslationEntry ***ReceiveTablePtr,STRPTR LastTranslation,struct Window *Parent,BYTE *ChangePtr)
{
	struct LayoutHandle	*Handle;
	BOOLEAN			 MadeChanges,
				 Created = FALSE;

	struct TranslationEntry	**SendTable	= *SendTablePtr,
				**ReceiveTable	= *ReceiveTablePtr;

	if(ChangePtr)
		MadeChanges = *ChangePtr;
	else
		MadeChanges = FALSE;

	if(!SendTable)
	{
		if(!(SendTable = AllocTranslationTable()))
		{
			DisplayBeep(Window -> WScreen);

			return(FALSE);
		}

		if(!(ReceiveTable = AllocTranslationTable()))
		{
			DisplayBeep(Window -> WScreen);

			FreeTranslationTable(SendTable);

			SendTable = NULL;

			return(FALSE);
		}

		if(!FillTranslationTable(SendTable))
		{
			DisplayBeep(Window -> WScreen);

			FreeTranslationTable(SendTable);

			SendTable = NULL;

			FreeTranslationTable(ReceiveTable);

			ReceiveTable = NULL;

			return(FALSE);
		}

		if(!FillTranslationTable(ReceiveTable))
		{
			DisplayBeep(Window -> WScreen);

			FreeTranslationTable(SendTable);

			SendTable = NULL;

			FreeTranslationTable(ReceiveTable);

			ReceiveTable = NULL;

			return(FALSE);
		}

		Created = TRUE;
	}

	*SendTablePtr		= SendTable;
	*ReceiveTablePtr	= ReceiveTable;

	if(Handle = LT_CreateHandleTags(Window -> WScreen,
		LH_LocaleHook,	&LocaleHook,
	TAG_DONE))
	{
		struct Window	*PanelWindow;
		LONG		 i,Width,Max = 0;

		for(i = 0 ; i < 256 ; i++)
		{
			if((Width = LT_LabelChars(Handle,CharCodes[i])) > Max)
				Max = Width;
		}

		LT_New(Handle,
			LA_Type,	VERTICAL_KIND,
		TAG_DONE);
		{
			LT_New(Handle,
				LA_Type,	VERTICAL_KIND,
			TAG_DONE);
			{
				STATIC STRPTR Halfs[] =
				{
					"NUL-DEL",
					"128-\"ÿ\"",
					NULL
				};

				LT_New(Handle,
					LA_Type,	TAB_KIND,
					LA_LabelID,	MSG_TRANSLATIONPANEL_CHARACTER_PAGE_GAD,
					LA_ID,		GAD_PAGE,
					GTCY_Labels,	Halfs,
					LA_NoKey,	TRUE,
					LATB_FullWidth,	TRUE,
				TAG_DONE);

				LT_EndGroup(Handle);
			}

			LT_New(Handle,
				LA_Type,	VERTICAL_KIND,
			TAG_DONE);
			{
				WORD i,j;

				for(i = 0 ; i < 8 ; i++)
				{
					LT_New(Handle,
						LA_Type,	HORIZONTAL_KIND,
						LA_SameSize,	TRUE,
					TAG_DONE);
					{
						for(j = 0 ; j < 16 ; j++)
						{
							LT_New(Handle,
								LA_Type,	BUTTON_KIND,
								LA_LabelText,	CharCodes[i * 16 + j],
								LA_ID,		GAD_CHAR + i * 16 + j,
								LA_Chars,	Max,
								LA_NoKey,	TRUE,
							TAG_DONE);
						}

						LT_EndGroup(Handle);
					}
				}

				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_Spread,	TRUE,
			TAG_DONE);
			{
				LT_New(Handle,
					LA_Type,	BUTTON_KIND,
					LA_LabelID,	MSG_GLOBAL_USE_GAD,
					LA_ID,		GAD_USE,
					LA_NoKey,	TRUE,
					LABT_ExtraFat,	TRUE,
				TAG_DONE);

				LT_New(Handle,
					LA_Type,	BUTTON_KIND,
					LA_LabelID,	MSG_GLOBAL_DEFAULT_GAD,
					LA_ID,		GAD_DEFAULT,
					LA_NoKey,	TRUE,
					LABT_ExtraFat,	TRUE,
				TAG_DONE);

				LT_New(Handle,
					LA_Type,	BUTTON_KIND,
					LA_LabelID,	MSG_GLOBAL_LOAD_GAD,
					LA_ID,		GAD_LOAD,
					LA_NoKey,	TRUE,
					LABT_ExtraFat,	TRUE,
				TAG_DONE);

				LT_New(Handle,
					LA_Type,	BUTTON_KIND,
					LA_LabelID,	MSG_GLOBAL_SAVE_GAD,
					LA_ID,		GAD_SAVE,
					LA_NoKey,	TRUE,
					LABT_ExtraFat,	TRUE,
				TAG_DONE);

				LT_New(Handle,
					LA_Type,	BUTTON_KIND,
					LA_LabelID,	MSG_GLOBAL_CLOSE_TXT,
					LA_ID,		GAD_CANCEL,
					LA_NoKey,	TRUE,
					LABT_ExtraFat,	TRUE,
				TAG_DONE);

				LT_EndGroup(Handle);
			}

			LT_EndGroup(Handle);
		}

		if(PanelWindow = LT_Build(Handle,
			LAWN_TitleID,		MSG_TRANSLATIONPANEL_CHARACTER_TABLE_TXT,
			LAWN_IDCMP,		IDCMP_CLOSEWINDOW,
			LAWN_HelpHook,		&GuideHook,
			LAWN_Parent,		Parent,
			WA_DepthGadget,		TRUE,
			WA_CloseGadget,		TRUE,
			WA_DragBar,		TRUE,
			WA_RMBTrap,		TRUE,
			WA_Activate,		TRUE,
			WA_SimpleRefresh,	TRUE,
		TAG_DONE))
		{
			struct IntuiMessage	*Message;
			BOOLEAN			 Done = FALSE;
			ULONG			 MsgClass,
						 MsgQualifier;
			UWORD			 MsgCode;
			struct Gadget		*MsgGadget;
			LONG			 CharBase = 0,i;
			UBYTE			 DummyBuffer[256],
						*DummyChar;
			struct FileRequester	*FileRequest;
			WORD			 KeyCode;

			PushWindow(PanelWindow);

			LT_ShowWindow(Handle,TRUE);

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

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

					if(MsgClass == IDCMP_RAWKEY)
						KeyCode = LT_GetCode(MsgQualifier,MsgClass,MsgCode,MsgGadget);
					else
						KeyCode = -1;

					GT_ReplyIMsg(Message);

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

					if(MsgClass == IDCMP_CLOSEWINDOW && KeyCode == -1)
						Done = TRUE;

					if(KeyCode != -1)
					{
						if(KeyCode >= CharBase && KeyCode < CharBase + 128)
							LT_PressButton(Handle,GAD_CHAR + KeyCode - CharBase);

						LT_LockWindow(PanelWindow);

						MadeChanges |= CodePanel(PanelWindow,KeyCode,SendTable,ReceiveTable);

						LT_UnlockWindow(PanelWindow);

						LT_ShowWindow(Handle,TRUE);
					}

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

								LT_LockWindow(PanelWindow);

								if(MsgCode)
								{
									for(i = 0 ; i < 128 ; i++)
										LT_SetAttributes(Handle,GAD_CHAR + i,LA_LabelText,CharCodes[128 + i],TAG_DONE);

									CharBase = 128;
								}
								else
								{
									for(i = 0 ; i < 128 ; i++)
										LT_SetAttributes(Handle,GAD_CHAR + i,LA_LabelText,CharCodes[0 + i],TAG_DONE);

									CharBase = 0;
								}

								if(!LT_Rebuild(Handle,NULL,0,0,FALSE))
								{
									LT_DeleteHandle(Handle);

									Handle = NULL;

									Done = TRUE;
								}
								else
									LT_UnlockWindow(PanelWindow);

								break;

							case GAD_DEFAULT:

								if(SendTable)
								{
									struct TranslationEntry **Table;

									if(Table = AllocTranslationTable())
									{
										if(FillTranslationTable(Table))
										{
											FreeTranslationTable(SendTable);

											SendTable = Table;
										}
									}
								}

								if(ReceiveTable)
								{
									struct TranslationEntry **Table;

									if(Table = AllocTranslationTable())
									{
										if(FillTranslationTable(Table))
										{
											FreeTranslationTable(ReceiveTable);

											ReceiveTable = Table;
										}
									}
								}

								break;

							case GAD_CLOSE:
							case GAD_USE:

								Done = TRUE;
								break;

							case GAD_CANCEL:

								Done = TRUE;
								break;

							case GAD_LOAD:

								strcpy(DummyBuffer,LastTranslation);

								DummyChar = PathPart(DummyBuffer);

								*DummyChar = 0;

								LT_LockWindow(PanelWindow);

								if(FileRequest = GetFile(PanelWindow,LocaleString(MSG_TRANSLATIONPANEL_LOAD_TRANSLATION_TABLES_TXT),DummyBuffer,FilePart(LastTranslation),DummyBuffer,"#?.prefs",FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_LOAD_TXT),TRUE))
								{
									struct TranslationEntry **Send,**Receive = NULL;
									BOOLEAN			Success = FALSE;

									if(Send = AllocTranslationTable())
									{
										if(Receive = AllocTranslationTable())
											Success = LoadTranslationTables(DummyBuffer,Send,Receive);
									}

									if(!Success)
									{
										ShowError(PanelWindow,ERR_LOAD_ERROR,IoErr(),DummyBuffer);

										if(Send)
											FreeTranslationTable(Send);

										if(Receive)
											FreeTranslationTable(Receive);
									}
									else
									{
										strcpy(Config -> TranslationFileName,DummyBuffer);

										strcpy(LastTranslation,DummyBuffer);

										MadeChanges	= FALSE;
										Created		= FALSE;

										FreeTranslationTable(SendTable);
										FreeTranslationTable(ReceiveTable);

										SendTable	= Send;
										ReceiveTable	= Receive;

										if(ChangePtr)
											*ChangePtr = FALSE;
									}

									FreeAslRequest(FileRequest);
								}

								LT_UnlockWindow(PanelWindow);
								break;

							case GAD_SAVE:

								strcpy(DummyBuffer,LastTranslation);

								DummyChar = PathPart(DummyBuffer);

								*DummyChar = 0;

								LT_LockWindow(PanelWindow);

								if(FileRequest = GetFile(PanelWindow,LocaleString(MSG_TRANSLATIONPANEL_SAVE_TRANSLATION_TABLES_TXT),DummyBuffer,FilePart(LastTranslation),DummyBuffer,"#?.prefs",TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),TRUE))
								{
									if(!SaveTranslationTables(DummyBuffer,SendTable,ReceiveTable))
										ShowError(PanelWindow,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
									else
									{
										strcpy(LastTranslation,DummyBuffer);

										MadeChanges = FALSE;

										Created = FALSE;

										if(ChangePtr)
											*ChangePtr = FALSE;
									}

									FreeAslRequest(FileRequest);
								}

								LT_UnlockWindow(PanelWindow);
								break;

							default:

								if(MsgGadget -> GadgetID >= GAD_CHAR && MsgGadget -> GadgetID < GAD_CHAR + 128)
								{
									LT_LockWindow(PanelWindow);

									MadeChanges |= CodePanel(PanelWindow,CharBase + MsgGadget -> GadgetID - GAD_CHAR,SendTable,ReceiveTable);

									LT_UnlockWindow(PanelWindow);

									LT_ShowWindow(Handle,TRUE);
								}

								break;
						}
					}
				}
			}
			while(!Done);

			PopWindow();
		}

		LT_DeleteHandle(Handle);
	}

	if(!MadeChanges && Created || (IsStandardTable(SendTable) && IsStandardTable(ReceiveTable)))
	{
		FreeTranslationTable(SendTable);

		SendTable = NULL;

		FreeTranslationTable(ReceiveTable);

		ReceiveTable = NULL;
	}

	*SendTablePtr		= SendTable;
	*ReceiveTablePtr	= ReceiveTable;

	if(ChangePtr)
		*ChangePtr |= MadeChanges;

	return(MadeChanges);
}
