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

#include "gtlayout_global.h"

VOID __regargs
LTP_CreateGadgets(LayoutHandle *Handle,struct IBox *Bounds,LONG Left,LONG Top,LONG PlusWidth,LONG PlusHeight)
{
	if(!Handle -> Failed)
	{
		BOOLEAN	Fits;
		BOOLEAN	Cloned = FALSE;
		WORD	Attempt = 3;

		if(!V39 && (Handle -> RPort . TxFlags & FPF_PROPORTIONAL))
		{
			LTP_Rescale(Handle,FALSE,FALSE);

			Handle -> Rescaled = FALSE;
		}

		do
		{
			LTP_LayoutGroup(Handle,Handle -> TopGroup);
			LTP_PlaceGroups(Handle,Handle -> TopGroup,Left,Top);

			Fits = TRUE;

			if(Handle -> TopGroup -> Width + PlusWidth > Bounds -> Width)
			{
				if(Handle -> TopGroup -> Width + PlusWidth > Handle -> Screen -> Width)
				{
					Fits = FALSE;

					if(Handle -> TopGroup -> Height + PlusHeight > Bounds -> Height)
					{
						if(!LTP_Rescale(Handle,TRUE,TRUE))
							Handle -> Failed = TRUE;
					}
					else
					{
						if(!LTP_Rescale(Handle,TRUE,FALSE))
							Handle -> Failed = TRUE;
					}
				}
			}
			else
			{
				if(Handle -> TopGroup -> Height + PlusHeight > Bounds -> Height)
				{
					if(Handle -> TopGroup -> Height + PlusHeight > Handle -> Screen -> Height)
					{
						Fits = FALSE;

						if(!LTP_Rescale(Handle,FALSE,TRUE))
							Handle -> Failed = TRUE;
					}
				}
			}

#ifdef DO_CLONING
			if(Handle -> Failed && !Cloned && Handle -> CloningPermitted)
			{
				if(LTP_PrepareCloning(Handle))
					Bounds = &Handle -> CloneExtra -> Bounds;

				Cloned = TRUE;
			}
#endif

			if(Attempt > 0 && Fits && !Handle -> Rescaled && !Cloned && !Handle -> Failed && (Handle -> GrowView || (Handle -> ResizeView && Handle -> Window)))
			{
				LONG		Width	= Handle -> TopGroup -> Width + PlusWidth,
						Height	= Handle -> TopGroup -> Height + PlusHeight;
				ObjectNode	*View;

				Attempt--;

				if(Handle -> GrowView)
					View = Handle -> GrowView;
				else
					View = Handle -> ResizeView;

				if(Bounds -> Width != Width || Bounds -> Height != Height)
				{
					LONG	 PlusChars,
						 PlusLines;

					if(View -> Special . List . MaxGrowX && Handle -> GrowView)
					{
						PlusChars = (Bounds -> Width - Width) / Handle -> GlyphWidth;

						if(PlusChars > 0 && View -> Chars + PlusChars > View -> Special . List . MaxGrowX)
							PlusChars = View -> Special . List . MaxGrowX - View -> Chars;

						if(PlusChars < 0)
							PlusChars = 0;
					}
					else
					{
						if(View -> Special . List . ResizeX && !Handle -> GrowView)
							PlusChars = (Bounds -> Width - Width) / Handle -> GlyphWidth;
						else
							PlusChars = 0;
					}

					if(View -> Special . List . MaxGrowY && Handle -> GrowView)
					{
						PlusLines = (Bounds -> Height - Height) / Handle -> RPort . TxHeight;

						if(PlusLines > 0 && View -> Lines + PlusLines > View -> Special . List . MaxGrowY)
							PlusLines = View -> Special . List . MaxGrowY - View -> Lines;

						if(PlusLines < 0)
							PlusLines = 0;
					}
					else
					{
						if(View -> Special . List . ResizeY && !Handle -> GrowView)
							PlusLines = (Bounds -> Height - Height) / Handle -> RPort . TxHeight;
						else
							PlusLines = 0;
					}

					if(PlusChars != 0 || PlusLines != 0)
					{
						View -> Chars += PlusChars;
						View -> Lines += PlusLines;

						LTP_ResetGroups(Handle -> TopGroup);

						if(!V39 && (Handle -> RPort . TxFlags & FPF_PROPORTIONAL))
						{
							LTP_Rescale(Handle,FALSE,FALSE);

							Handle -> Rescaled = FALSE;
						}

						Fits = FALSE;
					}
				}

				Handle -> GrowView = NULL;
			}
		}
		while(!Fits && !Handle -> Failed);

#ifdef DO_CLONING
		if(!Handle -> Failed && Cloned)
			LTP_CloneScreen(Handle,Handle -> TopGroup -> Width + PlusWidth,Handle -> TopGroup -> Height + PlusHeight);
#endif

		if(!Handle -> Failed)
		{
			if(Handle -> GadgetArray = LTP_Alloc(Handle,sizeof(struct Gadget *) * Handle -> Count))
			{
#ifdef DO_PICKSHORTCUTS
				LTP_SearchKeys(Handle,Handle -> TopGroup);
				LTP_SelectKeys(Handle,Handle -> TopGroup);
#endif
				LTP_LayoutGadgets(Handle,Handle -> TopGroup);

				if(Handle -> Failed)
				{
					FreeGadgets(Handle -> List);

					Handle -> List = NULL;
				}
			}
		}
	}
}
