#ifndef XPKMASTER_XPKMASTER_H
#define XPKMASTER_XPKMASTER_H

/* Includeheader

	Name:		xpkmaster.h
	Main:		xpkmaster
	Versionstring:	$VER: xpkmaster.h 1.8 (12.04.97)
	Author:		SDI
	Distribution:	PD
	Description:	Master library global definitions and declarations
			and prototypes

 1.0   05.10.96 : first real version
 1.1   27.12.96 : removed library protos - call now via library interface,
 	allows patching
 1.2   30.01.97 : change of cchecksum proto
 1.3   31.01.97 : checksum changed again
 1.4   01.03.97 : added new flags
 1.5   08.03.97 : changed XpkBuffer a bit
 1.6   31.03.97 : some little corrections
 1.7   02.04.97 : removed obsolete stuff
 1.8   12.04.97 : added DebugTagList
*/

/* To disable PowerPacker support comment out the next line. */
#define USE_POWERPACKER 1

#ifndef __MAXON__
  #include <pragma/xpksub_lib.h>
  #ifdef USE_POWERPACKER
    #include <pragma/powerpacker_lib.h>
  #endif
#else
  #include "SDI_xpksub.h"	// Stubs for xpksub and powerpacker
  #define __asm
#endif

#ifdef SUPPORT_A4
  #define A4SUPP	,a4
  #define A4SUPP2	,xbuf->xb_regA4
  #define A4PROTO	,register __a4 ULONG a4
#else
  #define A4SUPP
  #define A4SUPP2
  #define A4PROTO
#endif

#define SDI_TO_ANSI
#include "SDI_ASM_STD_protos.h"

#include <xpk/xpk.h>
#include <xpk/xpksub.h>

#define ROUNDLONG(x)		(((x)+3)&(~3))	/* round to next longword */
#define DEFAULTCHUNKSIZE	0x8000

#ifndef Min
  #define Min(a,b) ((a) < (b) ? (a) : (b))
  #define max(a,b) ((a) > (b) ? (a) : (b))
#endif

#define CHUNKSIZE 50000

/* The structure used for I/O, special master library version */
struct XpkMasterMsg {
  ULONG  xmm_Type;		/* Read/Write/Alloc/Free/Abort		*/
  STRPTR xmm_Ptr;		/* The mem area to read from/write to	*/
  LONG   xmm_Size;		/* The size of the read/write		*/
  ULONG  xmm_IOError;		/* The IoErr() that occurred		*/
  ULONG  xmm_Reserved;		/* Reserved for future use		*/
  STRPTR xmm_Buf;		/* Specific to the internal hooks	*/
  LONG   xmm_Error;		/* The XPKERR that occurred		*/
  ULONG  xmm_BufLen;
  ULONG  xmm_BufOfs;
  ULONG  xmm_Len;
  ULONG  xmm_Flags;
  ULONG  xmm_FH;
  ULONG  xmm_MemType;
};

#define XIO_GETOUTBUF 1

#define XPKMF_SEEKABLE	0x0001	/* ALL chunks (-dict) are independent	*/
#define XPKMF_DICTCHUNK	0x0002	/* First chunk is a global dictionary	*/
#define XPKMF_FIXSPEED	0x0004	/* Speed is for A3000/25MHz/SCRAM/2.04	*/
#define XPKMF_NOCLOBBER	0x0008	/* Don't overwrite			*/

/* These structures define the file format for compressed streams */
struct XpkStreamHeader {
  ULONG xsh_Pack;
  ULONG xsh_CLen;
  ULONG xsh_Type;
  ULONG xsh_ULen;
  UBYTE xsh_Initial[16];
  UBYTE xsh_Flags;
  UBYTE xsh_HChk;
  UBYTE xsh_SubVrs;
  UBYTE xsh_MasVrs;
};

#define XPK_COOKIE 0x58504b46	/* 'XPKF' - ID for xsh_Pack */

#define XPKSTREAMF_LONGHEADERS  0x01	/* Use XpkLongLocHeaders	*/
#define XPKSTREAMF_PASSWORD     0x02	/* This file encoded		*/
#define XPKSTREAMF_EXTHEADER    0x04	/* Extended globhdr		*/

struct XpkChunkHdrWord {
  UBYTE xchw_Type;
  UBYTE xchw_HChk;
  UWORD xchw_CChk;
  UWORD xchw_CLen;
  UWORD xchw_ULen;
};

struct XpkChunkHdrLong {
  UBYTE xchl_Type;
  UBYTE xchl_HChk;
  UWORD xchl_CChk;
  ULONG xchl_CLen;
  ULONG xchl_ULen;
};

typedef union {
  struct XpkChunkHdrLong xch_Long;
  struct XpkChunkHdrWord xch_Word;
} XpkChunkHeader;

#define XPKCHUNK_TYPE		0x0f
#define XPKCHUNK_RAW		0x00
#define XPKCHUNK_PACKED		0x01
#define XPKCHUNK_FDATA		0x02 /* Protection bits, file comment ... */
#define XPKCHUNK_END		0x0f

#define XPKCHUNKF_ENTRYPOINT	0x80 /* Stream can be seeked to at this point */

struct Headers {
  struct XpkStreamHeader h_Glob;
  XpkChunkHeader	 h_Loc;
  ULONG			 h_LocSize;
};

#define XPKMODE_UPUP   1
#define XPKMODE_UPSTD  2
#define XPKMODE_UPPP   3
#define XPKMODE_PKSTD  20

#define AUTO_PASS_SIZE	50

/* This is what XPK "handles" really point to */
struct XpkBuffer {
  struct XpkFib		 xb_Fib;/* file info about this file		*/
  UWORD   xb_PackingMode;	/* desired packing efficiency, 0..100   */
  struct Headers	 xb_Headers;	/* global and local file header */
  ULONG   xb_Format;		/* type of file				*/
  ULONG   xb_ChunkLen;		/* compressed chunk len			*/
  LONG    xb_Result;		/* error code from last call		*/
//  LONG    xb_Result2;		/* possible result from IoErr()		*/
  STRPTR  xb_ErrBuf;		/* Where user wants the error		*/
  STRPTR *xb_GetOutBuf;		/* Where user wants the out buf addr	*/
  ULONG  *xb_GetOutLen;		/* Where user wants the output len	*/
  ULONG  *xb_GetOutBufLen;	/* Where user wants the out buf len	*/
  ULONG   xb_ULen;		/* Uncompressed length of file		*/
  ULONG   xb_Secs;		/* Start time, the seconds		*/
  ULONG   xb_Mics;		/* Start time, the micros		*/
  struct Hook		*xb_RHook;	/* input data hook		*/
  struct Hook		*xb_WHook;	/* output data hook		*/
  struct Hook		*xb_ChunkHook;	/* Hook to call between chunks	*/
  STRPTR  xb_Password;		/* password for de/encoding		*/
  ULONG   xb_PasswordSize;	/* password buffer size for own password*/
  ULONG   xb_SubPackMode;	/* Packing mode to be used		*/
  ULONG   xb_SubID;		/* ID of currently open sub		*/
  ULONG   xb_ChunkSize;		/* Chunk size to use for packing	*/
  ULONG   xb_FirstChunk;	/* Smallest chunk so far		*/
  ULONG   xb_MinChunk;		/* Minimum size of a chunk		*/
  ULONG   xb_Flags;		/* private for xpkmaster		*/
  LONG    xb_Priority;		/* task pri during packing		*/
  struct XpkInfo	*xb_SubInfo; /* Info of current open sub-lib	*/
  struct Library	*xb_SubBase; /* Currently open sub-library	*/
  LONG    xb_InLen;		/* Number of bytes to (un)pack		*/
  STRPTR  xb_InName;		/* InputName for prefs Recog func	*/
  ULONG   xb_OutLen;		/* Number of bytes written		*/
  ULONG   xb_OutMemType;	/* Type of memory for output buffer	*/
  STRPTR  xb_OutName;		/* Output file name			*/
  struct XpkMasterMsg 	 xb_RMsg; /* Parameters for reading		*/
  struct XpkMasterMsg	 xb_WMsg; /* Parameters for writing		*/
  struct XpkSubParams	 xb_PackParam;/* Parameters to (Un)PackChunk()	*/
  struct XpkProgress	 xb_Prog; /* Parameters to progress report	*/
  STRPTR  xb_LastMsg;		/* The last progress message		*/
#ifdef SUPPORT_A4
  ULONG	  xb_regA4;
#endif
};

/* Values for MasterFlags */
#define XMF_PRIVFH	(1<<0)	/* We opened the FH, so we close it.	*/
#define XMF_PACKING	(1<<1)	/* This is a packing operation.		*/
#define XMF_PASSTHRU	(1<<2)	/* Pass uncompressed data through	*/
#define XMF_GETOUTBUF	(1<<3)	/* Get output buffer when size known	*/
#define XMF_NOCLOBBER	(1<<4)	/* Don't overwrite			*/
#define XMF_EOF		(1<<5)	/* End of file				*/
#define XMF_IDSENT	(1<<6)	/* First four bytes of unpacked sent	*/
#define XMF_INITED	(1<<7)	/* Sublib buffers have been allocted	*/
#define XMF_GLOBHDR	(1<<8)	/* GlobHdr is already written		*/
#define XMF_LOSSYOK	(1<<9)	/* Lossy compression permitted		*/
#define XMF_OWNTASKPRI	(1<<10) /* Altered task pri, restore		*/
#define XMF_NOCRC	(1<<11)	/* Do not check the checksum on decomp	*/
#define XMF_USECOMMENT	(1<<12) /* Store FIB in file comment		*/
#define XMF_NOPREFS	(1<<13) /* Are prefs allowed ?			*/
#define XMF_XFD		(1<<14) /* Is XFD unpacking allowed ?		*/
#define XMF_EXTERNALS	(1<<15) /* Is extern allowed ?			*/
#define XMF_AUTOPASSWD	(1<<16) /* Automatic password			*/
#define XMF_AUTOPRHOOK  (1<<17) /* Automatic Progress hook		*/
#define XMF_NOPACK	(1<<18) /* destination file equals source	*/
#define XMF_OWNPASSWORD (1<<19) /* free password buffer later !!!	*/

#ifdef DEBUG
void 	DebugError(STRPTR, ...);			// debug.c
void 	DebugRunTime(STRPTR, ...);			// debug.c
void    DebugTagList(STRPTR, struct TagItem *);		// debug.c
#endif

ULONG __asm MyCallHookPkt(register __a0 struct Hook *,
register __a1 APTR A4PROTO);

extern struct DosLibrary       *DOSBase;		// libdata.a
extern struct Hook		fhinhook;		// hook_fh.c
extern struct Hook		fhouthook;		// hook_fh.c
extern struct IntuitionBase    *IntuitionBase;		// libdata.a
extern UBYTE			MainVersion;		// libdata.a
extern struct Hook		meminhook;		// hook_mem.c
extern struct Hook		memouthook;		// hook_mem.c
extern struct ExecBase         *SysBase;		// libdata.a
extern struct Library	       *UtilityBase;		// libdata.a
extern struct Library	       *XpkBase;		// libdata.a

LONG	callprogress(struct XpkBuffer *);			// progress.c
UWORD	cchecksum(ULONG *, ULONG);				// checksum.c
void	closesub(struct XpkBuffer *);				// sublibs.c
LONG	freebufs(struct XpkBuffer *);				// xbuf.h
struct XpkPrefsSemaphore *GetPrefsSem(void);			// objects.c
UBYTE	hchecksum(STRPTR, ULONG);				// checksum.c
APTR	hookread(struct XpkBuffer *, ULONG, APTR, ULONG);	// hook.c
APTR	hookwrite(struct XpkBuffer *, ULONG, APTR, ULONG);	// hook.c
ULONG	idfromname(STRPTR);					// util.c
struct XpkBuffer	*initxbuf(void);			// xbuf.h
struct Library		*opensub(struct XpkBuffer *, ULONG);	// sublibs.c
LONG	parsebuftags(struct XpkBuffer*, struct TagItem*, ULONG);// tags.c
void	parseerrortags(struct TagItem *);			// tags.c
void	parsegettags(struct XpkBuffer *);			// tags.c
void	percentages(struct XpkFib *);				// fib.c
void	updatefib(struct XpkBuffer *);				// fib.c
LONG	__asm xpkopen(   register __a0 struct XpkBuffer **,
			 register __a1 struct TagItem *,
			 register __d2 ULONG
			 A4PROTO);				// open.c
LONG	xpkopenwrite(struct XpkBuffer **, struct TagItem *);	// open.c

#endif /* XPKMASTER_XPKMASTER_H */
