/*  :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
 *
 * Attempt at Lattice-ification and retrofit of 1.4 hooks.
 * Leo L. Schwab			8912.06
 ********
 * 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.
 *
 * 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 stream.
 * "iff_Stream" is a value used by the client's read/write/seek functions -
 * it will not be accessed by the library itself and can have any value
 * (could even be a pointer or a BPTR).
 */
struct IFFHandle {
	ULONG	iff_Stream;
	ULONG	iff_Flags;
	LONG	iff_Depth;
	/*  There are private fields hiding here.  */
};

/*
 * Bit masks for "iff_Flags" field.
 */
#define IFFF_READ	0L			/* read mode - default */
#define IFFF_WRITE	1L			/* write mode */
#define IFFF_RWBITS	(IFFF_READ | IFFF_WRITE)	/* read/write bits */
#define IFFF_FSEEK	(1L<<1)			/* forward seek only */
#define IFFF_RSEEK	(1L<<2)			/* random seek */
#define	IFFF_RESERVED	0xFFFF0000L		/* Don't touch these bits. */

/*
 * When the library calls your stream handler, you'll be passed a pointer
 * to this structure as the "message packet".
 */
struct IFFStreamCmd {
	LONG	sc_Command;	/*  Operation to be performed		*/
	APTR	sc_Buf;		/*  Pointer to data buffer		*/
	LONG	sc_NBytes;	/*  Number of bytes to be affected	*/
};

/*
 * Possible values for sc_Command.
 */
enum IFFStreamCmdCode {
	IFFSCC_INIT,		/*  Prepare your stream for a session	*/
	IFFSCC_CLEANUP,		/*  Terminate stream session		*/
	IFFSCC_READ,		/*  Read bytes from stream		*/
	IFFSCC_WRITE,		/*  Write bytes to stream		*/
	IFFSCC_SEEK		/*  Seek on stream			*/
};

/*
 * 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 (private) 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;	/*  Size of this chunk		   */
	LONG		cn_Scan;	/*  # of bytes read/written so far */
					/*  You touch cn_Scan, you DIE!!   */
	/*  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 (private) purge vector for when the
 * parent context node is popped.
 */
struct LocalContextItem {
	struct MinNode	lci_Node;
	ULONG		lci_ID,
			lci_Type,
			lci_Ident;
	/*  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 at which
 * client will look.  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;
};

/*
 * Structure returned by OpenClipboard().  You may do CMD_POSTs and such
 * using this structure.  However, once you call OpenIFF(), you may not
 * do any more of your own I/O to the clipboard until you call CloseIFF().
 */
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 exceptions 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	/*  Reached logical end of file	*/
#define IFFERR_EOC		-2L	/*  About to leave context	*/
#define	IFFERR_NOSCOPE		-3L	/*  No valid scope for property	*/
#define	IFFERR_NOMEM		-4L	/*  Internal memory alloc failed*/
#define	IFFERR_READ		-5L	/*  Stream read error		*/
#define	IFFERR_WRITE		-6L	/*  Stream write error		*/
#define	IFFERR_SEEK		-7L	/*  Stream seek error		*/
#define	IFFERR_MANGLED		-8L	/*  Data in file is corrupt	*/
#define	IFFERR_SYNTAX		-9L	/*  IFF syntax error		*/
#define	IFFERR_NOTIFF		-10L	/*  Not an IFF file		*/
#define	IFFERR_NOHOOK		-11L	/*  No call-back hook provided	*/
#define IFF_RETURN2CLIENT	-12L	/*  Client handler normal return*/

#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

#endif
