/*  GadTools layout toolkit
**
**  Copyright © 1993-1994 by Olaf `Olsen' Barthel
**  Freely distributable.
*/

#include "gtlayout_global.h"

LayoutHandle * LIBENT
LT_CreateHandle(REG(a0) struct Screen *Screen,REG(a1) struct TextAttr *Font)
{
	return(LT_CreateHandleTags(Screen,
		LH_Font,	Font,
	TAG_DONE));
}

LayoutHandle * __stdargs
LT_CreateHandleTags(struct Screen *Screen,...)
{
	LayoutHandle	*Handle;
	va_list 	 VarArgs;

	va_start(VarArgs,Screen);
	Handle = LT_CreateHandleTagList(Screen,(struct TagItem *)VarArgs);
	va_end(VarArgs);

	return(Handle);
}

LayoutHandle * LIBENT
LT_CreateHandleTagList(REG(a0) struct Screen *Screen,REG(a1) struct TagItem *TagList)
{
	LayoutHandle	*Handle;
	struct Screen	*PubScreen;
	struct TextAttr *textAttr;

#ifdef DO_PICKSHORTCUTS
	ObtainSemaphore(&LTP_KeySemaphore);

	if(!LTP_KeysInitialized)
	{
		UBYTE		  mapBuffer[2 * 3];
		UBYTE		  remapBuffer[10];
		LONG		  i;
		struct InputEvent event;

		for(i = 0 ; i < 256; i++)
		{
			if((i > ' ' && i < 127) || i > 160)
			{
				remapBuffer[0] = i;
				remapBuffer[1] = 0;

				if(MapANSI(remapBuffer,1,mapBuffer,3,NULL) == 1)
				{
					if(!(mapBuffer[1] & ~QUALIFIER_SHIFT))
					{
						event . ie_NextEvent		= NULL;
						event . ie_Class		= IECLASS_RAWKEY;
						event . ie_SubClass		= 0;
						event . ie_Code 		= mapBuffer[0];
						event . ie_Qualifier		= mapBuffer[1] & ~QUALIFIER_SHIFT;
						event . ie_position . ie_addr	= NULL;

						if(MapRawKey(&event,remapBuffer,10,NULL) == 1)
							LTP_Keys[0][i] = remapBuffer[0];

						event . ie_NextEvent		= NULL;
						event . ie_Class		= IECLASS_RAWKEY;
						event . ie_SubClass		= 0;
						event . ie_Code 		= mapBuffer[0];
						event . ie_Qualifier		= mapBuffer[1] | QUALIFIER_SHIFT;
						event . ie_position . ie_addr	= NULL;

						if(MapRawKey(&event,remapBuffer,10,NULL) == 1)
							LTP_Keys[1][i] = remapBuffer[0];
					}
				}
			}
		}

		LTP_KeysInitialized = TRUE;
	}

	ReleaseSemaphore(&LTP_KeySemaphore);
#endif	/* DO_PICKSHORTCUTS */

	textAttr = (struct TextAttr *)GetTagData(LH_Font,NULL,TagList);

	if(!Screen)
	{
		if(!(PubScreen = LockPubScreen(NULL)))
			return(NULL);
		else
			Screen = PubScreen;
	}
	else
		PubScreen = NULL;

	if(Handle = AllocMem(sizeof(LayoutHandle),MEMF_ANY | MEMF_PUBLIC | MEMF_CLEAR))
	{
		Handle -> Screen	= Screen;
		Handle -> PubScreen	= PubScreen;
		Handle -> AutoActivate	= GetTagData(LH_AutoActivate,FALSE,TagList);
		Handle -> LocaleHook	= (struct Hook *)GetTagData(LH_LocaleHook,NULL,TagList);

		Handle -> Parent	= (struct Window *)GetTagData(LH_Parent,NULL,TagList);
		Handle -> BlockParent	= GetTagData(LH_BlockParent,FALSE,TagList);
		Handle -> Expand	= GetTagData(LH_Expand,FALSE,TagList);
		Handle -> ExitFlush	= GetTagData(LH_ExitFlush,TRUE,TagList);
		Handle -> UserData	= (APTR)GetTagData(LH_UserData,TRUE,TagList);

#ifdef DO_CLONING
		Handle -> CloningPermitted	= GetTagData(LH_CloningPermitted,TRUE,TagList);
		Handle -> SimpleClone		= GetTagData(LH_SimpleClone,FALSE,TagList);
		Handle -> ExactClone		= GetTagData(LH_ExactClone,FALSE,TagList);

		if(Handle -> ExactClone)
			Handle -> SimpleClone = FALSE;
#endif

#ifdef DO_FRACTION_KIND
		Handle -> FracEditHook . h_Entry	= (HOOKFUNC)LTP_FracEditRoutine;
		Handle -> FracEditHook . h_Data 	= Handle;
#endif

#ifdef DO_PASSWORD_KIND
		Handle -> PasswordEditHook . h_Entry	= (HOOKFUNC)LTP_PasswordEditRoutine;
		Handle -> PasswordEditHook . h_Data	= Handle;
#endif

		Handle -> DefaultEditHook . h_Entry	= (HOOKFUNC)LTP_DefaultEditRoutine;
		Handle -> DefaultEditHook . h_Data	= Handle;

		Handle -> BackfillHook . h_Entry	= (HOOKFUNC)LTP_BackfillRoutine;
		Handle -> BackfillHook . h_Data 	= Handle;

		Handle -> StandardEditHook = (struct Hook *)GetTagData(LH_EditHook,(ULONG)&Handle -> DefaultEditHook,TagList);

#ifdef DO_HEXHOOK
		Handle -> HexEditHook . h_Entry 	= (HOOKFUNC)LTP_HexEditRoutine;
		Handle -> HexEditHook . h_Data		= Handle;
#endif
		if(Handle -> Pool = AsmCreatePool(MEMF_PUBLIC | MEMF_ANY | MEMF_CLEAR,1024,1024,SysBase))
		{
			if(Handle -> DrawInfo = GetScreenDrawInfo(Screen))
			{
				LONG i;

				Handle -> TextPen	= Handle -> DrawInfo -> dri_Pens[TEXTPEN];
				Handle -> BackgroundPen = Handle -> DrawInfo -> dri_Pens[BACKGROUNDPEN];
				Handle -> ShinePen	= Handle -> DrawInfo -> dri_Pens[SHINEPEN];
				Handle -> ShadowPen	= Handle -> DrawInfo -> dri_Pens[SHADOWPEN];
				Handle -> AspectX	= Handle -> DrawInfo -> dri_Resolution . X;
				Handle -> AspectY	= Handle -> DrawInfo -> dri_Resolution . Y;

				if(V39 && FindTagItem(LH_MenuGlyphs,TagList))
				{
					LONG Size,FontHeight = Handle -> DrawInfo -> dri_Font -> tf_Baseline + 2;

					if(Screen -> Flags & SCREENHIRES)
						Size = SYSISIZE_MEDRES;
					else
						Size = SYSISIZE_LOWRES;

					if(Handle -> AmigaGlyph = NewObject(NULL,SYSICLASS,
						SYSIA_DrawInfo, Handle -> DrawInfo,
						SYSIA_Size,	Size,
						SYSIA_Which,	AMIGAKEY,
						IA_Left,	0,
						LA_Top, 	0,
						IA_Width,	(FontHeight * 3 * Handle -> AspectY) / (2 * Handle -> AspectX),
						IA_Height,	FontHeight,
					TAG_DONE))
					{
						if(!(Handle -> CheckGlyph = NewObject(NULL,SYSICLASS,
							SYSIA_DrawInfo, Handle -> DrawInfo,
							SYSIA_Size,	Size,
							SYSIA_Which,	MENUCHECK,
							IA_Left,	0,
							LA_Top, 	0,
							IA_Width,	(FontHeight * Handle -> AspectY) / Handle -> AspectX,
							IA_Height,	FontHeight,
						TAG_DONE)))
						{
							DisposeObject(Handle -> AmigaGlyph);

							Handle -> AmigaGlyph = NULL;
						}
					}
				}

				for(i = 0 ; i < Handle -> DrawInfo -> dri_NumPens ; i++)
				{
					if(Handle -> DrawInfo -> dri_Pens[i] > Handle -> MaxPen)
						Handle -> MaxPen = Handle -> DrawInfo -> dri_Pens[i];
				}

				if(Handle -> VisualInfo = GetVisualInfoA(Screen,NULL))
				{
					if(textAttr)
						Handle -> InitialTextAttr = textAttr;

					InitRastPort(&Handle -> RPort);

					if(LTP_GlyphSetup(Handle,textAttr))
					{
#ifdef DO_PICKSHORTCUTS
						memset(Handle -> Keys,TRUE,256);

						for(i = 0 ; i < 256 ; i++)
						{
							if(i != 32 && i != 160)
							{
								if(LTP_Keys[0][i])
									Handle -> Keys[LTP_Keys[0][i]] = FALSE;

								if(LTP_Keys[1][i])
									Handle -> Keys[LTP_Keys[1][i]] = FALSE;
							}
						}
#endif
						return(Handle);
					}
				}
			}
		}

		LT_DeleteHandle(Handle);
	}
	else
		UnlockPubScreen(NULL,PubScreen);

	return(NULL);
}
