/*
**	GadTools layout toolkit
**
**	Copyright © 1993-1996 by Olaf `Olsen' Barthel
**		Freely distributable.
**
**	:ts=4
*/

#ifndef _GTLAYOUT_GLOBAL_H
#include "gtlayout_global.h"
#endif

#ifdef DO_LEVEL_KIND
VOID
LTP_LevelGadgetDrawLabel(struct Gadget *Gadget,BOOL FullRefresh)
{
	LevelExtra	*Special = (LevelExtra *)Gadget->SpecialInfo;
	LONG		 Current;
	ObjectNode	*Node = (ObjectNode *)Gadget->UserData;

	GetAttr(LVIA_Current,Special->LevelImage,(ULONG *)&Current);

	Current += Special->Plus;

	Special->Level = Current;

	if(Node->Label)
	{
		LayoutHandle *Handle = Special->Handle;

		if(FullRefresh)
			LTP_DrawObjectLabel(Handle,Node);

		if(Special->LevelFormat)
		{
			UBYTE			 Buffer[256];
			struct RastPort *RPort = &Special->Handle->RPort;
			LONG			 LabelTop,LabelLeft;
			LONG			 LevelWidth,
							 LevelLen;

			switch(Special->LevelPlace)
			{
				case PLACETEXT_LEFT:

					LabelLeft	= Node->Left - INTERWIDTH;
					LabelTop	= Node->Top + (Node->Height - Handle->GlyphHeight) / 2;
					break;

				case PLACETEXT_RIGHT:

					LabelLeft	= Node->Left + Node->Width + INTERWIDTH + Special->MaxLevelWidth;
					LabelTop	= Node->Top + (Node->Height - Handle->GlyphHeight) / 2;
					break;

				case PLACETEXT_ABOVE:

					LabelLeft	= Node->Left + (Node->Width - Special->MaxLevelWidth) / 2 + Special->MaxLevelWidth;
					LabelTop	= Node->Top - (Handle->GlyphHeight + INTERHEIGHT);
					break;

				case PLACETEXT_BELOW:

					LabelLeft	= Node->Left + (Node->Width - Special->MaxLevelWidth) / 2 + Special->MaxLevelWidth;
					LabelTop	= Node->Top + Node->Height + INTERHEIGHT;
					break;
			}

			LTP_SetPens(RPort,Handle->TextPen,Handle->BackgroundPen,JAM2);

			if(Special->DispFunc)
				Current = (*Special->DispFunc)(Gadget,Current);

			SPrintf(Buffer,Special->LevelFormat,Current);

			LevelLen = strlen(Buffer);

			LevelWidth = TextLength(RPort,Buffer,LevelLen);

			LTP_PrintText(RPort,Buffer,LevelLen,LabelLeft - LevelWidth,LabelTop);

			if(LevelWidth < Special->MaxLevelWidth)
				LTP_EraseBox(RPort,LabelLeft - Special->MaxLevelWidth,LabelTop,Special->MaxLevelWidth - LevelWidth,Handle->GlyphHeight);
		}
	}
}


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


ULONG
LTP_LevelGadgetRender(struct Gadget *Gadget,struct gpRender *RenderMsg)
{
	LevelExtra *Special = (LevelExtra *)Gadget->SpecialInfo;

	DrawImageState(RenderMsg->gpr_RPort,Special->LevelImage,Gadget->LeftEdge,Gadget->TopEdge,Gadget->Flags & GFLG_DISABLED ? IDS_DISABLED : IDS_NORMAL,Special->Handle->DrawInfo);

	LTP_LevelGadgetDrawLabel(Gadget,RenderMsg->gpr_Redraw == GREDRAW_REDRAW);

	return(TRUE);
}


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


ULONG
LTP_LevelGadgetGoActive(struct Gadget *Gadget,struct gpInput *InputMsg)
{
	LevelExtra		*Special = Gadget->SpecialInfo;
	LONG			 Left;
	ULONG			 Position,
					 KnobWidth,
					 Current,
					 Max;
	LONG			 State;
	struct RastPort	*RPort;

	GetAttr(LVIA_Position,	Special->LevelImage,&Position);
	GetAttr(LVIA_Current,	Special->LevelImage,&Current);
	GetAttr(LVIA_KnobWidth, Special->LevelImage,&KnobWidth);
	GetAttr(LVIA_Max,		Special->LevelImage,&Max);

	Left = InputMsg->gpi_Mouse.X;

	if(Left < Position)
	{
		if(Current > 0)
		{
			State = IDS_NORMAL;

			Current--;
		}
	}
	else
	{
		if(Left > KnobWidth + Position + KnobWidth)
		{
			if(Current < Max)
			{
				State = IDS_NORMAL;

				Current++;
			}
		}
		else
		{
			State = IDS_SELECTED;

			Special->MidOffset = KnobWidth + Position - Left;
		}
	}

	if(RPort = ObtainGIRPort(InputMsg->gpi_GInfo))
	{
		DrawImageState(RPort,Special->LevelImage,Gadget->LeftEdge,Gadget->TopEdge,State,Special->Handle->DrawInfo);

		ReleaseGIRPort(RPort);
	}

	if(State == IDS_NORMAL)
	{
		SetAttrs(Special->LevelImage,LVIA_Current,Current,TAG_DONE);

		LTP_LevelGadgetDrawLabel(Gadget,FALSE);

		*InputMsg->gpi_Termination = FALSE;

		return(GMR_NOREUSE | GMR_VERIFY);
	}
	else
		return(GMR_MEACTIVE);
}


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


ULONG
LTP_LevelGadgetHandleInput(struct Gadget *Gadget,struct gpInput *InputMsg)
{
	if(InputMsg->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE)
	{
		LevelExtra		*Special = Gadget->SpecialInfo;
		LONG			 Left,Width;
		ULONG			 KnobWidth,
						 Position,
						 Current,
						 Max,
						 Result;
		struct RastPort *RPort;
		BOOL			 DrawIt;

		GetAttr(LVIA_Position,	Special->LevelImage,&Position);
		GetAttr(LVIA_KnobWidth, Special->LevelImage,&KnobWidth);
		GetAttr(LVIA_Max,		Special->LevelImage,&Max);

		Left = InputMsg->gpi_Mouse.X + Special->MidOffset - KnobWidth;

		Width = Special->LevelImage->Width - 2 * KnobWidth;

		if(InputMsg->gpi_IEvent->ie_Code == SELECTUP)
		{
			*InputMsg->gpi_Termination = FALSE;

			Result = GMR_NOREUSE | GMR_VERIFY;
		}
		else
			Result = 0;

		if(Left < 0)
			Left = 0;
		else
		{
			if(Left > Width)
				Left = Width;
		}

		if(Max)
		{
			Current = (Left * Max + (Width / (Max * 2))) / Width;

			if(Current > Max)
				Current = Max;
			else
			{
				if(Current < 0)
					Current = 0;
			}
		}
		else
			Current = 0;

		SetAttrs(Special->LevelImage,LVIA_Current,Current,TAG_DONE);

		if(Result)
			DrawIt = TRUE;
		else
		{
			if(Position != Left && Max)
			{
				DrawIt = TRUE;

				SetAttrs(Special->LevelImage,
					LVIA_Position,	Left,
				TAG_DONE);
			}
			else
				DrawIt = FALSE;
		}

		if(DrawIt)
		{
			if(RPort = ObtainGIRPort(InputMsg->gpi_GInfo))
			{
				DrawImageState(RPort,Special->LevelImage,Gadget->LeftEdge,Gadget->TopEdge,Result ? IDS_NORMAL : IDS_SELECTED,Special->Handle->DrawInfo);

				ReleaseGIRPort(RPort);
			}

			LTP_LevelGadgetDrawLabel(Gadget,FALSE);
		}

		return(Result);
	}
	else
		return(0);
}


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

	// Note: this is not a class dispatcher, it's a custom gadget dispatcher

ULONG __saveds __asm
LTP_LevelGadgetDispatcher(REG(a0) struct Hook *Hook,REG(a2) struct Gadget *Gadget,REG(a1) Msg msg)
{
	switch(msg->MethodID)
	{
		case GM_HITTEST:
			return(GMR_GADGETHIT);

		case GM_RENDER:
			return(LTP_LevelGadgetRender(Gadget,(struct gpRender *)msg));

		case GM_GOACTIVE:
			return(LTP_LevelGadgetGoActive(Gadget,(struct gpInput *)msg));

		case GM_HANDLEINPUT:
			return(LTP_LevelGadgetHandleInput(Gadget,(struct gpInput *)msg));

		default:
			return(0);
	}
}
#endif /* DO_LEVEL_KIND */
