//===========================================================================//
// File:	audiorenderer.hpp                                                //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 03/22/99  SMJ  Initial coding.                                            //
//---------------------------------------------------------------------------//
// Copyright (C) 1999, Microsoft Corporation		                         //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#pragma once

#include "Adept.hpp"
#include "AudioCommand.hpp"

namespace Adept {

	//##########################################################################
	//#########################    SpatializedCommand    #######################
	//##########################################################################

	class SpatializedCommand:
		public AudioCommand
	{
		friend class SpatializedChannel;

	public:
		typedef AudioCommand BaseClass;

		static void InitializeClass(size_t block_count = 20, size_t block_delta = 10);
		static void TerminateClass();

		static ClassData *DefaultData;

		void TestInstance() const;

		static SpatializedCommand *Create(
			int type,
			const ResourceID &hint_ID,
			Stuff::Scalar priority,
			Stuff::Scalar volume,
			Stuff::Scalar min_restart,
			Stuff::Scalar min_replace,
			const Point3D &position,
			const Vector3D &velocity,
			Stuff::Scalar min_deviation,
			Stuff::Scalar near_clip,
			Stuff::Scalar min_range,
			Stuff::Scalar max_range,
			Stuff::Scalar far_clip
		);

		void SetPosition(const Stuff::Point3D &position);
		void SetVelocity(const Stuff::Vector3D &velocity);
		const Stuff::Point3D& GetPosition()
			{Check_Object(this); return m_position;}
		const Stuff::Vector3D& GetVelocity()
			{Check_Object(this); return m_velocity;}

		bool ConnectToChannel(AudioSample* sample);
		bool AddLoop();

		Stuff::Scalar ComputeEnergy(AudioChannel *channel);

	protected:
		SpatializedCommand(
			ClassData *class_data,
			int type,
			const ResourceID &hint_ID,
			Stuff::Scalar priority,
			Stuff::Scalar volume,
			Stuff::Scalar min_restart,
			Stuff::Scalar min_replace,
			const Point3D &position,
			const Vector3D &velocity,
			Stuff::Scalar min_deviation,
			Stuff::Scalar near_clip,
			Stuff::Scalar min_range,
			Stuff::Scalar max_range,
			Stuff::Scalar far_clip
		);
		~SpatializedCommand();

		void*
			operator new(size_t size)
				{Verify(size == sizeof(SpatializedCommand)); return s_AllocatedMemory->New();}
		void
			operator delete(void *where)
				{s_AllocatedMemory->Delete(where);}

		Stuff::Scalar
			m_minDeviation,
			m_nearClip,
			m_minRange,
			m_maxRange,
			m_farClip;
		Stuff::Point3D m_position;
		Stuff::Vector3D m_velocity;
		Stuff::YawPitchRange m_bearing;

	private:
		static Stuff::MemoryBlock *s_AllocatedMemory;
	};
}
