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

#include "gtlayout_global.h"

#ifdef DO_LEVEL_KIND
VOID __regargs
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)
	{
		struct RastPort *RPort = &Special -> Handle -> RPort;
		LayoutHandle	*Handle = Special -> Handle;
		WORD			 LabelTop,LabelLeft;

		switch(Special -> LevelPlace)
		{
			case PLACETEXT_LEFT:

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

			case PLACETEXT_RIGHT:

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

			case PLACETEXT_ABOVE:

				LabelLeft	= Node -> Left + (Node -> Width - Special -> MaxLevelWidth) / 2 + Special -> MaxLevelWidth;
				LabelTop	= Node -> Top - (Handle -> RPort . TxHeight + 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(FullRefresh)
			LTP_DrawObjectLabel(Handle,Node);

		if(Special -> LevelFormat)
		{
			UBYTE	Buffer[256];
			WORD	LevelWidth,
				LevelLen;

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

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

			LevelLen = strlen(Buffer);

			LevelWidth = TextLength(RPort,Buffer,LevelLen);

			Move(RPort,LabelLeft - LevelWidth,LabelTop + RPort -> TxBaseline);
			Text(RPort,Buffer,LevelLen);

			if(LevelWidth < Special -> MaxLevelWidth)
			{
				LTP_SetAPen(RPort,Handle -> BackgroundPen);
				RectFill(RPort,	LabelLeft - (Special -> MaxLevelWidth),	LabelTop,
								LabelLeft - (LevelWidth + 1),			LabelTop + RPort -> TxHeight - 1);
			}
		}
	}
}


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


ULONG __regargs
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,TRUE);

	return(TRUE);
}


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


ULONG __regargs
LTP_LevelGadgetGoActive(struct Gadget *Gadget,struct gpInput *InputMsg)
{
	LevelExtra		*Special = Gadget -> SpecialInfo;
	LONG			 Left;
	ULONG			 Position,
					 KnobWidth,
					 Current,
					 Max;
	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)
		{
			SetAttrs(Special -> LevelImage,LVIA_Current,Current - 1,TAG_DONE);

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

				ReleaseGIRPort(RPort);
			}

			LTP_LevelGadgetDrawLabel(Gadget,FALSE);
		}

		*InputMsg -> gpi_Termination = FALSE;

		return(GMR_NOREUSE | GMR_VERIFY);
	}

	if(Left > KnobWidth + Position + KnobWidth)
	{
		if(Current < Max)
		{
			SetAttrs(Special -> LevelImage,LVIA_Current,Current + 1,TAG_DONE);

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

				ReleaseGIRPort(RPort);
			}

			LTP_LevelGadgetDrawLabel(Gadget,FALSE);
		}

		*InputMsg -> gpi_Termination = FALSE;

		return(GMR_NOREUSE | GMR_VERIFY);
	}

	Special -> MidOffset = KnobWidth + Position - Left;

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

		ReleaseGIRPort(RPort);
	}

	return(GMR_MEACTIVE);
}


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


ULONG __regargs
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;
		}

//		Current = (Left * Max + Width - 1) / 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);
}


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


ULONG __saveds __asm
LTP_LevelGadgetDispatcher(register __a0 struct Hook *Hook,register __a2 struct Gadget *Gadget,register __a1 Msg msg)
{
	ULONG Result;

	switch(msg -> MethodID)
	{
		case GM_HITTEST:

			Result = GMR_GADGETHIT;
			break;

		case GM_RENDER:

			Result = LTP_LevelGadgetRender(Gadget,(struct gpRender *)msg);
			break;

		case GM_GOACTIVE:

			Result = LTP_LevelGadgetGoActive(Gadget,(struct gpInput *)msg);
			break;

		case GM_HANDLEINPUT:

			Result = LTP_LevelGadgetHandleInput(Gadget,(struct gpInput *)msg);
			break;

		default:

			Result = 0;
			break;
	}

	return(Result);
}
#endif /* DO_LEVEL_KIND */
