
/******************************************************************************
 *
 * Flowerpower's AOM_Raw Datatype
 *
 * Written by Christian Buchner and David N. Junod
 *
 ******************************************************************************
 * dispatch.c
 *
 */

#include "classbase.h"

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

ULONG setdtattrs (struct ClassBase * cb, Object * o, ULONG data,...)
{
	return (SetDTAttrsA (o, NULL, NULL, (struct TagItem *) & data));
}

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

ULONG getdtattrs (struct ClassBase * cb, Object * o, ULONG data,...)
{
	return (GetDTAttrsA (o, (struct TagItem *) & data));
}

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

Class *initClass (struct ClassBase * cb)
{
	Class *cl;
	
	/* Create our class.  Note that this particular class doesn't have any instance data */
	if (cl = MakeClass (AOM_RAWDTCLASS, PICTUREDTCLASS, NULL, NULL, 0L))
	{
		cl->cl_Dispatcher.h_Entry = (ULONG (*)())Dispatch;
		cl->cl_UserData = (ULONG) cb;
		AddClass (cl);
	}
	
	return (cl);
}

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

ULONG __asm Dispatch (register __a0 Class * cl, register __a2 Object * o, register __a1 Msg msg)
{
	struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
	ULONG retval;
	
	switch (msg->MethodID)
	{
		case OM_NEW:
		if (retval = DoSuperMethodA (cl, o, msg))
		{
			if (!GetPicture (cb, cl, (Object *) retval, ((struct opSet *) msg)->ops_AttrList))
			{
				CoerceMethod (cl, (Object *) retval, OM_DISPOSE);
				return NULL;
			}
		}
		break;
		
		/* Let the superclass handle everything else */
		default:
		retval = (ULONG) DoSuperMethodA (cl, o, msg);
		break;
	}
	
	return (retval);
}

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

struct RawHeader
{
	ULONG width;
	ULONG height;
	ULONG depth;
};

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

BOOL __asm GetPicture (register __a6 struct ClassBase * cb, register __a0 Class * cl, register __a2 Object * o, register __a1 struct TagItem * attrs)
{
	BOOL success = FALSE;
	struct BitMapHeader *bmhd;
	struct RawHeader rh;
	struct BitMap *bm;
	UWORD n,ncolors;
	UWORD colors[32];
	ULONG modeid;
	STRPTR title;
	BPTR fh;
	struct ColorRegister *cmap;
	LONG *cregs;
	
	/* Get the default title */
	title = (STRPTR) GetTagData (DTA_Name, NULL, attrs);
	
	/* Get the file handle to read from and the BitMapHeader to write to */
	if (!((getdtattrs (cb, o, DTA_Handle, &fh, PDTA_BitMapHeader, &bmhd, TAG_DONE) == 2) && fh))
	{
		SetIoErr(ERROR_OBJECT_WRONG_TYPE);
	}
	else
	{
		/* Make sure we are at the beginning of the file */
		Seek (fh, 0L, OFFSET_BEGINNING);
		
		if (Read(fh, &rh, sizeof(rh))==sizeof(rh))
		{
			/* Fill in the size information */
			bmhd->bmh_Width  = bmhd->bmh_PageWidth  = rh.width;
			bmhd->bmh_Height = bmhd->bmh_PageHeight = rh.height;
			bmhd->bmh_Depth  = rh.depth;
			
			/* Compute the mode ID */
			modeid = LORES_KEY;
			
			if (bmhd->bmh_Height >= 400)
				modeid |= LACE;
			
			if (bmhd->bmh_Depth==6)
				modeid |= HAM;
			else
				if (bmhd->bmh_Width >= 640)
					modeid = HIRES;
			
			/* Set the number of colors */
			ncolors = 32;
			setdtattrs (cb, o, PDTA_NumColors, ncolors, TAG_DONE);
			
			/* Get the destination for the color information */
			getdtattrs (cb, o,
				PDTA_ColorRegisters,	(ULONG) &cmap,
				PDTA_CRegs,		&cregs,
				TAG_DONE);
			
			if (Read(fh, colors, sizeof(colors))==sizeof(colors))
			{
				/* Set the color information */
				for (n = 0; n < ncolors; n++)
				{
					UWORD col=colors[n];
					
					/* Set the master color table */
					cmap->red = ((col&0xF00)>>4)|((col&0xF00)>>8);
					cmap->green=((col&0x0F0)   )|((col&0x0F0)>>4);
					cmap->blue =((col&0x00F)<<4)|((col&0x00F)   );
					
					/* Set the color table used for remapping */
					cregs[n * 3 + 0] = cmap->red   << 24;
					cregs[n * 3 + 1] = cmap->green << 24;
					cregs[n * 3 + 2] = cmap->blue  << 24;
					
					cmap++;
				}
				
				/* Allocate the bitmap */
				if (!(bm = AllocBitMap (bmhd->bmh_Width, bmhd->bmh_Height, bmhd->bmh_Depth, BMF_CLEAR, NULL)))
				{
					SetIoErr (ERROR_NO_FREE_STORE);
				}
				else
				{
					for (n=0;n<bmhd->bmh_Depth;n++)
					{
						Read(fh, bm->Planes[n], RASSIZE(bmhd->bmh_Width,bmhd->bmh_Height));
					}
					
					/* Set the attributes */
					setdtattrs (cb, o,
						DTA_ObjName,		title,
						DTA_NominalHoriz,	bmhd->bmh_Width,
						DTA_NominalVert,	bmhd->bmh_Height,
						PDTA_BitMap,		bm,
						PDTA_ModeID,		modeid,
						TAG_DONE);
						
					/* Indicate success */
					success = TRUE;
				}
			}
		}
	}
	return (success);
}
