#include "xprxmodem.h"
#include <exec/resident.h>

void myInit(void);
long myOpen(void);
long myClose(void);
long myExpunge(void);

#pragma amicall(XProtocolBase, 0x06, myOpen())
#pragma amicall(XProtocolBase, 0x0c, myClose())
#pragma amicall(XProtocolBase, 0x12, myExpunge())

/* library initialization table, used for AUTOINIT libraries			 */
struct InitTable {
	unsigned long it_DataSize;	/* library data space size		 */
	void **it_FuncTable;	/* table of entry points			 */
	void *it_DataInit;	/* table of data initializers		 */
	void (*it_InitFunc) (void);	/* initialization function to run	 */
};

static void *libfunctab[] =
{				/* my function table */
	myOpen,			/* standard open	 */
	myClose,		/* standard close	 */
	myExpunge,		/* standard expunge	 */
	0,
	XProtocolCleanup,
	XProtocolSetup,
	XProtocolSend,
	XProtocolReceive,
	(void *) -1		/* end of function vector table */
};

struct InitTable myInitTab =
{
	sizeof(struct XProtocolBase),
	libfunctab,
	0,			/* will initialize my data in funkymain()	 */
	myInit
};

#define MYREVISION	36	/* would be nice to auto-increment this		 */

char myname[] = "xprxmodem.library";
char myid[] = "xprxmodem 34.3 (" __DATE__ ")\n";

extern struct Resident myRomTag;

struct IntuitionBase *IntuitionBase = 0;

void _main(struct XProtocolBase * XProtocolBase, unsigned long seglist)
{
	XProtocolBase->xp_SegList = seglist;

	/* ----- init. library structure  -----		 */
	XProtocolBase->xp_Lib.lib_Node.ln_Type = NT_LIBRARY;
	XProtocolBase->xp_Lib.lib_Node.ln_Name = (char *) myname;
	XProtocolBase->xp_Lib.lib_Flags = LIBF_SUMUSED | LIBF_CHANGED;
	XProtocolBase->xp_Lib.lib_Version = myRomTag.rt_Version;
	XProtocolBase->xp_Lib.lib_Revision = MYREVISION;
	XProtocolBase->xp_Lib.lib_IdString = (APTR) myid;
	IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0);
}

long myOpen(void)
{
	struct XProtocolBase *XProtocolBase;

	/* mark us as having another customer					 */
	XProtocolBase->xp_Lib.lib_OpenCnt++;

	/* prevent delayed expunges (standard procedure)		 */
	XProtocolBase->xp_Lib.lib_Flags &= ~LIBF_DELEXP;

	return ((long) XProtocolBase);
}

long myClose(void)
{
	struct XProtocolBase *XProtocolBase;
	long retval = 0;

	if (--XProtocolBase->xp_Lib.lib_OpenCnt == 0) {
		if (XProtocolBase->xp_Lib.lib_Flags & LIBF_DELEXP) {

			/*
			 * no more people have me open, and I have a delayed
			 * expunge pending
			 */
			retval = myExpunge();	/* return segment list	 */
		}
	}
	return (retval);
}

long myExpunge(void)
{
	struct XProtocolBase *XProtocolBase;
	unsigned long seglist = 0;
	long libsize;

	if (XProtocolBase->xp_Lib.lib_OpenCnt == 0) {

		CloseLibrary((struct Library *) IntuitionBase);

		/* really expunge: remove libbase and freemem */
		seglist = XProtocolBase->xp_SegList;

		Remove(&XProtocolBase->xp_Lib.lib_Node);
		/* i'm no longer an installed library */

		libsize = XProtocolBase->xp_Lib.lib_NegSize + XProtocolBase->xp_Lib.lib_PosSize;
		FreeMem((char *) XProtocolBase - XProtocolBase->xp_Lib.lib_NegSize, libsize);
	} else
		XProtocolBase->xp_Lib.lib_Flags |= LIBF_DELEXP;

	/* return NULL or real seglist */
	return ((long) seglist);
}
