#include <clib/alib_protos.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <dos/dos.h>
#include <exec/resident.h>
#include "class.h"

#define VERSION 43
#define REVISION 9

struct ClassBase:Library
{
BPTR cb_SegList;
IClass *cb_Class;
SignalSemaphore cb_Lock;
};

extern APTR Dispatcher;
extern ULONG InitTab[];
extern APTR LibVectors[];
extern char LibName[];
extern char LibId[];

ClassBase *LibInit(register __a0 ULONG Segment,register __d0 ClassBase *cb,register __a6 Library *sysbase);
ClassBase *LibOpen(register __a6 ClassBase *cb);
ULONG LibClose(register __a6 ClassBase *cb);
ULONG LibExpunge(register __a6 ClassBase *cb);
IClass *ObtainClass(register __a6 ClassBase *cb);

BOOL L_OpenLibs();
void L_CloseLibs();
IClass *InitClass(ClassBase *cb);

static LONG LibExtFunc()
{
return -1;
}

static Resident RomTag=
{
RTC_MATCHWORD,
&RomTag,
&RomTag+sizeof(RomTag),
RTF_AUTOINIT,
VERSION,
NT_LIBRARY,
0,
LibName,
LibId,
&InitTab
};

char LibName[]="rgfx.datatype";
char LibId[]="$VER:rgfx.datatype 43.9 (15.12.98) © 1997/98 by Achim Stegemann\n";

APTR LibVectors[]=
{
LibOpen,
LibClose,
LibExpunge,
LibExtFunc,
ObtainClass,
APTR(-1),
};

ULONG InitTab[]=
{
sizeof(ClassBase),
ULONG(LibVectors),
0,
ULONG(LibInit)
};

Library *SysBase;
Library *DOSBase;
Library *IntuitionBase;
Library *GfxBase;
Library *UtilityBase;
Library *IFFParseBase;
Library *XpkBase;
Library *RenderBase;
Library *DataTypesBase;
Library *SuperClassBase;
Library *CyberGfxBase;

ClassBase *LibInit(register __a0 ULONG Segment,register __d0 ClassBase *cb,register __a6 Library *sysbase)
{
SysBase=sysbase;
cb->lib_Revision=REVISION;
cb->cb_SegList=Segment;
InitSemaphore(&cb->cb_Lock);
return cb;
}

ClassBase *LibOpen(register __a6 ClassBase *cb)
{
ClassBase *ret=0;
cb->lib_Flags&=~LIBF_DELEXP;
ObtainSemaphore(&cb->cb_Lock);
if(!cb->cb_Class)
	{
	if(L_OpenLibs())
		{
		if(cb->cb_Class=InitClass(cb)) ret=cb;
		}
	}
else ret=cb;
if(ret) cb->lib_OpenCnt++;
ReleaseSemaphore(&cb->cb_Lock);
return ret;
}

ULONG LibClose(register __a6 ClassBase *cb)
{
if(cb->lib_OpenCnt) cb->lib_OpenCnt--;
return (!cb->lib_OpenCnt&&cb->lib_Flags&LIBF_DELEXP)?LibExpunge(cb):0;
}

ULONG LibExpunge(register __a6 ClassBase *cb)
{
if(!cb->lib_OpenCnt)
	{
	if(cb->cb_Class) 
		{
		if(!FreeClass(cb->cb_Class))
			{
			AddClass(cb->cb_Class);
			return 0;
			}
		}
	L_CloseLibs();
	Remove(cb);
	FreeMem((BYTE *)cb-cb->lib_NegSize,cb->lib_NegSize+cb->lib_PosSize);
	return cb->cb_SegList;
	}
else cb->lib_Flags|=LIBF_DELEXP;
return 0;
}

IClass *InitClass(ClassBase *cb)
{
IClass *cl;
if(cl=MakeClass(LibName,"picture.datatype",0,sizeof(Data),0))
	{
	cl->h_Entry=&HookEntry;
	cl->h_SubEntry=&Dispatcher;
	cl->cl_UserData=ULONG(cb);
	AddClass(cl);
	}
return cl;
}

BOOL L_OpenLibs()
{
if(DOSBase=OpenLibrary("dos.library",39))
	{
	if(GfxBase=OpenLibrary("graphics.library",39))
		{
		if(IntuitionBase=OpenLibrary("intuition.library",39))
			{
			if(UtilityBase=OpenLibrary("utility.library",39))
				{
				if(IFFParseBase=OpenLibrary("iffparse.library",39))
					{
					if(XpkBase=OpenLibrary("xpkmaster.library",4))
						{
						if(DataTypesBase=OpenLibrary("datatypes.library",39))
							{
							if(SuperClassBase=OpenLibrary("datatypes/picture.datatype",39))
								{
								if(RenderBase=OpenLibrary("render.library",29))
									{
									CyberGfxBase=OpenLibrary("cybergraphics.library",40);
									return 1;
									}
								}
							}
						}
					}
				}
			}
		}
	}
L_CloseLibs();
return 0;
}

void L_CloseLibs()
{
CloseLibrary(DOSBase);
CloseLibrary(IntuitionBase);
CloseLibrary(GfxBase);
CloseLibrary(UtilityBase);
CloseLibrary(IFFParseBase);
CloseLibrary(DataTypesBase);
CloseLibrary(SuperClassBase);
CloseLibrary(RenderBase);
CloseLibrary(XpkBase);
CloseLibrary(CyberGfxBase);
}

IClass *ObtainClass(register __a6 ClassBase *cb)
{
return cb->cb_Class;
}

