/*  :ts=8 bk=0
 *
 * tiff.c:	ILBM scanner utilizing DeclareProp().
 *		Alpha Concept Prototype.
 *
 * All the code needed for an ILBM reader, except the stuff to process the
 * ILBM itself.
 *
 * Stuart Ferguson				8807.??
 * Leo L. Schwab (adjusted for new semantics)	8808.16
 *
 * Adjustments; added "This ain't an ILBM" feature.
 * Leo L. Schwab				8811.02
 *
 * Updated to Dec 88 design revision
 * shf						8812.15
 *
 * Updated to 1.4 Beta
 * ewhac					8912.06
 */
#include <exec/types.h>
#include <libraries/dos.h>
#include <iff/iffparse.h>
#include "ifffuncs.h"

#define	ID_ILBM	MAKE_ID('I','L','B','M')
#define	ID_BODY	MAKE_ID('B','O','D','Y')
#define	ID_BMHD	MAKE_ID('B','M','H','D')
#define	ID_CMAP	MAKE_ID('C','M','A','P')
#define	ID_CAMG	MAKE_ID('C','A','M','G')
#define	ID_CRNG	MAKE_ID('C','R','N','G')

extern void	*OpenLibrary();
extern LONG	Open();

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

struct Library	*IFFParseBase;


main (argc, argv)
int	argc;
char	**argv;
{
	struct IFFHandle	*iff;
	struct ContextNode	*cn;
	long			error;
	char			foundbody = 0, gottoend = 0;

	if (!(IFFParseBase = OpenLibrary ("iffparse.library", 0L))) {
		puts ("Cannot open library.");
		goto die;
	}

	/*
	 * Create IFF file and open a DOS stream on it.
	 */
	if (!(iff = AllocIFF())) {
		puts ("AllocIFF() failed.");
		goto die;
	}

	if (!(iff -> iff_Stream = Open (argv[1], MODE_OLDFILE))) {
		puts ("File open failed.");
		goto die;
	}
	InitIFFasDOS (iff);

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

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

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

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

	/*
	 * Test the chunk info to see if this is a simple ILBM.
	 */
	if (!(cn = CurrentChunk (iff))) {
		puts ("No top chunk!");
		goto die;
	}
	if (cn -> cn_ID != ID_FORM  ||  cn -> cn_Type != ID_ILBM)
		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);

		/*
		 * Test for end of context condition and process
		 * collected CRNG chunks here.
		 */
		if (error == IFFERR_EOC) {
			ProcessCrng (iff);
			/* error = 0;
			   continue;
			 */
			break;
		}

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

		ProcessBody (iff);
		foundbody = 1;
	}
err:
	if (error == IFFERR_EOC) {
		if (foundbody)
			puts ("File scan complete.");
		else
			puts ("Failed to find an ILBM BODY chunk.");
	} else if (error == IFFERR_EOF)
		puts ("Failed to find a FORM ILBM.");
	else
		printf ("File scan aborted (%ld)\n", error);

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

	if (IFFParseBase)	CloseLibrary (IFFParseBase);
}


ProcessBody (iff)
struct IFF_File *iff;
{
	register struct StoredProperty	*sp;

	if (sp = FindProp (iff, ID_ILBM, ID_BMHD))
		printf ("BMHD chunk, size: %ld\n", sp -> sp_Size);
	else
		puts ("No BMHD chunk.");

	if (sp = FindProp (iff, ID_ILBM, ID_CMAP))
		printf ("CMAP chunk, size: %ld\n", sp -> sp_Size);
	else
		puts ("No CMAP chunk.");

	if (sp = FindProp (iff, ID_ILBM, ID_CAMG))
		printf ("CAMG chunk, size: %ld\n", sp -> sp_Size);
	else
		puts ("No CAMG chunk.");

	printf ("BODY chunk, size: %ld\n", CurrentChunk (iff) -> cn_Size);
}


ProcessCrng (iff)
struct IFF_File *iff;
{
	register struct CollectionItem	*ci;

	ci = FindCollection (iff, ID_ILBM, ID_CRNG);
	if (!ci) {
		puts ("No CRNG chunks.");
		return;
	}

	for (; ci; ci = ci -> ci_Next) {
		printf ("CRNG chunk, size: %ld\n", ci -> ci_Size);
	}
}
