/*  :ts=8 bk=0
 *
 * iffparse.h:	Structure definitions for the all new good nifty IFF code.
 *		Alpha Concept Prototype.
 *
 * Stuart Ferguson			8807.??
 * Leo L. Schwab (semantic changes)	8808.15
 *
 * Added rudimentary callback vectors and read/write mode bits.
 * Added clipboard functions and structures.
 * shf					8808.31
 *
 * Modified for revised design Oct 88.
 * shf					8810.12
 *
 * Updated to Dec 88 design revision.
 * shf					8812.15
 * Added IFF_PRIVATE symbol for denoting private data structures.
 * shf					8902.07
 *
 * New InitIFF() declaration, and a change to IFFM_MODE declaration.
 * ewhac				8902.22
 *
 * Removed private parts.
 * ewhac				8903.07
 ********
 * Copyright 1989 Stuart H. Ferguson and Leo L. Schwab.  All Rights Reserved.
 * Use of this file in the creation of a commercial product without the
 * prior written consent of the Copyright holders is prohibited.
 *
 * Dissemination of this file without prior written consent is prohibited.
 *
 * If you have suggestions for improvements to the parser, we'd like to hear
 * them.  Send them to either of the addresses below, and we'll look them
 * over.  Thanks!
 *
 * Stuart H. Ferguson			Leo L. Schwab
 * 123 James Ave.			23 Summerhill Court
 * Redwood City, CA   94062		Terra Linda, CA   94903-3873
 * well!shf@ucbvax.Berkeley.EDU		well!ewhac@ucbvax.Berkeley.EDU
 */
#ifndef IFF_IFFPARSE_H
#define IFF_IFFPARSE_H

#ifndef EXEC_TYPES_H
#include <exec/types.h>
#endif
#ifndef EXEC_LISTS_H
#include <exec/lists.h>
#endif
#ifndef EXEC_PORTS_H
#include <exec/ports.h>
#endif
#ifndef DEVICES_CLIPBOARD_H
#include <devices/clipboard.h>
#endif

/*
 * Struct associated with an active IFF file.
 * "iff_Stream" is a value used by the read/write functions -
 * it will not be accessed by the library itself and can have any value
 * (could even be a pointer or a BPTR).
 **
 * ewhac:  Philosophical problem.  ULONG implies "big unsigned int".  APTR
 * implies "pointer to something".  It just so happens that sizeof (ULONG) ==
 * sizeof (APTR).  What if someone comes along with a long that's 64 bits
 * wide?  Does exec/types.h get hacked by CBM to maintain the element sizes?
 * (A pretty strong argument can be made in favor of that.)
 */
struct IFF_File {
	ULONG			iff_Stream;
	ULONG			iff_Flags;
	LONG			iff_Depth;
	/*  There are private fields hiding here.  */
};

/*
 * Bit masks for "flags" field.
 */
#define IFFM_READ	0L			/* read mode - default */
#define IFFM_WRITE	1L			/* write mode */
#define IFFM_FSEEK	(1L<<1)			/* forward seek only */
#define IFFM_RSEEK	(1L<<2)			/* random seek */
#define IFFM_MODE	(IFFM_READ | IFFM_WRITE)	/* read/write bit */

/*
 * A node associated with a context on the iff_Stack.  Each node
 * represents a chunk, the stack representing the current nesting 
 * of chunks in the open IFF file.  Each context node has associated
 * local context items in the LocalItems list.  The ID, type, size and
 * scan values describe the chunk associated with this node.
 */
struct ContextNode {
	struct MinNode	cn_Node;
	LONG		cn_ID;
	LONG		cn_Type;
	LONG		cn_Size;
	/*  There are private fields hiding here.  */
};

/*
 * Local context items live in the ContextNode's.  Each class 
 * is identified by its lci_Ident code and has a purge vector for
 * when the parent context node is popped.
 */
struct LocalContextItem {
	struct MinNode	lci_Node;
	ULONG		lci_Ident,
			lci_ID,
			lci_Type;
	/*  There are private fields hiding here.  */
};

/*
 * StoredProperty: a local context item containing the data stored
 * from a previously encountered property chunk.
 */
struct StoredProperty {
	LONG			sp_Size;
	UBYTE			*sp_Data;
};

/*
 * Collection Item: the actual node in the collection list that the
 * client will look at.  The next pointers cross context boundaries
 * so that the complete list is accessable.
 */
struct CollectionItem {
	struct CollectionItem	*ci_Next;
	LONG			ci_Size;
	UBYTE			*ci_Data;
};

/*
 * Issue (shf): Should this be here, or should it be private to iffi.c?
 **
 * ewhac:  I think it should be public.  It has general use outside of
 * IFF applications.  Privatizing it also makes it real hard to do POST
 * commands to the clipboard.
 */
struct ClipboardHandle {
	struct IOClipReq	cbh_Req;
	struct MsgPort		cbh_CBport;
	struct MsgPort		cbh_SatisfyPort;
};

/*
 * IFF return codes.  Most functions return either zero for success or
 * one of these codes.  The exception are the read/write functions which
 * return positive values for number of bytes or records read or written,
 * or a negative error code.  Some of these codes are not errors per sae,
 * but valid conditions such as EOF or EOC (End of Chunk).
 */
#define	IFFERR_EOF		-1L
#define IFFERR_EOC		-2L
#define	IFFERR_NOSCOPE		-3L
#define	IFFERR_NOMEM		-4L
#define	IFFERR_READ		-5L
#define	IFFERR_WRITE		-6L
#define	IFFERR_SEEK		-7L
#define	IFFERR_MANGLED		-8L
#define	IFFERR_SYNTAX		-9L
#define	IFFERR_NOTIFF		-10L
#define IFF_RETURN2CLIENT	-11L

#define	MAKE_ID(a,b,c,d)	((a<<24L) | (b<<16L) | (c<<8L) | d)

/*
 * Universal IFF identifiers.
 */
#define	ID_FORM			MAKE_ID('F','O','R','M')
#define	ID_LIST			MAKE_ID('L','I','S','T')
#define	ID_CAT			MAKE_ID('C','A','T',' ')
#define	ID_PROP			MAKE_ID('P','R','O','P')

/*
 * Ident codes for universally recognized local context items.
 */
#define IFFLCI_PROP		MAKE_ID('p','r','o','p')
#define IFFLCI_COLLECTION	MAKE_ID('c','o','l','l')
#define IFFLCI_ENTRYHANDLER	MAKE_ID('e','n','h','d')
#define IFFLCI_EXITHANDLER	MAKE_ID('e','x','h','d')

/*
 * Control modes for ParseIFF() function.
 */
#define IFFPARSE_SCAN		0L
#define IFFPARSE_STEP		1L
#define IFFPARSE_RAWSTEP	2L

/*
 * Control modes for StoreLocalItem().
 */
#define IFFSLI_ROOT		1L
#define IFFSLI_TOP		2L
#define IFFSLI_PROP		3L

/*
 * "Flag" for writing functions.  If you pass this value in as a size
 * to PushChunk() when writing a file, the parser will figure out the
 * size of the chunk for you.  (Chunk sizes >= 2**31 are forbidden by the
 * IFF specification, so this works.)
 */
#define	IFFSIZE_UNKNOWN		-1L

/*
 * High Level Functions.
 */
struct IFF_File		*AllocIFF();
LONG			PropChunk();
LONG			PropChunks();
LONG			StopChunk();
LONG			StopChunks();
LONG			CollectionChunk();
LONG			CollectionChunks();
LONG			StopOnExit();
LONG			ParseIFF();
struct StoredProperty	*FindProp();
struct CollectionItem	*FindCollection();
LONG			ReadChunkBytes();
LONG			WriteChunkBytes();
LONG			ReadChunkRecords();
LONG			WriteChunkRecords();
void			OpenIFF();
void			CloseIFF();
void			FreeIFF();

/*
 * Medium level
 */
struct ContextNode	*CurrentChunk();
struct ContextNode	*ParentChunk();
struct ContextNode	*FindPropContext();

/*
 * Low level
 */
LONG			PushChunk();
LONG			PopChunk();
LONG			EntryHandler();
LONG			ExitHandler();
LONG			StoreLocalItem();
void			StoreItemInContext();
struct LocalContextItem	*FindLocalItem();
struct LocalContextItem *AllocLocalItem();
UBYTE			*LocalItemData();
void			SetLocalItemPurge();
void			FreeLocalItem();
LONG			GoodID();
LONG			GoodType();
char			*IDtoStr();

/*
 * Support functions for pre-coded stream types, including
 * DOS files and the Clipboard
 */
void			InitIFF();
void			InitIFFasDOS();
void			InitIFFasClip();
struct ClipboardHandle	*OpenClipboard();
void			CloseClipboard();
void			BeginCB_Read();
LONG			EndCB_Read();
void			BeginCB_Write();
LONG			EndCB_Write();

#endif
