  /*********************/
 /*     Pointer.c     */
/*********************/


#if LIBRARY
	#include <clib/exec_protos.h>
	#include <pragmas/exec_pragmas.h>
#else
	#include <proto/exec.h>
	#include <stdio.h>
	#include <stdlib.h>
#endif

#include <intuition/intuition.h>
#include <proto/intuition.h>
/*#include <libraries/dos.h>*/
#include <dos.h>
#include <proto/dos.h>
#include <proto/iffparse.h>
#include <libraries/iffparse.h>
#include <exec/memory.h>
#include <error.h>
#include "PointerCust.h"
#include "PointerLib.h"
#include "Pointer.h"
#include "myilbm.h"

#if LIBRARY
	extern struct ExecBase* SysBase;
#endif
struct DosLibrary *DOSBase;
struct Library	*IFFParseBase;

static long	ilbmprops[] =
{
	ID_ILBM, ID_BMHD,
	ID_ILBM, ID_CMAP,
	ID_ILBM, ID_GRAB
};

extern struct Pointer *BusyPointer;
extern struct IntuitionBase *IntuitionBase;

#if LIBRARY
void __saveds __asm LIBSetBusyPointer( register __a0 struct Window *window )
#else
void LIBSetBusyPointer( struct Window *window )
#endif
{

	SetPointer( window, BusyPointer->Data,
		BusyPointer->Height, BusyPointer->Width,
		BusyPointer->XOff, BusyPointer->YOff );

	return;
}


  /***********************************/
 /*  IFF Parser LIFTED from tiff.c  */
/***********************************/
/*	tiff.c was written by:
		Stuart Ferguson,
		ewhac,
		shf
*/


#if LIBRARY
struct Pointer* __saveds __asm LIBLoadPointer( register __a0 char *filename )
#else
struct Pointer* LIBLoadPointer( char *filename )
#endif
{
struct Pointer* NewPointer;
struct IFFHandle *iff;
struct ContextNode *cn;
struct StoredProperty *sp;
struct ContextNode *body;
struct BitMapHeader *bmhd;
long error;
int count;
/*
int ii;
USHORT* clear;
*/

	if( !(DOSBase = (struct DosLibrary*)OpenLibrary( "dos.library", 0L ) ) )
	{
		NewPointer = NULL;
		goto end;
	}

	if( !(IFFParseBase = OpenLibrary( "iffparse.library", 0L ) ) )
	{
		NewPointer = NULL;
		goto end;
	}

	NewPointer = (struct Pointer*)AllocMem( sizeof( struct Pointer ),
		MEMF_PUBLIC );

	if( NewPointer == 0 )
	{
		NewPointer = NULL;
		goto end;
	}

	/*
	 * Create IFF file and open a DOS stream on it.
	 */
	if( !( iff = AllocIFF() ) )
	{
		NewPointer = NULL;
		goto end;
	}

	if( !( iff->iff_Stream = Open( filename, MODE_OLDFILE ) ) )
	{
		NewPointer = NULL;
		goto end;
	}
	InitIFFasDOS( iff );

	/*
	 * Declare property, collection and stop chunks.
	 */
	if( error = PropChunks( iff, ilbmprops, 3L ) )
		goto end;
	if( error = StopChunk( iff, ID_ILBM, ID_BODY ) )
		goto end;
	if( error = CollectionChunk( iff, ID_ILBM, ID_CRNG ) )
		goto end;

	/*
	 * We want to stop at the end of an ILBM context.
	 */
	if( error = StopOnExit( iff, ID_ILBM, ID_FORM ) )
		goto end;

	if( error = OpenIFF( iff, IFFF_READ ) )
		goto end;

	/*
	 * Take first parse step to enter main chunk.
	 */
	if( error = ParseIFF( iff, IFFPARSE_STEP ) )
		goto end;

	/*
	 * Test the chunk info to see if this is a simple ILBM.
	 */
	if( !( cn = CurrentChunk( iff ) ) )
	{
		NewPointer = NULL;
		/*puts( "No top chunk!" );*/
		goto end;
	}
	if( cn->cn_ID != ID_FORM  ||  cn->cn_Type != ID_ILBM )
	{
		NewPointer = NULL;
		/*puts( "Not a FORM ILBM.  Blundering on anyway..." );*/
	}

	while( !error )
	{
		/*
		 * ParseIFF() will return on BODY chunk or end of
		 * context for an ILBM FORM.
		 */
		error = ParseIFF( iff, IFFPARSE_SCAN );

		/*	Did I delete something important?	*/

		/*
		 * Other values for error are real errors.
		 */
		if( error )
			break;

		if( sp = FindProp( iff, ID_ILBM, ID_BMHD ) )
		{
			bmhd = (struct BitMapHeader*)sp->sp_Data;
			if( bmhd->Compression != NULL )
			{
				NewPointer = NULL;
				goto end;
			}
			NewPointer->Width = bmhd->w;
			NewPointer->Height = bmhd->h;
		}
		else
		{
			NewPointer = NULL;
			goto end;
			/*puts( "No BMHD chunk." );*/
		}
 
		/*	NewPointer Doesn't touch CMAP!	*/
		
		NewPointer->XOff = 0;
		NewPointer->YOff = 0;
		if( sp = FindProp( iff, ID_ILBM, ID_GRAB ) )
		{
			NewPointer->XOff = -(*(USHORT*)sp->sp_Data);
			NewPointer->YOff = -(*(USHORT*)(sp->sp_Data+2));
		}
 
		body = CurrentChunk( iff );
		NewPointer->Size = body->cn_Size+8;
		NewPointer->Data = (USHORT*)AllocMem( NewPointer->Size, MEMF_CHIP );
		if( NewPointer->Data == NULL )
		{
			NewPointer = NULL;
			goto end;
		}
/*		for( clear = NewPointer->Data, ii = 0;
				ii< NewPointer->Size; clear++, ++ii++ )
			*clear = 0;
*/
 		count = ReadChunkRecords( iff, NewPointer->Data+2, body->cn_Size>>1, 2 );
	}

end:
	if( iff )
	{
		CloseIFF( iff );
		if( iff->iff_Stream )
			Close( iff->iff_Stream );
		FreeIFF( iff );
	}

	if( IFFParseBase )
		CloseLibrary( IFFParseBase );
	if( DOSBase )
		CloseLibrary( (struct Library*)DOSBase );

	return( NewPointer );
}


void __asm __saveds LIBFreePointer( register __a0 struct Pointer *OldPointer );
void __asm __saveds LIBFreePointer( register __a0 struct Pointer *OldPointer )
{
	if( OldPointer->Data )
		FreeMem( OldPointer->Data, OldPointer->Size );
	FreeMem( OldPointer, sizeof( struct Pointer ) );

	return;
}
