#include"CSoundBufferStaticDS8.h"

#include"../../../../Template/Mathematics.h"


namespace Maid
{
void CSoundBufferStaticDS8::Setup( const SPDSBUFFER& p )
{
	m_pBuffer = p;
	m_IsLoop = false;

	{
		DWORD size;

		m_pBuffer->GetFormat( NULL, NULL, &size );
		m_FormatData.resize( size );

		m_pBuffer->GetFormat( (WAVEFORMATEX*)&(m_FormatData[0]), size, NULL );
	}

}

SPDSBUFFER CSoundBufferStaticDS8::GetBuffer() const
{
	return m_pBuffer;
}


void	CSoundBufferStaticDS8::Play()
{
	DWORD flag = 0;

	if( m_IsLoop ) { flag |= DSBPLAY_LOOPING; }

	const HRESULT ret = m_pBuffer->Play( 0, 0, flag );
	if( FAILED(ret) ) { MAID_THROWEXCEPTION( MAIDTEXT("IDirectSoundBuffer::Play()") ); }
}

void	CSoundBufferStaticDS8::Stop()
{
	const HRESULT ret = m_pBuffer->Stop();
	if( FAILED(ret) ) { MAID_THROWEXCEPTION( MAIDTEXT("IDirectSoundBuffer::Stop()") ); }
}

unt		CSoundBufferStaticDS8::GetBytePosition () const
{
	DWORD pos = 0;
	const HRESULT ret = m_pBuffer->GetCurrentPosition(&pos,NULL);
	if( FAILED(ret) ) { MAID_THROWEXCEPTION( MAIDTEXT("IDirectSoundBuffer::GetCurrentPosition()") ); }

	return (unt)pos;
}

void	CSoundBufferStaticDS8::SetBytePosition ( unt pos )
{
	const HRESULT ret = m_pBuffer->SetCurrentPosition( pos );
	if( FAILED(ret) ) { MAID_THROWEXCEPTION( MAIDTEXT("IDirectSoundBuffer::SetCurrentPosition()") ); }
}

void	CSoundBufferStaticDS8::SetVolume( int vol )
{
	if( vol==0 )
	{
		const HRESULT ret = m_pBuffer->SetVolume( DSBVOLUME_MIN );
		if( FAILED(ret) ) { MAID_THROWEXCEPTION( MAIDTEXT("IDirectSoundBuffer::SetVolume(DSBVOLUME_MIN)") ); }
	}else
	{
		const float p = float(vol)/10000.0f;
		const int   v = (int)( 20.0f * Math<float>::log10(p) * 100.0f );
		const HRESULT ret = m_pBuffer->SetVolume( max(DSBVOLUME_MIN,v) );
		if( FAILED(ret) ) { MAID_THROWEXCEPTION( MAIDTEXT("IDirectSoundBuffer::SetVolume()") ); }
	}
}

int		CSoundBufferStaticDS8::GetVolume() const
{
	LONG vol;
	const HRESULT ret = m_pBuffer->GetVolume( &vol );
	if( FAILED(ret) ) { MAID_THROWEXCEPTION( MAIDTEXT("IDirectSoundBuffer::GetVolume()") ); }
	if( vol==DSBVOLUME_MIN ) { return VOLUME_MIN; }
	
	return int(Math<float>::pow(10.0f,float(vol)/100.0f/20.0f)*10000.0f);

}

bool	CSoundBufferStaticDS8::IsPlay() const
{
	DWORD dw;
	const HRESULT ret = m_pBuffer->GetStatus( &dw );
	if( FAILED(ret) ) { MAID_THROWEXCEPTION( MAIDTEXT("IDirectSoundBuffer::GetStatus()") ); }

	return IsFlag( dw, DSBSTATUS_PLAYING );
}

void	CSoundBufferStaticDS8::SetLoopState( bool IsLoop )
{
	m_IsLoop = IsLoop;

	if( IsLoop && IsPlay() )
	{	//	再生中だったらフラグを再設定しておく
		const HRESULT ret = m_pBuffer->Play( 0, 0, DSBPLAY_LOOPING );
		if( FAILED(ret) ) { MAID_THROWEXCEPTION( MAIDTEXT("IDirectSoundBuffer::Play()") ); }
	}
}

int	CSoundBufferStaticDS8::GetSamplePerSec()const
{
	return GetFormat()->nSamplesPerSec;
}

int	CSoundBufferStaticDS8::GetBitPerSample()const
{
	return GetFormat()->wBitsPerSample;
}

int	CSoundBufferStaticDS8::GetChannel()const
{
	return GetFormat()->nChannels;
}

int	CSoundBufferStaticDS8::GetCurrentSample() const
{
	//	めんどいので未実装(ﾟ∀ﾟ)
	return 0;
}


void	CSoundBufferStaticDS8::Update( unt time )
{
	//	特になし
}

const WAVEFORMATEX* CSoundBufferStaticDS8::GetFormat()const
{
	return (const WAVEFORMATEX*)&(m_FormatData[0]);
}

}
