/****************************************************************************
*
* VERSION
*	$VER: datatypes.c 1.60 (03.12.93)
*
* DESCRIPTION
*	Datatypes code...
*
* AUTHOR
*	Rune Johnsrud
*
* COPYRIGHT
*	(c) 1993 Amiga Freelancers
*
*****************************************************************************/

#include <exec/types.h>
#include <exec/memory.h>
#include <graphics/gfx.h>
#include <datatypes/datatypes.h>
#include <datatypes/datatypesclass.h>
#include <datatypes/pictureclass.h>
#include <intuition/icclass.h>
#include <utility/date.h>
#include <libraries/asl.h>

#include <clib/alib_protos.h>
#include <clib/alib_stdio_protos.h>

#include <proto/intuition.h>
#include <proto/datatypes.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/utility.h>

#include <string.h>

#include "global.h"

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

extern struct GlobalData *gd;
extern struct ClockInfo *ci;

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

static WORD SyncLayout(Object *o, struct Window *win);

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


WORD ReadDTPic(BOOL render)
{
	WORD errcode = NOERROR, x, y, nw, nh;
    ULONG nomwidth, nomheight;
	Object *o = NULL;
    struct dtFrameBox *dtf = NULL;
    struct FrameInfo *fri = NULL;

	dtf = AllocVec(sizeof(struct dtFrameBox), MEMF_CLEAR);
	fri = AllocVec(sizeof(struct FrameInfo),  MEMF_CLEAR);

	if (dtf && fri)
	{
		o = NewDTObject((APTR) ci->BDRPic,
				DTA_SourceType,	DTST_FILE,
				DTA_GroupID,	GID_PICTURE,
				TAG_DONE);

		if (o)
		{
			if (GetDTAttrs(o,
				DTA_NominalHoriz, &nomwidth,
				DTA_NominalVert,  &nomheight,
				TAG_DONE))
			{
				dtf->MethodID			= DTM_FRAMEBOX;
				dtf->dtf_FrameInfo		= fri;
				dtf->dtf_ContentsInfo	= fri;
				dtf->dtf_SizeFrameInfo	= sizeof(struct FrameInfo);

				if (DoDTMethodA(o, NULL, NULL, (Msg) dtf) && fri->fri_Dimensions.Depth)
				{
					if ((nomwidth > 32000) || (nomwidth == 0))
						nw = fri->fri_Dimensions.Width;
					else
						nw = nomwidth;

					if ((nomheight > 32000) || (nomheight == 0))
						nh = fri->fri_Dimensions.Height;
					else
						nh = nomheight;

					if (nw < ci->InnerWidth)
						x = ((ci->InnerWidth - nw) / 2);
					else
						x = ci->InnerLeft;

					if (nh < ci->InnerHeight)
						y = ((ci->InnerHeight - nh) / 2);
					else
						y = ci->InnerTop;

					if (ci->AutoSize)
					{
						ci->Width  = nw;
						ci->Height = nh;
					}

					if (render)
					{
						SetDTAttrs(o, NULL, NULL,
						    GA_Left,	x,
						    GA_Top,		y,
						    GA_Width,	ci->InnerWidth,
						    GA_Height,	ci->InnerHeight,
						    ICA_TARGET,	ICTARGET_IDCMP,
						    TAG_DONE);

						AddDTObject(gd->ClockWindow, NULL, o, -1);
						errcode = SyncLayout(o, gd->ClockWindow);
					}
				}
				else errcode = DT_ERR_DOMETHOD;
			}
			else errcode = DT_ERR_GETATTRS;
		}
		else
		{
			errcode = IoErr();

			if (errcode >= DTERROR_UNKNOWN_DATATYPE)
				sprintf(gd->SysErr, GetDTString(errcode), ci->BDRPic);
			else
				Fault(errcode, NULL, (STRPTR) gd->SysErr, sizeof(gd->SysErr));

			errcode = SYSERROR;
		}
	}
	else errcode = GEN_ERR_ALLOCMEM;

	if ((gd->ClockWindow) && (render))
	{
		if (o) RemoveDTObject(gd->ClockWindow, o);
	}
	if (o)	 DisposeDTObject(o);
	if (fri) FreeVec(fri);
	if (dtf) FreeVec(dtf);

	return errcode;
}


static WORD SyncLayout(Object *o, struct Window *win)
{
	BOOL done = FALSE;
	WORD errcode = NOERROR;
	ULONG tidata;
	struct IntuiMessage *imsg;
    struct TagItem *tstate, *tag;
    struct TagItem *tags;
	
	while (!done)
	{
		WaitPort(win->UserPort);

	    while (imsg = (struct IntuiMessage *) GetMsg(win->UserPort))
	    {
			switch (imsg->Class)
			{
		    case IDCMP_IDCMPUPDATE:
				tstate = tags = (struct TagItem *) imsg->IAddress;

				while (tag = NextTagItem(&tstate))
				{
				    tidata = tag->ti_Data;

				    switch (tag->ti_Tag)
				    {
					case DTA_Busy:
					    if (tidata)
						{
							SetWindowPointer(win,
								WA_BusyPointer, TRUE,
								TAG_DONE);
						}
						else
						{
							SetWindowPointer(win,
								WA_Pointer, NULL,
								TAG_DONE);
						}
						break;

					case DTA_ErrorLevel:
					    if (tidata)
						{
							errcode = GetTagData(DTA_ErrorNumber, NULL, tags);;

							if (errcode >= DTERROR_UNKNOWN_DATATYPE)
								sprintf(gd->SysErr, GetDTString(errcode), ci->BDRPic);
							else
								Fault(errcode, NULL, (STRPTR) gd->SysErr, sizeof(gd->SysErr));

							errcode = SYSERROR;
						}
					    break;

					case DTA_Sync:
					    RefreshDTObjects(o, win, NULL, NULL);
						done = TRUE;
					    break;
					}
				}
				break;
			}

			ReplyMsg((struct Message *) imsg);
	    }
	}

	return errcode;
}


ULONG ASM FReqFilter(REG (a0) struct Hook *h, REG (a2) struct FileRequester *fr, REG (a1) struct AnchorPath *ap)
{
	struct DataType *dtn;
	ULONG use = FALSE;
	static UBYTE buffer[512];
	BPTR lock;

	if (ap->ap_Info.fib_DirEntryType > 0)
	{
		use = TRUE;
		return (use);
	}

	strncpy(buffer, fr->fr_Drawer, sizeof(buffer));
	AddPart(buffer, ap->ap_Info.fib_FileName, sizeof(buffer));

	if (lock = Lock(buffer, ACCESS_READ))
	{
		if (dtn = ObtainDataTypeA(DTST_FILE, (APTR) lock, NULL))
		{
			if (dtn->dtn_Header->dth_GroupID == GID_PICTURE) use = TRUE;

			ReleaseDataType(dtn);
		}

		UnLock(lock);
    }

    return (use);
}


/* End Of File */
