/******************************************************************************
 *
 * HSN Datatype, based on the sourcecode found in OS3.1 Native Developer Kit
 *
 * Written by Christian Buchner
 *
 ******************************************************************************
 * classbase.c
 *
 */

#include "classbase.h"

/****** HSN.datatype/HSN.datatype ****************************************
*
*    NAME
*	HSN.datatype -- data type for HSN sounds.
*
*    FUNCTION
*	The HSN data type, a sub-class of the sound.datatype, is used
*	to load HSN files.
*
*    METHODS
*	OM_NEW -- Create a new sound object from a HSN file.  The
*	    source may be either a file or the clipboard.
*
*    SEE ALSO
*	sound.datatype.
*
*******************************************************************************
*
* Created:  27-Feb-92, David N. Junod
* Modified: 09-Jan-95, Christian Buchner
*
*/

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

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

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

struct Library *ASM LibInit (REG (d0) struct ClassBase *cb, REG (a0) BPTR seglist, REG (a6) struct Library * sysbase)
{
	cb->cb_SegList = seglist;
	SysBase = (struct ExecBase*)sysbase;
	InitSemaphore (&cb->cb_Lock);
	if (((struct Library *)SysBase)->lib_Version >= 39)
	{
		DOSBase       = OpenLibrary ("dos.library",      39);
		UtilityBase   = OpenLibrary ("utility.library",  39);
		IntuitionBase = OpenLibrary ("intuition.library",39);
		return cb;
	}
	else
	{
		return NULL;
	}
}

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

LONG ASM LibOpen (REG (a6) struct ClassBase *cb)
{
	LONG retval = (LONG) cb;
	BOOL success = TRUE;
	
	ObtainSemaphore (&cb->cb_Lock);
	
	/* Use an internal use counter */
	cb->cb_Lib.lib_OpenCnt++;
	cb->cb_Lib.lib_Flags &= ~LIBF_DELEXP;
	
	if (cb->cb_Lib.lib_OpenCnt == 1)
	{
		if (cb->cb_Class == NULL)
		{
			success = FALSE;
			if (DataTypesBase = OpenLibrary ("datatypes.library", 0))
				if (cb->cb_SuperClassBase = OpenLibrary ("datatypes/sound.datatype", 39))
					if (cb->cb_Class = initClass (cb))
						success = TRUE;
		}
	}
	
	if (!success)
	{
		CloseLibrary (cb->cb_SuperClassBase);
		CloseLibrary (DataTypesBase);
		cb->cb_Lib.lib_OpenCnt--;
		retval = NULL;
	}
	
	ReleaseSemaphore (&cb->cb_Lock);
	
	return (retval);
}

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

LONG ASM LibClose (REG (a6) struct ClassBase *cb)
{
	LONG retval = NULL;
	
	ObtainSemaphore (&cb->cb_Lock);
	
	if (cb->cb_Lib.lib_OpenCnt)
	cb->cb_Lib.lib_OpenCnt--;
	
	if ((cb->cb_Lib.lib_OpenCnt == 0) && cb->cb_Class)
	{
		if (FreeClass (cb->cb_Class))
		{
			CloseLibrary (cb->cb_SuperClassBase);
			CloseLibrary (DataTypesBase);
			cb->cb_Class = NULL;
		}
		else
		{
			cb->cb_Lib.lib_Flags |= LIBF_DELEXP;
		}
	}
	
	if (cb->cb_Lib.lib_Flags & LIBF_DELEXP)
	retval = LibExpunge (cb);
	
	ReleaseSemaphore (&cb->cb_Lock);
	
	return (retval);
}

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

LONG ASM LibExpunge (REG (a6) struct ClassBase *cb)
{
	BPTR seg = cb->cb_SegList;
	
	if (cb->cb_Lib.lib_OpenCnt)
	{
	cb->cb_Lib.lib_Flags |= LIBF_DELEXP;
	return (NULL);
	}
	
	Remove ((struct Node *) cb);
	
	CloseLibrary (IntuitionBase);
	CloseLibrary (UtilityBase);
	CloseLibrary (DOSBase);
	
	FreeMem ((APTR)((ULONG)(cb) - (ULONG)(cb->cb_Lib.lib_NegSize)), cb->cb_Lib.lib_NegSize + cb->cb_Lib.lib_PosSize);
	
	return ((LONG) seg);
}

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

void ASM LibReserved(REG (a6) struct ClassBase *cb)
{
}
