//===========================================================================//
// File:	AudioFXComponent_Tool.cpp				                             //
// Project: MUNGA           Brick: Win95 Video Renderer 	                 //
// Contents: Windows95 Layer Video Renderer									 //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 03/24/99  SMJ  Initial coding.                                            //
//---------------------------------------------------------------------------//
// Copyright (C) 1997, Virtual World Entertainment, Inc.                     //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#include "AdeptHeaders.hpp"

#include "AudioFXComponent.hpp"
#include "EntityClassData.hpp"

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
AudioFXComponent::ClassData*
	AudioFXComponent::CreateFactoryRequest(
		FactoryRequestParameters *parameters,
		Entity::ClassData *class_data
	)
{
	Check_Object(parameters);

	//
	//-------------------------------------------------------------------------
	// Allocate enough room for what we need to write out, then call our parent
	//-------------------------------------------------------------------------
	//
	MemoryStream *component_stream = parameters->m_stream;
	Check_Object(component_stream);
	component_stream->AllocateBytes(sizeof(AudioFXComponent));
	bool result = BaseClass::CreateFactoryRequest(parameters) != NULL;

	//
	//-----------------------
	// Read the viewing state
	//-----------------------
	//
	Page *page = parameters->m_page;
	Check_Object(page);

	//
	//-------------------------------
	// Find the type of audio to play
	//-------------------------------
	//
	const char* type_name = "General";
	page->GetEntry("ChannelType", &type_name);
	int type = AudioRenderer::FindChannelType(type_name);
	if (type<0)
	{
		PAUSE((
			"%s: {[%s]ChannelType=%s}: not a legal channel type",
			page->GetNotationFile()->GetFileName(),
			page->GetName(),
			type_name
		));
		result = false;
	}
	*component_stream << type;

	//
	//-------------------
	// Find the wave file
	//-------------------
	//
	const char* wav_file;
	page->GetEntry("Sample", &wav_file, true);
	MString handle_file(wav_file);
	handle_file += "{handle}";
	Resource hint(handle_file, true);
	if (!hint.DoesResourceExist())
	{
		PAUSE((
			"%s: {[%s]Sample=%s}: wave file isn't in an accessible .sounds file",
			page->GetNotationFile()->GetFileName(),
			page->GetName(),
			wav_file
		));
		result = false;
		*component_stream << ResourceID::Null;
	}
	else
		*component_stream << hint.GetResourceID();

	//
	//------------------------
	// Find the low-end sample
	//------------------------
	//
	page->GetEntry("LowEndSample", &wav_file);
	handle_file = wav_file;
	handle_file += "{handle}";
	Resource low_hint(handle_file, true);
	if (!low_hint.DoesResourceExist())
	{
		PAUSE((
			"%s: {[%s]LowEndSample=%s}: wave file isn't in an accessible .sounds file",
			page->GetNotationFile()->GetFileName(),
			page->GetName(),
			wav_file
		));
		result = false;
		*component_stream << ResourceID::Null;
	}
	else
		*component_stream << low_hint.GetResourceID();

	//
	//------------------------------------------
	// Make sure the wave file is enabled for 3D
	//------------------------------------------
	//
	ResourceID sample_id;
	int gos_type;
	bool cached, is3d;
	hint >> sample_id >> gos_type >> cached >> is3d;
	if (!is3d)
	{
		PAUSE((
			"%s: {[%s]Sample=%s}: .wav is not enabled for 3D",
			page->GetNotationFile()->GetFileName(),
			page->GetName(),
			wav_file
		));
		result = false;
	}

	//
	//-------------------------
	// Audio command properties
	//-------------------------
	//
	bool loop=false;
	page->GetEntry("Loop", &loop);
	int play_mode = (loop) ? gosAudio_Loop : gosAudio_PlayOnce;
	*component_stream << play_mode;

	Scalar pri = 1.0f;
	page->GetEntry("Priority", &pri);
	*component_stream << pri;

	Scalar volume = 1.0f;
	page->GetEntry("Volume", &volume);
	*component_stream << volume;

	Scalar delay=0.5f;
	page->GetEntry("MinRestartDelay", &delay);
	*component_stream << delay;

	delay = 0.8f;
	page->GetEntry("MaxReplaceDelay", &delay);
	*component_stream << delay;

	//
	//---------------------------
	// Spatial command properties
	//---------------------------
	//
	Scalar bearing = 30.0f;
	page->GetEntry("BearingDelta", &bearing);
	bearing *= Stuff::Radians_Per_Degree;
	*component_stream << bearing;

	Scalar minRange = 10.0f;
	page->GetEntry("MinRange", &minRange);
	Scalar near_clip = 0.0f;
	page->GetEntry("NearClip", &near_clip);
	Scalar maxRange = 100.0f;
	page->GetEntry("MaxRange", &maxRange);
	Scalar far_clip = maxRange;
	page->GetEntry("FarClip", &far_clip);

	*component_stream << near_clip << minRange << maxRange << far_clip;

	//
	//---------------------------------
	// Now read the component variables
	//---------------------------------
	//
	int attribute_id = -1;
	const char* attribute_name;
	result = true;
	if (page->GetEntry("Status", &attribute_name))
	{
		Check_Object(class_data);
		const AttributeEntry *attribute_entry =
			class_data->attributeTable.GetAttributeEntry(attribute_name);
		if (attribute_entry == NULL)
		{
			PAUSE((
				"%s: {[%s]Status=%s}: Unknown attribute!",
				page->GetNotationFile()->GetFileName(),
				page->GetName(),
				attribute_name
			));
			result = false;
		}
		else
		{
			Check_Object(attribute_entry);
			if (attribute_entry->attributeType != IntClassID)
			{
				PAUSE((
					"%s: {[%s]Status=%s}: Attribute is not correct type!",
					page->GetNotationFile()->GetFileName(),
					page->GetName(),
					attribute_name
				));
				result = false;
			}
			else
				attribute_id = attribute_entry->attributeID;
		}
	}
	*component_stream << attribute_id;

	bool does_start_running = false;
	page->GetEntry("StartsRunning", &does_start_running);
	*component_stream << does_start_running;

	Scalar frame_rate = 8.0f;
	page->GetEntry("FrameRate", &frame_rate);
	if (frame_rate > SMALL)
		frame_rate = 1.0f/frame_rate;
	else
		frame_rate = 0.0f;
	*component_stream << frame_rate;

	Check_Object(DefaultData);
	return (result) ? DefaultData : NULL;
}
