/*

		Busy.mcc (c) 1994 by kmel, Klaus Melchior

		Registered MUI class, Serial Number: 0002

		busy.c

*/

/* SMAKE */


#define SUPERCLASS "Area.mui"

/*** includes ***/

#include "mui_class.h"
#include "busy_mcc.h"


struct Data
{
	UWORD Pos;
	UWORD Size;
	UBYTE Color1;
	UBYTE Color2;
};


#define DEFAULT_POSITION 0
#define DEFAULT_COLOR1   1
#define DEFAULT_COLOR2   2
#define DEFAULT_SIZE     8


static struct Library *MUIClassBase;
static struct Library *MUIMasterBase;
static struct Library *SysBase;
static struct Library *UtilityBase;
static struct Library *DOSBase;
static struct Library *GfxBase;
static struct Library *IntuitionBase;

struct MUI_CustomClass *ThisClass;


ULONG _New(struct IClass *cl, Object *obj, Msg msg)
{
	struct Data *data;

	if (!(obj = (Object *)DoSuperMethodA(cl, obj, msg)))
		return(0);

	data = INST_DATA(cl, obj);

	/*** parse taglist ***/
	data->Pos    = GetTagData(MUIA_Busy_Position, DEFAULT_POSITION, ((struct opSet *)msg)->ops_AttrList);
	data->Color1 = GetTagData(MUIA_Busy_Color1,   DEFAULT_COLOR1, ((struct opSet *)msg)->ops_AttrList);
	data->Color2 = GetTagData(MUIA_Busy_Color2,   DEFAULT_COLOR2, ((struct opSet *)msg)->ops_AttrList);
	data->Size   = GetTagData(MUIA_Busy_Size,     DEFAULT_SIZE, ((struct opSet *)msg)->ops_AttrList);

	return((ULONG)obj);
}



ULONG _Dispose(struct IClass *cl,Object *obj,Msg msg)
{
	return(DoSuperMethodA(cl,obj,msg));
}



ULONG _Set(struct IClass *cl,Object *obj,Msg msg)
{
	struct Data *data = INST_DATA(cl, obj);
	struct TagItem *tags,*tag;

	for (tags=((struct opSet *)msg)->ops_AttrList;tag=NextTagItem(&tags);)
	{
		switch (tag->ti_Tag)
		{
			case MUIA_Busy_Position:
				data->Pos = tag->ti_Data;
				MUI_Redraw(obj,MADF_DRAWOBJECT);
				break;

			case MUIA_Busy_Color1:
				data->Color1 = tag->ti_Data;
				MUI_Redraw(obj,MADF_DRAWOBJECT);
				break;

			case MUIA_Busy_Color2:
				data->Color2 = tag->ti_Data;
				MUI_Redraw(obj,MADF_DRAWOBJECT);
				break;

			case MUIA_Busy_Size:
				data->Size = tag->ti_Data;
				MUI_Redraw(obj,MADF_DRAWOBJECT);
				break;

		}
	}

	return(DoSuperMethodA(cl,obj,msg));
}


static ULONG _Get(struct IClass *cl,Object *obj,Msg msg)
{
	struct Data *data = INST_DATA(cl,obj);
	ULONG *store = ((struct opGet *)msg)->opg_Storage;

	switch (((struct opGet *)msg)->opg_AttrID)
	{
		case MUIA_Busy_Position:
			*store = data->Pos;
			return(TRUE);
		break;

		case MUIA_Busy_Color1:
			*store = data->Color1;
			return(TRUE);
		break;

		case MUIA_Busy_Color2:
			*store = data->Color2;
			return(TRUE);
		break;

		case MUIA_Busy_Size:
			*store = data->Size;
			return(TRUE);
		break;

	}

	return(DoSuperMethodA(cl,obj,msg));
}


ULONG _AskMinMax(struct IClass *cl, Object *obj, struct MUIP_AskMinMax *msg)
{
	/*** first ask the superclass ***/
	DoSuperMethodA(cl,obj,(Msg)msg);

	/*** add our values ***/
	msg->MinMaxInfo->MinWidth  += 8;
	msg->MinMaxInfo->DefWidth  += 24;
	msg->MinMaxInfo->MaxWidth  += MBQ_MUI_MAXMAX;

	msg->MinMaxInfo->MinHeight += 4;
	msg->MinMaxInfo->DefHeight += 4;
	msg->MinMaxInfo->MaxHeight += MBQ_MUI_MAXMAX;

	return(0);
}


ULONG _Draw(struct IClass *cl,Object *obj,struct MUIP_Draw *msg)
{
	struct Data *data = INST_DATA(cl,obj);
	int i;

	/*** first draw the superclass ***/
	DoSuperMethodA(cl,obj,(Msg)msg);

	/*** move the busy line ***/
	if (msg->flags & MADF_DRAWUPDATE)
	{
		data->Pos += 2;

		if (data->Pos > (data->Size << 1))
			data->Pos -= (data->Size << 1);

		SetBPen(_rp(obj), data->Color2);

		ScrollRaster(_rp(obj), -2, 0,	
			 _mleft(obj), _mtop(obj), _mright(obj) , _mbottom(obj));

		SetAPen(_rp(obj), data->Color1);

		if (data->Pos > data->Size)
			RectFill(_rp(obj), _mleft(obj), _mtop(obj), _mleft(obj) + data->Pos - data->Size - 1, _mbottom(obj));
	}

	else if (msg->flags & MADF_DRAWOBJECT)
	{
		SetAPen(_rp(obj), data->Color2);
		RectFill(_rp(obj), _mleft(obj), _mtop(obj), _mright(obj), _mbottom(obj));

		SetAPen(_rp(obj), data->Color1);

		if (data->Pos > data->Size)
			RectFill(_rp(obj), _mleft(obj), _mtop(obj), _mleft(obj) + data->Pos - data->Size - 1, _mbottom(obj));

		for (i=_mleft(obj) + data->Pos; (i + data->Size) < _mright(obj); i += (data->Size << 1))
			RectFill(_rp(obj), i, _mtop(obj), i + data->Size - 1, _mbottom(obj));

		if (_mright(obj) - i > 0)
			RectFill(_rp(obj), i, _mtop(obj), _mright(obj), _mbottom(obj));
	}

	return(0);
}


ULONG ASM _Dispatcher(REG(a0) struct IClass *cl, REG(a2) Object *obj, REG(a1) Msg msg)
{
	switch (msg->MethodID)
	{
		case OM_NEW        : return(_New      (cl,obj,(APTR)msg));
		case OM_DISPOSE    : return(_Dispose  (cl,obj,(APTR)msg));
		case OM_SET        : return(_Set      (cl,obj,(APTR)msg));
		case OM_GET        : return(_Get      (cl,obj,(APTR)msg));
		case MUIM_AskMinMax: return(_AskMinMax(cl,obj,(APTR)msg));
		case MUIM_Draw     : return(_Draw     (cl,obj,(APTR)msg));

		case MUIM_Busy_Move:
			MUI_Redraw(obj, MADF_DRAWUPDATE);
			return(0);
		break;
	}

	return(DoSuperMethodA(cl,obj,msg));
}


int ASM __UserLibInit(REG(a6) struct Library *mybase)
{
	SysBase = *((struct Library **)4);
	MUIClassBase = mybase;

	if (MUIMasterBase = OpenLibrary("muimaster.library",8))
	{
		if (ThisClass = MUI_CreateCustomClass(
			mybase, SUPERCLASS, NULL, sizeof(struct Data), _Dispatcher))
		{
			UtilityBase   = ThisClass->mcc_UtilityBase;
			DOSBase       = ThisClass->mcc_DOSBase;
			GfxBase       = ThisClass->mcc_GfxBase;
			IntuitionBase = ThisClass->mcc_IntuitionBase;

			return(0);
		}
		CloseLibrary(MUIMasterBase);
	}
	return(-1);
}


void ASM __UserLibCleanup(REG(a6) struct Library *mybase)
{
	if (MUIMasterBase)
	{
		if (ThisClass) MUI_DeleteCustomClass(ThisClass);
		CloseLibrary(MUIMasterBase);
	}
}


struct MUI_CustomClass *ASM MCC_GetClass(VOID)
{
	return(ThisClass);
}
