#include "mof/sound/StaticSoundBuffer.hpp"
#include "mof/sound/DirectSoundDevice.hpp"
#include "mof/ConsoleIO.hpp"
#include <cassert>

mof::StaticSoundBuffer::StaticSoundBuffer
(
	std::shared_ptr<mof::sound::DirectSoundDevice> pDevice,
	LPDIRECTSOUNDBUFFER8 pBuffer,
	SoundFile* pResource
)
: mof::SoundBuffer(pDevice, pBuffer , pResource)
{
}

mof::StaticSoundBuffer::~StaticSoundBuffer(void)
{
	
}


bool mof::StaticSoundBuffer::initialize(){
	LPVOID pMem1 , pMem2;
	DWORD dwSize1 , dwSize2;
	HRESULT hr = getSoundBuffer()->Lock(0 , getResource()->getSize() , &pMem1 , &dwSize1 , &pMem2 , &dwSize2 , 0);
	if(FAILED(hr)){
		*ConsoleOut::getInstance() << _T("Failed --- LockSoundBuffer") << std::endl;
		return false;
	}

	getResource()->resetFile();
	getResource()->read((BYTE*)pMem1 , dwSize1 , (BYTE*)pMem2 , dwSize2);
	getSoundBuffer()->Unlock(pMem1 , dwSize1 , pMem2 , dwSize2);
	return true;
}


bool mof::StaticSoundBuffer::play(bool looping){
	getSoundBuffer()->SetCurrentPosition(0);
	HRESULT hr = getSoundBuffer()->Play( 0 , 0 , (looping)?DSBPLAY_LOOPING : 0);
	if(hr == DSERR_BUFFERLOST){
		*ConsoleOut::getInstance() << _T("Failed --- PlaySound") << std::endl;
		return false;
	}
	return true;
}

void mof::StaticSoundBuffer::pause(){
	// TODO Pause
	getSoundBuffer()->Stop();
}

void mof::StaticSoundBuffer::stop(){
	getSoundBuffer()->Stop();
}

std::unique_ptr<mof::StaticSoundBuffer> mof::StaticSoundBuffer::duplicate()
{
	auto buffer = getSoundBuffer();
	LPDIRECTSOUNDBUFFER tmp_buffer;
	if (FAILED(pDevice_->raw()->DuplicateSoundBuffer(buffer, &tmp_buffer))) {
		throw std::runtime_error("Failed duplicate sound");
	}
	LPDIRECTSOUNDBUFFER8 new_buffer;
	if (FAILED(tmp_buffer->QueryInterface(IID_IDirectSoundBuffer8 , (LPVOID*)&new_buffer))) {
		tmp_buffer->Release();
		throw std::runtime_error("Failed query IDirectSoundBuffer8");
	}
	tmp_buffer->Release();
	
	auto p = new mof::StaticSoundBuffer(pDevice_, new_buffer, NULL);
	// initializeは呼び出さない
	// TODO duplicated_souond_buffer
	return std::unique_ptr<mof::StaticSoundBuffer>(p);
}
