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

#include "gtlayout_global.h"

BOOL LIBENT
LT_RebuildTagList(REG(a0) LayoutHandle *handle,REG(d0) BOOL clear,REG(a1) struct TagItem *TagParams)
{
	struct TagItem	*item,
			*list;
	struct IBox	*bounds = NULL;
	WORD		 RightEdge,
			 BottomEdge;

	list = TagParams;

	while(item = NextTagItem(&list))
	{
		switch(item -> ti_Tag)
		{
			case LAWN_Bounds:

				bounds = (struct IBox *)item -> ti_Data;
				break;
		}
	}

	if(handle)
	{
		struct Gadget	*gadget,
				*next;
		ObjectNode	*node;
		LONG		 left,top;
		struct IBox	 newBounds;
		LONG		 i;
		struct Image	**ImagePtr;

		if(!handle -> SizeVerified)
		{
			RemoveGList(handle -> Window,handle -> List,(UWORD)-1);
#ifdef DO_BOOPSI_KIND
			if(handle -> BOOPSIList)
				RemoveGList(handle -> Window,(struct Gadget *)handle -> BOOPSIList,(UWORD)-1);
#endif	/* DO_BOOPSI_KIND */
		}
		gadget = handle -> List;

		while(gadget)
		{
			if(GETOBJECT(gadget,node))
			{
				LTP_PutStorage(node);

				ImagePtr = NULL;

				switch(node -> Type)
				{
#ifdef DO_GAUGE_KIND
					case GAUGE_KIND:

						node -> Special . Gauge . LastPercentage = -1;
						break;
#endif	/* DO_GAUGE_KIND */

					case BUTTON_KIND:

						ImagePtr = &node -> Special . Button . ButtonImage;
						break;

					case PICKER_KIND:

						ImagePtr = &node -> Special . Picker . Image;
						break;

					case TAPEDECK_KIND:

						ImagePtr = &node -> Special . TapeDeck . ButtonImage;
						break;

					case INCREMENTER_KIND:

						ImagePtr = &node -> Special . Incrementer . Image;
						break;

					case STRING_KIND:

						if(!node -> Special . String . Backup)
							node -> Special . String . Backup = (STRPTR)LTP_Alloc(handle,node -> Special . String . MaxChars + 1);

						if(node -> Special . String . Backup)
						{
							strcpy(node -> Special . String . Backup,((struct StringInfo *)gadget -> SpecialInfo) -> Buffer);

							node -> Special . String . String = node -> Special . String . Backup;
						}

						node -> Special . String . Picker = NULL;

						break;

					case TEXT_KIND:

						node -> Special . Text . Picker = NULL;
						break;

					case INTEGER_KIND:

						node -> Special . Integer . LeftIncrementer	= NULL;
						node -> Special . Integer . RightIncrementer	= NULL;

						break;
#ifdef DO_LEVEL_KIND
					case LEVEL_KIND:

						ImagePtr = &node -> Special . Level . LevelImage;
						break;
#endif	/* DO_LEVEL_KIND */
				}

				if(ImagePtr && *ImagePtr)
				{
					DisposeObject(*ImagePtr);

					*ImagePtr = NULL;
				}

				node -> Host = NULL;
			}

			gadget = gadget -> NextGadget;
		}

		FreeGadgets(handle -> List);

		handle -> List = NULL;

#ifdef DO_BOOPSI_KIND
		gadget = (struct Gadget *)handle -> BOOPSIList;

		while(gadget)
		{
			next = gadget -> NextGadget;

			if(GETOBJECT(gadget,node))
			{
				DisposeObject(gadget);

				if(node -> Type == BOOPSI_KIND)
				{
					if(node -> Special . BOOPSI . ClassBase)
					{
						CloseLibrary(node -> Special . BOOPSI . ClassBase);

						node -> Special . BOOPSI . ClassBase = NULL;
					}
				}

				node -> Host = NULL;
			}

			gadget = next;
		}

		handle -> BOOPSIList = NULL;
		handle -> BOOPSIPrevious = NULL;
#endif	/* DO_BOOPSI_KIND */

		LTP_Free(handle,handle -> GadgetArray,sizeof(struct Gadget *) * handle -> Count);

		handle -> GadgetArray = NULL;

		handle -> Count = handle -> Index = 0;

		LTP_ResetGroups(handle -> TopGroup);

		if(!bounds)
		{
//			LTP_GetDisplayClip(handle -> Screen,&newBounds . Left,&newBounds . Top,&newBounds . Width,&newBounds . Height);

			bounds = &newBounds;

			newBounds . Left	= 0;
			newBounds . Top		= 0;
			newBounds . Width	= handle -> Window -> Width;
			newBounds . Height	= handle -> Window -> Height;
		}

		left		= handle -> Window -> BorderLeft;
		top		= handle -> Window -> BorderTop;
		RightEdge	= handle -> Window -> BorderRight;
		BottomEdge	= handle -> Window -> BorderBottom;

		if(!handle -> FlushLeft)
		{
			left		+= handle -> InterWidth;
			RightEdge	+= handle -> InterWidth;
		}

		if(!handle -> FlushTop)
		{
			top		+= handle -> InterHeight;
			BottomEdge	+= handle -> InterHeight;
		}

		LTP_CreateGadgets(handle,bounds,left,top,left + RightEdge,top + BottomEdge);

		if(handle -> Failed)
		{
			handle -> SizeVerified = FALSE;

			EraseRect(&handle -> RPort,handle -> Window -> BorderLeft,handle -> Window -> BorderTop,handle -> Window -> Width - (handle -> Window -> BorderRight + 1),handle -> Window -> Height - (handle -> Window -> BorderBottom + 1));

			RefreshWindowFrame(handle -> Window);

			return(FALSE);
		}

		if(clear)
		{
			EraseRect(&handle -> RPort,handle -> Window -> BorderLeft,handle -> Window -> BorderTop,handle -> Window -> Width - (handle -> Window -> BorderRight + 1),handle -> Window -> Height - (handle -> Window -> BorderBottom + 1));

			if(!handle -> SizeVerified)
				RefreshWindowFrame(handle -> Window);
		}

		handle -> SizeVerified = FALSE;

		LTP_AddGadgets(handle);

		handle -> Previous = NULL;

		for(i = 0 ; i < handle -> Count ; i++)
		{
			if(handle -> GadgetArray[i])
			{
				if(GETOBJECT(handle -> GadgetArray[i],node))
				{
					if(LIKE_STRING_KIND(node) || (node -> Type == INTEGER_KIND))
					{
						if(!handle -> Previous)
							handle -> Previous = handle -> GadgetArray[i];
					}
				}
			}
		}

		return(TRUE);
	}
	else
		return(FALSE);
}


/*****************************************************************************/


BOOL __stdargs
LT_RebuildTags(LayoutHandle *Handle,BOOL Clear,...)
{
	va_list VarArgs;
	BOOL	Result;

	va_start(VarArgs,Clear);
	Result = LT_RebuildTagList(Handle,Clear,(struct TagItem *)VarArgs);
	va_end(VarArgs);

	return(Result);
}


/*****************************************************************************/


BOOL LIBENT
LT_Rebuild(REG(a0) LayoutHandle *handle,REG(a1) struct IBox *bounds,REG(a2) LONG extraWidth,REG(d0) LONG extraHeight,REG(d1) BOOL clear)
{
	return(LT_RebuildTags(handle,clear,
		LAWN_Bounds,bounds,
	TAG_DONE));
}
