//===========================================================================//
// 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"

namespace Adept {

	class AudioChannel;
	class AudioSample;

	//##########################################################################
	//############################    AudioCommand    ##########################
	//##########################################################################

	class AudioCommand:
		public Stuff::Plug
	{
		friend class AudioRenderer;
		friend class AudioChannel;

	public:
		typedef Stuff::Plug BaseClass;

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

		static ClassData *DefaultData;

		void TestInstance() const;

		void Play(gosAudio_PlayMode mode=gosAudio_PlayOnce);
		void Stop();

		static AudioCommand *Create(
			int type,
			const ResourceID &hint_ID,
			Stuff::Scalar priority,
			Stuff::Scalar volume,
			Stuff::Scalar min_restart = 0.5f,
			Stuff::Scalar min_replace = 0.8f
		);
		static AudioCommand *Create(
			int type,
			const char* name,
			Stuff::Scalar priority,
			Stuff::Scalar volume,
			Stuff::Scalar min_restart = 0.5f,
			Stuff::Scalar min_replace = 0.8f
		);

		gosAudio_PlayMode GetPlayMode()
			{Check_Object(this); return m_playMode;}

		void SetChannel(AudioChannel *channel)
			{Check_Object(this); Check_Object(channel); m_channel = channel;}

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

		virtual Stuff::Scalar ComputeEnergy(AudioChannel *channel);

		Stuff::Scalar m_priority, m_volume, m_energy;
		Stuff::Scalar m_minRestartDelay, m_minReplaceDelay;

	protected:
		AudioCommand(
			ClassData *class_data,
			int type,
			const ResourceID &hint_ID,
			Stuff::Scalar priority,
			Stuff::Scalar volume,
			Stuff::Scalar min_restart,
			Stuff::Scalar min_replace
		);
		~AudioCommand();

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

		ResourceID m_handleResourceID;
		int m_type;
		AudioChannel* m_channel;
		gosAudio_PlayMode m_playMode;

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