
/*
**
**	aiff.datatype v41
**	© 1998/99 by Stephan Rupprecht
**	All Rights reserved
**
*/

#include <exec/resident.h>
#include <exec/initializers.h>
#include <exec/execbase.h>
#include <exec/libraries.h>
#include <datatypes/soundclass.h>
#include <graphics/gfxbase.h>

#ifdef __GNUC__
#include <inline/exec.h>
#include <inline/intuition.h>
#include <inline/dos.h>
#else
#include <pragma/exec_lib.h>
#include <pragma/intuition_lib.h>
#include <pragma/dos_lib.h>

#define REG( x, a )	register __## x a
#define __regargs
#endif

#include "classbase.h"
#ifdef __GNUC__
#include "BoopsiStubs.h"
#endif

/****************************************************************************/

#define BPTR		ULONG

#define VERSION		41
#define REVISION	3
#define VERSIONSTR	"41.3"
#define DATE		"22.02.00"
#define LIBNAME		"aiff.datatype"

/****************************************************************************/

STATIC struct Library *LibInit(REG(a0, ULONG Segment), REG(d0, struct ClassBase *ClassBase), REG(a6, struct Library *) );
STATIC struct Library *LibOpen( REG(a6, struct ClassBase *ClassBase ) );
STATIC ULONG LibExpunge( REG(a6, struct ClassBase *ClassBase ) );
STATIC ULONG LibClose( REG(a6, struct ClassBase *ClassBase ) );
STATIC LONG LibExtFunc(void);


BOOL __regargs L_OpenLibs(struct ClassBase *);
void __regargs L_CloseLibs(struct ClassBase *);
Class * __regargs initClass (struct ClassBase *);
Class  * ObtainClass(REG(a6, struct ClassBase *) );

extern ULONG   Dispatch(REG(a0, Class *), REG(a2, Object *), REG(a1, Msg ) );

/****************************************************************************/

UBYTE	LibName[] = LIBNAME,
		LibID[] = LIBNAME" "VERSIONSTR" ("DATE") © 1998-2000 by Stephan Rupprecht";

LONG	LibVersion = VERSION,
		LibRevision = REVISION;

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

ULONG LibInitTab[] =
{
	(ULONG) sizeof(struct ClassBase),
	(ULONG) LibVectors,
	(ULONG) NULL,
	(ULONG) LibInit
};

struct Resident ROMTag =     /* do not change */
{
	RTC_MATCHWORD,
 	&ROMTag,
 	&ROMTag + sizeof(ROMTag),
	RTF_AUTOINIT,
 	VERSION,
	NT_LIBRARY,
 	0,
	LibName,
	LibID,
	(APTR)&LibInitTab
};

/****************************************************************************/

LONG LibExtFunc(void)
{
	return(-1L);
}

/****************************************************************************/

#ifdef __GNUC__
#define DOSBase		cb->cb_DOSBase
#define SysBase		cb->cb_SysBase
#define DataTypesBase	cb->cb_DataTypesBase
#define IFFParseBase	cb->cb_IFFParseBase
#define SuperClassBase	cb->cb_SuperClassBase
#define IntuitionBase	cb->cb_IntuitionBase
#define UtilityBase		cb->cb_UtilityBase
#else
struct Library	*SysBase, *DOSBase, *DataTypesBase, *IFFParseBase, *SuperClassBase, *IntuitionBase, *UtilityBase;
#endif

/****************************************************************************/

struct Library *
  LibInit( REG(a0, ULONG Segment), REG(d0, struct ClassBase *cb), REG(a6, struct Library *ExecBase ) )
{
	SysBase = ExecBase;
	cb->LibSegment = Segment;
	cb->LibNode.lib_Revision = REVISION;
	
	if( ( SysBase->lib_Version >= 39L ) && ( ((struct ExecBase *)SysBase)->AttnFlags & AFF_68020 ) )
	{
		if(L_OpenLibs(cb))
		{	
			if(cb->cb_Class = initClass(cb))
			{			
				return((struct Library *)cb);
			}
		}
		
		L_CloseLibs( cb );
	}

	FreeMem((BYTE *)cb-cb->LibNode.lib_NegSize, 
		cb->LibNode.lib_NegSize + cb->LibNode.lib_PosSize);
	
	return(NULL);
}

/****************************************************************************/

struct Library *  LibOpen(REG(a6, struct ClassBase *cb ) )
{	
	cb->LibNode.lib_Flags &= ~LIBF_DELEXP;
	cb->LibNode.lib_OpenCnt++;

	return((struct Library *)cb);
}

/****************************************************************************/

ULONG  LibExpunge(REG(a6, struct ClassBase *cb) )
{
 	if(!cb->LibNode.lib_OpenCnt) 
 	{
		if(cb->cb_Class) 
		{
			if( ! FreeClass(cb->cb_Class) )
			{
				AddClass( cb->cb_Class );
				return NULL;
			}
		}
		
		L_CloseLibs(cb);
		
 		Remove((struct Node *)cb);

  		FreeMem((BYTE *)cb-cb->LibNode.lib_NegSize,
	          cb->LibNode.lib_NegSize + cb->LibNode.lib_PosSize);

		return( cb->LibSegment );
 	} 
 	else 
	{
		cb->LibNode.lib_Flags |= LIBF_DELEXP;
	}

 	return( NULL );
}

/****************************************************************************/

ULONG  LibClose(REG(a6, struct ClassBase *cb) )
{		
 	if(cb->LibNode.lib_OpenCnt) 
	{
		cb->LibNode.lib_OpenCnt--;
	}

 	return((!cb->LibNode.lib_OpenCnt &&
        	 cb->LibNode.lib_Flags & LIBF_DELEXP)?LibExpunge(cb):NULL);
}

/****************************************************************************/

BOOL __regargs L_OpenLibs( struct ClassBase *cb )
{
	if(	( DOSBase = OpenLibrary( "dos.library", 39L ) ) &&
		( IntuitionBase = OpenLibrary( "intuition.library", 39L ) ) &&
		( SuperClassBase = OpenLibrary( "datatypes/v41sound.datatype", 41L ) ) &&
		( DataTypesBase = OpenLibrary( "datatypes.library", 39L ) ) &&
		( UtilityBase = OpenLibrary( "utility.library", 39L ) ) &&
		( IFFParseBase = OpenLibrary( "iffparse.library", 39L ) )	)
	{	
		return( TRUE );
	}
	
	return FALSE;
}

/****************************************************************************/

Class * __regargs initClass ( struct ClassBase *cb )
{
 	register Class *cl;

 	if(cl = MakeClass(LibName, "v41sound.datatype", NULL, 0L, 0L))
  	{
   		cl->cl_Dispatcher.h_Entry = (HOOKFUNC) Dispatch;
   		cl->cl_UserData = (ULONG) cb;
   		AddClass(cl);
  	}

 	return (cl);
}

/****************************************************************************/

void __regargs L_CloseLibs( struct ClassBase *cb )
{
	CloseLibrary( DOSBase );
	CloseLibrary( IntuitionBase );
	CloseLibrary( SuperClassBase );
	CloseLibrary( DataTypesBase );
	CloseLibrary( UtilityBase );
	CloseLibrary( IFFParseBase );
}

/****************************************************************************/

Class *  ObtainClass(REG(a6, struct ClassBase *cb) )
{
	return(cb->cb_Class);
}

/****************************************************************************/
