//===========================================================================//
// File:	l4audres.cpp                                                        //
// Project: MUNGA           Brick: Audio Renderer Manager	                 //
// Contents: 																					  //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 05/10/95  ECH  Initial coding.                                            //
//---------------------------------------------------------------------------//
// Copyright (C) 1994, Virtual World Entertainment, Inc.                     //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#include <mungal4.hpp>
#pragma hdrstop

#if !defined(L4AUDRES_HPP)
#	include <l4audres.hpp>
#endif

#if !defined(L4AUDHDW_HPP)
#	include <l4audhdw.hpp>
#endif

#if !defined(L4AUDIO_HPP)
#	include <l4audio.hpp>
#endif

#if !defined(L4AUDLVL_HPP)
#	include <l4audlvl.hpp>
#endif

#if !defined(L4AUDWTR_HPP)
#	include <l4audwtr.hpp>
#endif

#if !defined(AUDCMP_HPP)
#	include <audcmp.hpp>
#endif

#if !defined(AUDSEQ_HPP)
#	include <audseq.hpp>
#endif

#if !defined(AUDREND_HPP)
#	include <audrend.hpp>
#endif

#if !defined(NAMELIST_HPP)
#	include <namelist.hpp>
#endif

#if !defined(APP_HPP)
#	include <app.hpp>
#endif

#if !defined(NOTATION_HPP)
#	include <notation.hpp>
#endif

//#############################################################################
//#######################    AudioObjectStream    #############################
//#############################################################################

//
//#############################################################################
// AudioObjectStream
//#############################################################################
//
AudioObjectStream::AudioObjectStream(
	ResourceDescription *resource_description,
   Entity *the_entity
):
	PlugStream(resource_description)
{
	entity = the_entity;
}

//
//#############################################################################
// AudioObjectStream
//#############################################################################
//
AudioObjectStream::AudioObjectStream()
{
	entity = NULL;
}

//
//#############################################################################
// ~AudioObjectStream
//#############################################################################
//
AudioObjectStream::~AudioObjectStream()
{
}

//
//#############################################################################
// TestInstance
//#############################################################################
//
Logical
	AudioObjectStream::TestInstance() const
{
	PlugStream::TestInstance();
   if (entity != NULL)
   {
	   Check(entity);
   }
   return True;
}

//
//#############################################################################
// MakeObjectImplementation
//#############################################################################
//
RegisteredClass*
   AudioObjectStream::MakeObjectImplementation(Enumeration class_ID)
{
	Check(this);
   Verify(class_ID != RegisteredClass::NullClassID);

   //
   //-----------------------------------------------------------------------
   // HACK - Constructors should be referenced through registration, for
   // now just use a switch statement
   //-----------------------------------------------------------------------
   //
	RegisteredClass *object;

   switch (class_ID)
   {
   //
   // Static resources ...
   //
	case RegisteredClass::PatchLevelOfDetailClassID:
		object = new PatchLevelOfDetail(this);
   	break;

	case RegisteredClass::PatchResourceClassID:
   	object = new PatchResource(this);
   	break;

	case RegisteredClass::AudioResourceIndexClassID:
   	object = new AudioResourceIndex(this);
      break;

	//
   // Location and sources ...
   //
	case RegisteredClass::L4AudioLocationClassID:
   	object = new L4AudioLocation(this, entity);
      break;

	case RegisteredClass::DirectPatchSourceClassID:
   	object = new DirectPatchSource(this, entity);
   	break;

	case RegisteredClass::Dynamic3DPatchSourceClassID:
   	object = new Dynamic3DPatchSource(this, entity);
      break;

	case RegisteredClass::Static3DPatchSourceClassID:
   	object = new Static3DPatchSource(this, entity);
      break;

   //
   // Audio components ...
   //
	case RegisteredClass::AudioControlMixerClassID:
   	object = new AudioControlMixer(this, entity);
      break;

	case RegisteredClass::AudioControlMultiplierClassID:
   	object = new AudioControlMultiplier(this, entity);
      break;

	case RegisteredClass::AudioResourceSelectorClassID:
   	object = new AudioResourceSelector(this, entity);
      break;

	case RegisteredClass::AudioControlSmootherClassID:
   	object = new AudioControlSmoother(this, entity);
      break;

	case RegisteredClass::AudioSampleAndHoldClassID:
   	object = new AudioSampleAndHold(this, entity);
      break;

	case RegisteredClass::AudioControlSendClassID:
   	object = new AudioControlSend(this, entity);
      break;

	case RegisteredClass::AudioControlSequenceClassID:
		object = new AudioControlSequence(this, entity);
      break;

	case RegisteredClass::AudioControlSplitterClassID:
		object = new AudioControlSplitter(this, entity);
      break;

	case RegisteredClass::AudioLFOClassID:
		object = new AudioLFO(this, entity);
      break;

	//
   // Audio watchers ...
   //
	case RegisteredClass::AudioMotionTriggerClassID:
   	object = new AudioMotionTrigger(this, entity);
      break;

	case RegisteredClass::AudioMotionScaleClassID:
   	object = new AudioMotionScale(this, entity);
      break;

	case RegisteredClass::AudioHingeScaleClassID:
   	object = new AudioHingeScale(this, entity);
      break;

	case RegisteredClass::AudioScalarTriggerClassID:
   	object = new AudioScalarTrigger(this, entity);
      break;

	case RegisteredClass::AudioScalarScaleClassID:
   	object = new AudioScalarScale(this, entity);
      break;

	case RegisteredClass::AudioLogicalTriggerClassID:
		object = new AudioLogicalTrigger(this, entity);
		break;

	case RegisteredClass::AudioEnumerationTriggerClassID:
   	object = new AudioEnumerationTrigger(this, entity);
      break;

	case RegisteredClass::AudioIntegerTriggerClassID:
   	object = new AudioIntegerTrigger(this, entity);
      break;

	case RegisteredClass::AudioControlsButtonTriggerClassID:
		object = new AudioControlsButtonTrigger(this, entity);
		break;

	case RegisteredClass::AudioStateTriggerClassID:
		object = new AudioStateTrigger(this, entity);
		break;

	case RegisteredClass::AudioIdleWatcherClassID:
		object = new AudioIdleWatcher(this, entity);
      break;

	case RegisteredClass::AudioEnumerationDeltaTriggerClassID:
		object = new AudioEnumerationDeltaTrigger(this, entity);
		break;

	case RegisteredClass::AudioScalarDeltaTriggerClassID:
		object = new AudioScalarDeltaTrigger(this, entity);
		break;

	case RegisteredClass::L4AudioCollisionTriggerClassID:
		object = new L4AudioCollisionTrigger(this, entity);
		break;

	case RegisteredClass::AudioMessageWatcherClassID:
		object = new AudioMessageWatcher(this, entity);
		break;

	case RegisteredClass::AudioControlsButtonMessageWatcherClassID:
		object = new AudioControlsButtonMessageWatcher(this, entity);
		break;

	//
   // Inherited behavior
   //
   default:
      object = PlugStream::MakeObjectImplementation(class_ID);
      break;
   }
   return object;
}

//
//#############################################################################
// CreatedObjectImplementation
//#############################################################################
//
void
   AudioObjectStream::CreatedObjectImplementation(
      RegisteredClass *object,
      ObjectID object_ID
   )
{
	Check(this);
   Check(object);
   Verify(object_ID != NullObjectID);

   //
	// Decide which index to add object to
   //
	switch (object->GetClassID())
   {
	case RegisteredClass::PatchLevelOfDetailClassID:
	case RegisteredClass::PatchResourceClassID:
	case RegisteredClass::AudioResourceIndexClassID:
		AddGlobalPlug(Cast_Object(Plug*, object), object_ID);
      break;

	default:
		AddLocalPlug(Cast_Object(Plug*, object), object_ID);
      break;
   }
}

//
//#############################################################################
// BuildFromPageImplementation
//#############################################################################
//
void
   AudioObjectStream::BuildFromPageImplementation(
      NameList *name_list,
      Enumeration class_ID_enumeration,
      ObjectID object_ID
   )
{
	Check(this);
   Verify(class_ID_enumeration != RegisteredClass::NullClassID);
   Verify(object_ID != NullObjectID);

   //
   //-----------------------------------------------------------------------
   // HACK - Page interpreters should be referenced through registration,
   // for now just use a switch statement
   //-----------------------------------------------------------------------
   //
   RegisteredClass::ClassID
		class_ID = (RegisteredClass::ClassID)class_ID_enumeration;

	switch (class_ID)
   {
   //
	// Static resources ...
   //
	case RegisteredClass::PatchLevelOfDetailClassID:
		PatchLevelOfDetail::BuildFromPage(this, name_list, class_ID, object_ID);
		break;

	case RegisteredClass::PatchResourceClassID:
		PatchResource::BuildFromPage(this, name_list, class_ID, object_ID);
		break;

	case RegisteredClass::AudioResourceIndexClassID:
      AudioResourceIndex::BuildFromPage(this, name_list, class_ID, object_ID);
      break;

	//
   // Location and sources ...
   //
	case RegisteredClass::L4AudioLocationClassID:
      L4AudioLocation::BuildFromPage(this, name_list, class_ID, object_ID);
      break;

	case RegisteredClass::DirectPatchSourceClassID:
      DirectPatchSource::BuildFromPage(this, name_list, class_ID, object_ID);
   	break;

	case RegisteredClass::Dynamic3DPatchSourceClassID:
      Dynamic3DPatchSource::BuildFromPage(this, name_list, class_ID, object_ID);
      break;

	case RegisteredClass::Static3DPatchSourceClassID:
      Static3DPatchSource::BuildFromPage(this, name_list, class_ID, object_ID);
      break;

   //
   // Audio components ...
	//
	case RegisteredClass::AudioControlMixerClassID:
      AudioControlMixer::BuildFromPage(this, name_list, class_ID, object_ID);
      break;

	case RegisteredClass::AudioControlMultiplierClassID:
		AudioControlMultiplier::BuildFromPage(this, name_list, class_ID, object_ID);
		break;

	case RegisteredClass::AudioResourceSelectorClassID:
      AudioResourceSelector::BuildFromPage(this, name_list, class_ID, object_ID);
      break;

	case RegisteredClass::AudioControlSmootherClassID:
      AudioControlSmoother::BuildFromPage(this, name_list, class_ID, object_ID);
      break;

	case RegisteredClass::AudioSampleAndHoldClassID:
      AudioSampleAndHold::BuildFromPage(this, name_list, class_ID, object_ID);
      break;

	case RegisteredClass::AudioControlSendClassID:
		AudioControlSend::BuildFromPage(this, name_list, class_ID, object_ID);
		break;

	case RegisteredClass::AudioControlSequenceClassID:
		AudioControlSequence::BuildFromPage(this, name_list, class_ID, object_ID);
		break;

	case RegisteredClass::AudioControlSplitterClassID:
		AudioControlSplitter::BuildFromPage(this, name_list, class_ID, object_ID);
		break;

	case RegisteredClass::AudioLFOClassID:
		AudioLFO::BuildFromPage(this, name_list, class_ID, object_ID);
		break;

	//
   // Audio watchers ...
   //
	case RegisteredClass::AudioMotionTriggerClassID:
      AudioMotionTrigger::BuildFromPage(this, name_list, class_ID, object_ID);
      break;

	case RegisteredClass::AudioMotionScaleClassID:
		AudioMotionScale::BuildFromPage(this, name_list, class_ID, object_ID);
      break;

	case RegisteredClass::AudioHingeScaleClassID:
      AudioHingeScale::BuildFromPage(this, name_list, class_ID, object_ID);
		break;

	case RegisteredClass::AudioScalarTriggerClassID:
      AudioScalarTrigger::BuildFromPage(this, name_list, class_ID, object_ID);
		break;

	case RegisteredClass::AudioScalarScaleClassID:
		AudioScalarScale::BuildFromPage(this, name_list, class_ID, object_ID);
      break;

	case RegisteredClass::AudioLogicalTriggerClassID:
      AudioLogicalTrigger::BuildFromPage(this, name_list, class_ID, object_ID);
      break;

	case RegisteredClass::AudioEnumerationTriggerClassID:
		AudioEnumerationTrigger::BuildFromPage(this, name_list, class_ID, object_ID);
      break;

	case RegisteredClass::AudioIntegerTriggerClassID:
		AudioIntegerTrigger::BuildFromPage(this, name_list, class_ID, object_ID);
		break;

	case RegisteredClass::AudioControlsButtonTriggerClassID:
		AudioControlsButtonTrigger::BuildFromPage(this, name_list, class_ID, object_ID);
		break;

	case RegisteredClass::AudioStateTriggerClassID:
		AudioStateTrigger::BuildFromPage(this, name_list, class_ID, object_ID);
		break;

	case RegisteredClass::AudioIdleWatcherClassID:
		AudioIdleWatcher::BuildFromPage(this, name_list, class_ID, object_ID);
		break;

	case RegisteredClass::AudioEnumerationDeltaTriggerClassID:
		AudioEnumerationDeltaTrigger::BuildFromPage(this, name_list, class_ID, object_ID);
		break;

	case RegisteredClass::AudioScalarDeltaTriggerClassID:
		AudioScalarDeltaTrigger::BuildFromPage(this, name_list, class_ID, object_ID);
		break;

	case RegisteredClass::L4AudioCollisionTriggerClassID:
		L4AudioCollisionTrigger::BuildFromPage(this, name_list, class_ID, object_ID);
		break;

	case RegisteredClass::AudioMessageWatcherClassID:
		AudioMessageWatcher::BuildFromPage(this, name_list, class_ID, object_ID);
		break;

	case RegisteredClass::AudioControlsButtonMessageWatcherClassID:
		AudioControlsButtonMessageWatcher::BuildFromPage(this, name_list, class_ID, object_ID);
		break;

	//
   // Inherited behavior
   //
   default:
   	PlugStream::BuildFromPageImplementation(name_list, class_ID, object_ID);
      break;
   }
}

//
//#############################################################################
// BuiltFromPageImplementation
//#############################################################################
//
void
   AudioObjectStream::BuiltFromPageImplementation(
      Enumeration class_ID,
      ObjectID object_ID,
      const CString &object_name
   )
{
	Check(this);
   Verify(class_ID != RegisteredClass::NullClassID);
   Verify(object_ID != NullObjectID);
   Check(&object_name);

	//
   // Decide which index to add object to
   //
   if (object_name.Length() == 0)
		return;

   switch (class_ID)
   {
   case RegisteredClass::PatchLevelOfDetailClassID:
	case RegisteredClass::PatchResourceClassID:
	case RegisteredClass::AudioResourceIndexClassID:
   	AddGlobalObjectID(object_ID, object_name);
      break;

   default:
   	AddLocalObjectID(object_ID, object_name);
      break;
   }
}

//#############################################################################
//######################    L4AudioResourceManager    #########################
//#############################################################################

//
//#############################################################################
// L4AudioResourceManager
//#############################################################################
//
L4AudioResourceManager::L4AudioResourceManager()
{
}

//
//#############################################################################
// ~L4AudioResourceManager
//#############################################################################
//
L4AudioResourceManager::~L4AudioResourceManager()
{
}

//
//#############################################################################
// TestInstance
//#############################################################################
//
Logical
	L4AudioResourceManager::TestInstance() const
{
	Node::TestInstance();
	return True;
}

//
//#############################################################################
// PreloadResources
//#############################################################################
//
void
	L4AudioResourceManager::PreloadResources(
		NotationFile *notation_file,
		AudioHardware *audio_hardware
	)
{
	Check(this);
	Check(notation_file);
	Check(audio_hardware);

	//
	//----------------------------------------------------------------------
	// Load the sound banks
	//----------------------------------------------------------------------
	//
	NameList *name_list;
	NameList::Entry *entry;

	Verify(notation_file->EntryCount("AudioResources") >= 2);

	name_list = notation_file->MakeEntryList("AudioResources");
	Register_Object(name_list);
	entry = name_list->GetFirstEntry();
	Check(entry);
	while (entry != NULL)
	{
		Check(entry);
		if (entry->IsName("front_audio_resource"))
		{
			Check_Pointer(entry->GetChar());
			Check(audio_hardware->GetFrontCard());
			audio_hardware->GetFrontCard()->LoadSBK(entry->GetChar());
		}
		else
		{
			Verify(entry->IsName("rear_audio_resource"));
			Check_Pointer(entry->GetChar());
			Check(audio_hardware->GetRearCard());
			audio_hardware->GetRearCard()->LoadSBK(entry->GetChar());
		}
		entry = entry->GetNextEntry();
	}
	Unregister_Object(name_list);
   delete name_list;

	//
	//----------------------------------------------------------------------
	// Create static audio objects
	//----------------------------------------------------------------------
	//

	//
	// Get static audio stream resource
	//
	ResourceDescription *resource_description;

   Check(application);
   Check(application->GetResourceFile());
   resource_description =
      application->GetResourceFile()->FindResourceDescription(
         "StaticAudioStream",
         ResourceDescription::StaticAudioStreamResourceType
		);
	Check(resource_description);
	resource_description->Lock();

	//
	// Parse the audio object stream
	//
	AudioObjectStream audio_object_stream(resource_description, NULL);

	Check(&audio_object_stream);
	audio_object_stream.CreateObjects();
	resource_description->Unlock();
}

//
//#############################################################################
// UnloadResources
//#############################################################################
//
void
   L4AudioResourceManager::UnloadResources(
      AudioHardware *audio_hardware
	)
{
	Check(this);
   Check(audio_hardware);

	//
	//----------------------------------------------------------------------
	// Release banks
	//----------------------------------------------------------------------
	//
   Check(audio_hardware->GetFrontCard());
   audio_hardware->GetFrontCard()->ReleaseAllBanks();
   Check(audio_hardware->GetRearCard());
   audio_hardware->GetRearCard()->ReleaseAllBanks();
}

//
//#############################################################################
// CreateStaticAudioStreamResource
//#############################################################################
//
ResourceDescription::ResourceID
   L4AudioResourceManager::CreateStaticAudioStreamResource(
      ResourceFile *resource_file
   )
{
   Check(resource_file);

	//
	//----------------------------------------------------------------------
	// Open the notation file for the static stream resource
	//----------------------------------------------------------------------
	//
   Tell("Opening Audio Script audio\\static.scp\n");
   NotationFile notation_file("audio\\static.scp");
   Check(&notation_file);

	//
	//----------------------------------------------------------------------
	// Build the static audio object stream
	//----------------------------------------------------------------------
	//
	AudioObjectStream audio_object_stream;

   Check(&audio_object_stream);
   audio_object_stream.BuildFromNotationFile(&notation_file, resource_file);
   Tell("Closed Audio Script\n");

   //
	//----------------------------------------------------------------------
   // Add the resource
	//----------------------------------------------------------------------
   //
   ResourceDescription *res_description;

   res_description =
      resource_file->AddResourceMemoryStream(
         "StaticAudioStream",
         ResourceDescription::StaticAudioStreamResourceType,
         1,
         ResourceDescription::Preload,
         &audio_object_stream
      );
	Check(res_description);
	return res_description->resourceID;
}

//
//#############################################################################
// CreateEntityAudioObjects
//#############################################################################
//
void
	L4AudioResourceManager::CreateEntityAudioObjects(
      Entity *entity,
		AudioRepresentation audio_representation
   )
{
	Check(this);
	Check(entity);
	Verify(
		audio_representation == InternalAudioRepresentation ||
		audio_representation == ExternalAudioRepresentation
	);

	//
	//------------------------------------------------------------------------
	// Read the audio resource for this entity
	//------------------------------------------------------------------------
	//
	ResourceDescription *audio_resource_description;

	Check(application);
	Check(application->GetResourceFile());
	audio_resource_description =
		application->GetResourceFile()->SearchList(
			entity->GetResourceID(),
			ResourceDescription::AudioStreamListResourceType
		);
	if (audio_resource_description == NULL)
		return;

	//
	//------------------------------------------------------------------------
	// Read the appropriate resource for an internal or external
	// representation
	//------------------------------------------------------------------------
	//
	ResourceDescription *stream_resource_description;

	Check(application);
	Check(application->GetResourceFile());
	Check(audio_resource_description);
	stream_resource_description =
		application->GetResourceFile()->SearchList(
			audio_resource_description->resourceID,
			(audio_representation == InternalAudioRepresentation) ?
				ResourceDescription::InternalAudioStreamResourceType :
				ResourceDescription::ExternalAudioStreamResourceType
		);
	if (stream_resource_description == NULL)
		return;
	Check(stream_resource_description);
	stream_resource_description->Lock();
	audio_resource_description->Lock();

	//
	//------------------------------------------------------------------------
	// Make the audio object stream
	//------------------------------------------------------------------------
	//
	AudioObjectStream
		audio_object_stream(
			stream_resource_description,
			entity
		);

	Check(&audio_object_stream);
	audio_object_stream.CreateObjects();
	stream_resource_description->Unlock();
	audio_resource_description->Unlock();
}

//
//#############################################################################
// DestroyEntityAudioObjects
//#############################################################################
//
void
	L4AudioResourceManager::DestroyEntityAudioObjects(Entity *entity)
{
	Check(this);
	Check(entity);

	//
	//--------------------------------------------------------------------------
	// Stop and delete all audio objects
	//--------------------------------------------------------------------------
	//
	Entity::AudioSocketIterator 
		iterator(entity);
	Component 
		*component;
	AudioComponent 
		*audio_component;

	Check(&iterator);
	while ((component = iterator.ReadAndNext()) != NULL)
	{
		audio_component = Cast_Object(AudioComponent*, component);
		Check(audio_component);
		audio_component->ReceiveControl(StopAudioControlID, 0.0f);
		audio_component->ReceiveControl(FlushMessagesAudioControlID, 0.0f);
	}
	iterator.DeletePlugs();
}

//
//#############################################################################
// CreateModelAudioResource
//#############################################################################
//
ResourceDescription::ResourceID
	L4AudioResourceManager::CreateModelAudioStreamResource(
		ResourceFile *resource_file,
		const char *model_name,
		NotationFile *model_file,
		const ResourceDirectories*
	)
{
	Check(resource_file);
	Check_Pointer(model_name);
	Check(model_file);

	const char *script_name = NULL;
	ResourceDescription::ResourceID resource_id_list[3];
	size_t list_length = 0;

	resource_id_list[0] = ResourceDescription::NullResourceID;
	resource_id_list[1] = ResourceDescription::NullResourceID;
	resource_id_list[2] = ResourceDescription::NullResourceID;

	//
	//--------------------------------------------------------------------------
	// Check for the external audio script
	//--------------------------------------------------------------------------
	//
	if (model_file->GetEntry("audio", "external", &script_name))
	{
		//
		// See if the resource already exists
		//
		ResourceDescription *res_description =
			resource_file->FindResourceDescription(
				script_name,
				ResourceDescription::ExternalAudioStreamResourceType
			);

		//
		//-----------------------------------------------------------------------
		// If not, create it
		//-----------------------------------------------------------------------
		//
		if (res_description == NULL)
		{
			//
			// Make the file name
			//
			CString file_name(script_name);
			CString prefix("audio\\");

         file_name = prefix + file_name;

         //
			// Build the memory stream
			//
			Tell("Opening Audio Script " << file_name << "\n");
         NotationFile script_file(file_name);
			AudioObjectStream audio_object_stream;

			Check(&script_file);
         Check(&audio_object_stream);
			audio_object_stream.BuildFromNotationFile(&script_file, resource_file);
			Tell("Closed Audio Script\n");

			//
			// Add the resource
         //
			res_description =
            resource_file->AddResourceMemoryStream(
					script_name,
               ResourceDescription::ExternalAudioStreamResourceType,
					1,
               ResourceDescription::Preload,
					&audio_object_stream
            );
		}
      Check(res_description);
		resource_id_list[list_length++] = res_description->resourceID;
	}

	//
	//--------------------------------------------------------------------------
	// Check for the internal audio script
	//--------------------------------------------------------------------------
	//
	if (model_file->GetEntry("audio", "internal", &script_name))
   {
		//
      // See if the resource already exists
		//
      ResourceDescription *res_description =
			resource_file->FindResourceDescription(
            script_name,
				ResourceDescription::InternalAudioStreamResourceType
			);

		//
		// If not, create it
      //
		if (res_description == NULL)
      {
			//
			// Make the file name
			//
      	CString file_name(script_name);
			CString prefix("audio\\");

			file_name = prefix + file_name;

			//
         // Build the memory stream
			//
		   Tell("Opening Audio Script " << file_name << "\n");
			NotationFile script_file(file_name);
         AudioObjectStream audio_object_stream;

			Check(&script_file);
			Check(&audio_object_stream);
         audio_object_stream.BuildFromNotationFile(&script_file, resource_file);
			Tell("Closed Audio Script\n");

			//
			// Add the resource
			//
         res_description =
				resource_file->AddResourceMemoryStream(
               script_name,
					ResourceDescription::InternalAudioStreamResourceType,
					1,
					ResourceDescription::Preload,
               &audio_object_stream
				);
      }
		Check(res_description);
		resource_id_list[list_length++] = res_description->resourceID;
	}

	//
	//--------------------------------------------------------------------------
	// Check for the audio entity model
	//--------------------------------------------------------------------------
	//
	const char *audio_entity_model = NULL;

	if (model_file->GetEntry("audio", "model", &audio_entity_model))
	{
		//
		// The resource should already exist
		//
		ResourceDescription *res_description =
			resource_file->FindResourceDescription(
				audio_entity_model,
				ResourceDescription::ModelListResourceType
			);
		if (res_description == NULL)
		{
			cout << "audio_entity_model == " << audio_entity_model;
			Fail("L4AudioResourceManager::CreateModelAudioStreamResource - model not found");
		}
		Check(res_description);
		resource_id_list[list_length++] = res_description->resourceID;
	}

	//
	//--------------------------------------------------------------------------
	// If either script has been created, then create the resource list
	//--------------------------------------------------------------------------
	//
	if (list_length > 0)
	{
		ResourceDescription *res_description =
			resource_file->AddResourceList(
				model_name,
				ResourceDescription::AudioStreamListResourceType,
				1,
				ResourceDescription::Preload,
				resource_id_list,
				list_length
			);
		Check(res_description);
		return res_description->resourceID;
	}
	return ResourceDescription::NullResourceID;
}

