#include"CSoundCore.h"
#include"../../Auxiliary/Debug/CAssert.h"


namespace Maid
{
CSoundCore*	GlobalPointer<CSoundCore>::s_pPointer;

CSoundCore::CSoundCore()
{
	GlobalPointer<CSoundCore>::Set();
}

CSoundCore::~CSoundCore()
{
	Finalize();
	GlobalPointer<CSoundCore>::Clear();
}


void CSoundCore::Initialize( const SPSOUNDCARDDRIVER& pDriver, const SPTIMER& pTimer, const ISoundCardDriver::PCMBUFFERFORMAT& Format  )
{
	m_SoundInfo.resize(100);	//	こんだけあれば十分？
	for( int i=0; i<(int)m_SoundInfo.size(); ++i )
	{
		SOUNDINFO& core = m_SoundInfo[i];
		core.State = SOUNDINFO::STATE_EMPTY;
	}

	m_pDriver = pDriver;
	m_pTimer  = pTimer;
	m_Format  = Format;


	m_Thread.SetFunc( MakeThreadObject(&CSoundCore::ThreadFunction,this) );
	m_Thread.Execute();
}

void CSoundCore::Finalize()
{
	m_Thread.Close();
}


const CSoundCore::BUFFERSTATUS* CSoundCore::CreateBufferStatus()
{
	CThreadMutexLocker Lock(m_SoundInfoMutex);

	for( int i=0; i<(int)m_SoundInfo.size(); ++i )
	{
		SOUNDINFO& info = m_SoundInfo[i];

		if( info.State!=SOUNDINFO::STATE_EMPTY ) { continue; }

		info.State = SOUNDINFO::STATE_STOP;
		info.BeginTime = 0;
		info.EndTime = 0;
		info.BeginVolume = 0;
		info.EndVolume = 0;
		info.IsVolumeChanging = false;

		info.Status.ID = i;
		info.Status.PlayCount = 0;
		info.Status.Position = 0;
		info.Status.IsPlay = false;
		info.Status.db = 0;

		return &info.Status;
	}

	MAID_ASSERT( true, "空き領域が足りません" );
	return NULL;
}

void CSoundCore::PostMessage( const SPSOUNDMESSAGE& pMessage )
{
	{
		CThreadMutexLocker Lock(m_MessageMutex);
		m_MessageQue.push_back( pMessage );
	}
}

void CSoundCore::SendDeviceCaps()
{
	SoundMessage::Base* p( new SoundMessage::Base(SoundMessage::Base::GETSOUNDINFO) );
	p->ID = 0;

	PostMessage( SPSOUNDMESSAGE(p) );
}

mstring CSoundCore::GetDeviceCaps()
{
	CThreadMutexLocker Lock(m_SoundInfoMutex);
	return m_CapsText;
}


}


