/*
**	TranslationPanel.c
**
**	Character code translation editing panel
**
**	Copyright © 1990-1994 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_CHAR=700
	};

	/* The character table. */

STATIC STRPTR CharCodes[256] =
{
	"NUL","SOH","STX","ETX","EOT","ENQ","ACK","BEL","BS" ,"HT" ,"LF" ,"VT" ,"FF" ,"CR" ,"SO" ,"SI" ,
	"DLE","DC1","DC2","DC3","DC4","NAK","SYN","ETB","CAN","EM" ,"SUB","ESC","FS" ,"GS" ,"RS" ,"US" ,
	"SP" , "!" , "\"", "#" , "$" , "%" , "&" , "'" , "(" , ")" , "*" , "+" , "," , "-" , "." , "/" ,
	 "0" , "1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , ":" , ";" , "<" , "=" , ">" , "?" ,
	 "@" , "A" , "B" , "C" , "D" , "E" , "F" , "G" , "H" , "I" , "J" , "K" , "L" , "M" , "N" , "O" ,
	 "P" , "Q" , "R" , "S" , "T" , "U" , "V" , "W" , "X" , "Y" , "Z" , "[" , "\\", "]" , "^" , "_" ,
	 "`" , "a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" , "i" , "j" , "k" , "l" , "m" , "n" , "o" ,
	 "p" , "q" , "r" , "s" , "t" , "u" , "v" , "w" , "x" , "y" , "z" , "{" , "|" , "}" , "~" ,"DEL",
	"128","129","130","131","132","133","134","135","136","137","138","139","140","141","SS2","SS3",
	"DCS","145","146","147","148","149","150","151","152","153","154","CSI","ST" ,"OSC","PM" ,"APC",
	"NBS", "¡" , "¢" , "£" , "¤" , "¥" , "¦" , "§" , "¨" , "©" , "ª" , "«" , "¬" ,"SHY", "®" , "¯" ,
	 "°" , "±" , "²" , "³" , "´" , "µ" , "¶" , "·" , "¸" , "¹" , "º" , "»" , "¼" , "½" , "¾" , "¿" ,
	 "À" , "Á" , "Â" , "Ã" , "Ä" , "Å" , "Æ" , "Ç" , "È" , "É" , "Ê" , "Ë" , "Ì" , "Í" , "Î" , "Ï" ,
	 "Ð" , "Ñ" , "Ò" , "Ó" , "Ô" , "Õ" , "Ö" , "×" , "Ø" , "Ù" , "Ú" , "Û" , "Ü" , "Ý" , "Þ" , "ß" ,
	 "à" , "á" , "â" , "ã" , "ä" , "å" , "æ" , "ç" , "è" , "é" , "ê" , "ë" , "ì" , "í" , "î" , "ï" ,
	 "ð" , "ñ" , "ò" , "ó" , "ô" , "õ" , "ö" , "÷" , "ø" , "ù" , "ú" , "û" , "ü" , "ý" , "þ" , "ÿ"
};

STATIC BYTE __regargs
CodePanel(struct Window *Window,UBYTE CharCode)
{
	struct LayoutHandle	*Handle;
	BYTE			 Result = FALSE;

	if(Handle = LT_CreateHandleTags(Window -> WScreen,
		LH_LocaleHook,	&LocaleHook,
	TAG_DONE))
	{
		struct Window	*Window;
		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);
		{
			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]);

			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(Window = LT_Layout(Handle,LocaleString(MSG_TRANSLATIONPANEL_CHARACTER_CODE_TRANSLATION_TXT),NULL,0,0,IDCMP_CLOSEWINDOW,0,
			LAWN_HelpHook,		&GuideHook,
			WA_DepthGadget,		TRUE,
			WA_CloseGadget,		TRUE,
			WA_DragBar,		TRUE,
			WA_RMBTrap,		TRUE,
			WA_Activate,		TRUE,
		TAG_DONE))
		{
			struct IntuiMessage	*Message;
			BOOLEAN			 Done = FALSE;
			ULONG			 MsgClass,
						 MsgQualifier;
			UWORD			 MsgCode;
			struct Gadget		*MsgGadget;

			LT_ShowWindow(Handle,TRUE);

			GuideContext(CONTEXT_TRANSLATION);

			PushWindow(Window);

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

				while(Message = (struct IntuiMessage *)GT_GetIMsg(Window -> 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)
						Done = TRUE;

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

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

BYTE
TranslationPanel()
{
	struct LayoutHandle	*Handle;
	BYTE			 MadeChanges	= FALSE,
				 Created	= 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;
	}

	if(Handle = LT_CreateHandleTags(Window -> WScreen,
		LH_LocaleHook,	&LocaleHook,
	TAG_DONE))
	{
		struct Window	*Window;
		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,
				LA_LabelID,	MSG_V36_1774,
			TAG_DONE);
			{
				LT_New(Handle,
					LA_Type,	VERTICAL_KIND,
				TAG_DONE);
				{
					STATIC STRPTR Halfs[] =
					{
						"NUL-DEL",
						"128-\"ÿ\"",
						NULL
					};

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

					LT_New(Handle,
						LA_Type,	XBAR_KIND,
					TAG_DONE);

					LT_EndGroup(Handle);
				}

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

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

							LT_EndGroup(Handle);
						}
					}

					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_CANCEL_GAD,
					LA_ID,		GAD_CANCEL,
					LA_NoKey,	TRUE,
					LABT_ExtraFat,	TRUE,
					LABT_EscKey,	TRUE,
				TAG_DONE);

				LT_EndGroup(Handle);
			}

			LT_EndGroup(Handle);
		}

		if(Window = LT_Layout(Handle,LocaleString(MSG_TRANSLATIONPANEL_CHARACTER_TABLE_TXT),NULL,0,0,IDCMP_CLOSEWINDOW,0,
			LAWN_HelpHook,		&GuideHook,
			WA_DepthGadget,		TRUE,
			WA_CloseGadget,		TRUE,
			WA_DragBar,		TRUE,
			WA_RMBTrap,		TRUE,
			WA_Activate,		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(Window);

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

				while(Message = (struct IntuiMessage *)GT_GetIMsg(Window -> 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)
						Done = TRUE;

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

						LT_LockWindow(Window);

						MadeChanges |= CodePanel(Window,KeyCode);

						LT_UnlockWindow(Window);

						LT_ShowWindow(Handle,TRUE);
					}

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

								LT_LockWindow(Window);

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

								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_USE:

								Done = TRUE;
								break;

							case GAD_CANCEL:

								Done = TRUE;
								break;

							case GAD_LOAD:

								strcpy(DummyBuffer,LastTranslation);

								DummyChar = PathPart(DummyBuffer);

								*DummyChar = 0;

								LT_LockWindow(Window);

								if(FileRequest = GetFile(Window,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;
									BYTE Success = FALSE;

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

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

										if(Send)
											FreeTranslationTable(Send);

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

										strcpy(LastTranslation,DummyBuffer);

										MadeChanges	= FALSE;
										Created		= FALSE;

										FreeTranslationTable(SendTable);
										FreeTranslationTable(ReceiveTable);

										SendTable	= Send;
										ReceiveTable	= Receive;
									}

									FreeAslRequest(FileRequest);
								}

								LT_UnlockWindow(Window);
								break;

							case GAD_SAVE:

								strcpy(DummyBuffer,LastTranslation);

								DummyChar = PathPart(DummyBuffer);

								*DummyChar = 0;

								LT_LockWindow(Window);

								if(FileRequest = GetFile(Window,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(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
									else
									{
										strcpy(LastTranslation,DummyBuffer);

										MadeChanges = FALSE;

										Created = FALSE;
									}

									FreeAslRequest(FileRequest);
								}

								LT_UnlockWindow(Window);
								break;

							default:

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

									MadeChanges |= CodePanel(Window,CharBase + MsgGadget -> GadgetID - GAD_CHAR);

									LT_UnlockWindow(Window);

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

	return(MadeChanges);
}
