/*  GadTools layout toolkit
**
**  Copyright © 1993-1995 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;
	APTR		 Pool;

#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 */

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

	if(Pool = AsmCreatePool(MEMF_PUBLIC | MEMF_ANY | MEMF_CLEAR,1024,1024,SysBase))
	{
		if(Handle = AsmAllocPooled(Pool,sizeof(LayoutHandle),SysBase))
		{
			struct TagItem	*List,
					*Entry;
			BOOLEAN		 MenuGlyphs;

			MenuGlyphs = FALSE;

			Handle -> Pool			= Pool;
			Handle -> Screen		= Screen;
			Handle -> InitialTextAttr	= Screen -> Font;
			Handle -> PubScreen		= PubScreen;
			Handle -> PointBack		= Handle;
			Handle -> GroupID		= PHANTOM_GROUP_ID;

			Handle -> ExitFlush		= TRUE;
			Handle -> RawKeyFilter		= TRUE;
#ifdef DO_CLONING
			Handle -> CloningPermitted	= TRUE;
#endif
			Handle -> StandardEditHook	= &Handle -> DefaultEditHook;

			List = TagList;

			while(Entry = NextTagItem(&List))
			{
				switch(Entry -> ti_Tag)
				{
					case LH_Font:

						Handle -> InitialTextAttr = (struct TextAttr *)Entry -> ti_Data;
						break;

					case LH_MenuGlyphs:

						MenuGlyphs = Entry -> ti_Data;
						break;

					case LH_Parent:

						Handle -> Parent = (struct Window *)Entry -> ti_Data;
						break;

					case LH_BlockParent:

						Handle -> BlockParent = Entry -> ti_Data;
						break;

					case LH_ExitFlush:

						Handle -> ExitFlush = Entry -> ti_Data;
						break;

					case LH_UserData:

						Handle -> UserData = (APTR)Entry -> ti_Data;
						break;

					case LH_RawKeyFilter:

						Handle -> RawKeyFilter = Entry -> ti_Data;
						break;

					case LH_AutoActivate:

						Handle -> AutoActivate = Entry -> ti_Data;
						break;

					case LH_LocaleHook:

						Handle -> LocaleHook = (struct Hook *)Entry -> ti_Data;
						break;

					case LH_EditHook:

						Handle -> StandardEditHook = (struct Hook *)Entry -> ti_Data;
						break;
#ifdef DO_CLONING
					case LH_CloningPermitted:

						Handle -> CloningPermitted = Entry -> ti_Data;
						break;

					case LH_SimpleClone:

						if(Handle -> SimpleClone = Entry -> ti_Data)
							Handle -> ExactClone = FALSE;

						break;

					case LH_ExactClone:

						if(Handle -> ExactClone = Entry -> ti_Data)
							Handle -> SimpleClone = FALSE;

						break;
#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;

#ifdef DO_HEXHOOK
			Handle -> HexEditHook . h_Entry 	= (HOOKFUNC)LTP_HexEditRoutine;
			Handle -> HexEditHook . h_Data		= Handle;
#endif

			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(Handle -> BackgroundPen)
				{
					InitBitMap(&Handle->BackfillBitMap,Handle->DrawInfo->dri_Depth,Handle->Screen->Width,Handle->Screen->Width);

					for(i = 0 ; i < Handle->BackfillBitMap.Depth ; i++)
					{
						if(Handle->BackgroundPen & (1L << i))
							Handle->BackfillBitMap.Planes[i] = (PLANEPTR)0xFFFFFFFF;
						else
							Handle->BackfillBitMap.Planes[i] = (PLANEPTR)NULL;
					}
				}

				if(V39 && MenuGlyphs)
				{
					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,
						IA_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,
							IA_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))
				{
					InitRastPort(&Handle -> RPort);

					if(LTP_GlyphSetup(Handle,Handle -> InitialTextAttr))
					{
#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
			AsmDeletePool(Pool,SysBase);
	}
	else
		UnlockPubScreen(NULL,PubScreen);

	return(NULL);
}
