#include "SkOSSound.h"

#ifdef SK_BUILD_FOR_WIN

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

#include <Mmreg.h>
#if defined _WIN32 && _MSC_VER >= 1300	// disable nameless struct/union
#pragma warning ( push )
#pragma warning ( disable : 4201 )
#endif
#include <Mmsystem.h>
#if defined _WIN32 && _MSC_VER >= 1300	
#pragma warning ( pop )
#endif
#include <stdio.h>

class CWaveFile {
public:
	BOOL Open(const char path[]);
	void Close();

	long Read(char* pData, long nLength);

	long GetLength() const {return m_nLength;}
	WAVEFORMATEX* GetWaveFormat()	{return (&m_Format);}

protected:
	FILE* m_pFile;
	long m_nLength;
	WAVEFORMATEX m_Format;

private:
	enum {
		WF_OFFSET_FORMATTAG	=		20,
		WF_OFFSET_CHANNELS =			22,
		WF_OFFSET_SAMPLESPERSEC =		24,
		WF_OFFSET_AVGBYTESPERSEC =	28,
		WF_OFFSET_BLOCKALIGN =		32,
		WF_OFFSET_BITSPERSAMPLE =		34,
		WF_OFFSET_DATASIZE =			40,
		WF_OFFSET_DATA =				44,
		WF_HEADER_SIZE = WF_OFFSET_DATA
	};
};

BOOL CWaveFile::Open(const char path[])
{
	BYTE aHeader[WF_HEADER_SIZE];

/*	hResInfo = FindResource (hInst, lpName, "WAVE"); 

	if (hResInfo == NULL) 
	return FALSE; 

	// Load the wave resource. 
	hRes = LoadResource (hInst, hResInfo); 

	if (hRes == NULL) 
		return FALSE; 

	// Lock the wave resource and play it. 
	lpRes = LockResource (0);
*/


	// open file
//	m_pFile = _tfopen(szFileName, TEXT("rb"));
	m_pFile = fopen(path, "rb");
	if (!m_pFile) {
		return FALSE;
	}

	// set file length
	fseek(m_pFile, 0, SEEK_END);
	m_nLength = ftell(m_pFile) - WF_HEADER_SIZE;

	// set the format attribute members
	fseek(m_pFile, 0, SEEK_SET);
	fread(aHeader, 1, WF_HEADER_SIZE, m_pFile);
	m_Format.wFormatTag = *((WORD*) (aHeader + WF_OFFSET_FORMATTAG));
	m_Format.nChannels = *((WORD*) (aHeader + WF_OFFSET_CHANNELS));
	m_Format.nSamplesPerSec = *((DWORD*) (aHeader + WF_OFFSET_SAMPLESPERSEC));
	m_Format.nAvgBytesPerSec = *((DWORD*) (aHeader + WF_OFFSET_AVGBYTESPERSEC));
	m_Format.nBlockAlign = *((WORD*) (aHeader + WF_OFFSET_BLOCKALIGN));
	m_Format.wBitsPerSample = *((WORD*) (aHeader + WF_OFFSET_BITSPERSAMPLE));

	return TRUE;
}

void CWaveFile::Close()
{
	fclose(m_pFile);
}

long CWaveFile::Read(char* pData, long nLength)
{
	return fread(pData, 1, nLength, m_pFile);
}

////////////////////////////////////////////////////////////////////////////////////////

struct SkOSSoundWave {
	HWAVEOUT hwo;
	WAVEHDR whdr;
	DWORD dwOldVolume;
	CWaveFile waveFile;
	HANDLE hDoneEvent;
};

static SkOSSoundWave gWave;
static bool			 gWavePaused;
static U8			 gVolume;
static bool			 gInited = false;

static void init_wave()
{
	if (gInited == false)
	{
		gWave.hwo = nil;
		gWavePaused = false;
		gVolume = 0x80;
		gInited = true;
	}
}

MMRESULT StartWave(const char path[], SkOSSoundWave* wave, U32 vol);
MMRESULT EndWave(SkOSSoundWave* wave);

#define MAX_ERRMSG 256

//#include "SkOSFile.h"	// for utf16

void SkOSSound::Play(const char path[]) 
{
	init_wave();

	if (gWave.hwo != nil)
		SkOSSound::Stop();

	U32 v32 = (gVolume << 8) | gVolume;	// fill it out to 16bits
	v32 |= v32 << 16;					// set the left and right channels

	StartWave(path, &gWave, v32);
	gWavePaused = false;
}

bool SkOSSound::TogglePause() 
{
	init_wave();

	if (gWavePaused) 
		SkOSSound::Resume();
	else 
		SkOSSound::Pause(); 
	return !gWavePaused;
}


void SkOSSound::Pause() 
{
	init_wave();

	if (gWave.hwo == nil || (gWave.whdr.dwFlags & WHDR_DONE))
		return;
	waveOutPause(gWave.hwo);
	gWavePaused = true;
}

void SkOSSound::Resume() 
{
	init_wave();

	if (gWave.hwo == nil || (gWave.whdr.dwFlags & WHDR_DONE))
		return;
	waveOutRestart(gWave.hwo);
	gWavePaused = false;
}

void SkOSSound::Stop() 
{
	init_wave();

//	if (gWave.hwo == nil || (gWave.whdr.dwFlags & WHDR_DONE))
	if (gWave.hwo == nil)
		return;
	waveOutReset(gWave.hwo);
	EndWave(&gWave);
	gWavePaused = false;
	gWave.hwo = nil;
}

U8 SkOSSound::GetVolume()
{
	init_wave();
	return gVolume;
}

void SkOSSound::SetVolume(U8CPU vol)
{
	if ((int)vol < 0)
		vol = 0;
	else if (vol > 255)
		vol = 255;

	init_wave();
	gVolume = SkToU8(vol);

	if (gWave.hwo)
	{
		unsigned long v32 = (vol << 8) | vol;	// fill it out to 16bits
		v32 |= v32 << 16;						// set the left and right channels
		waveOutSetVolume(gWave.hwo, v32);
	}
}

#if 0
unsigned long SoundManager::GetPosition()
{
	if (fWave.hwo == nil)
		return 0;
	MMTIME time;
	time.wType = TIME_MS;
	if (waveOutGetPosition(fWave.hwo, &time, sizeof(time)) == MMSYSERR_NOERROR &&
		time.wType == TIME_MS)
	{
		return time.u.ms;
	}
	return 0;
}
#endif

MMRESULT StartWave(const char path[], SkOSSoundWave* wave, U32 vol)
{
	HWAVEOUT hwo = nil;
//	WAVEHDR whdr;
	MMRESULT mmres = 0;
//	CWaveFile waveFile;
//	HANDLE hDoneEvent = wave.hDoneEvent = 
//		CreateEvent(NULL, FALSE, FALSE, TEXT("DONE_EVENT"));
	UINT devId;
//	DWORD dwOldVolume;

	// Open wave file
	if (!wave->waveFile.Open(path)) {
//		TCHAR szErrMsg[MAX_ERRMSG];
//		_stprintf(szErrMsg,	TEXT("Unable to open file: %s\n"), szWavFile);
//		MessageBox(NULL, szErrMsg, TEXT("File I/O Error"), MB_OK);
		return MMSYSERR_NOERROR;
	}

	// Open audio device
	for (devId = 0; devId < waveOutGetNumDevs(); devId++)
	{
		mmres = waveOutOpen(&hwo, devId, wave->waveFile.GetWaveFormat(), 0, 0, CALLBACK_NULL);
		if (mmres == MMSYSERR_NOERROR)
		{
			wave->hwo = hwo;
			break;
		}
	}
	if (mmres != MMSYSERR_NOERROR)
	{
		SkDEBUGCODE(SkDebugf("waveOutOpen(%s) -> %d\n", path, mmres);) 
		return mmres;
	}

	// Set volume
	mmres = waveOutGetVolume(hwo, &wave->dwOldVolume);
	if (mmres != MMSYSERR_NOERROR) {
		return mmres;
	}

	waveOutSetVolume(hwo, vol);
	if (mmres != MMSYSERR_NOERROR) {
		return mmres;
	}

	// Initialize wave header
	ZeroMemory(&wave->whdr, sizeof(WAVEHDR));
	wave->whdr.lpData = new char[wave->waveFile.GetLength()];
	wave->whdr.dwBufferLength = wave->waveFile.GetLength();
	wave->whdr.dwUser = 0;
	wave->whdr.dwFlags = 0;
	wave->whdr.dwLoops = 0;
	wave->whdr.dwBytesRecorded = 0;
	wave->whdr.lpNext = 0;
	wave->whdr.reserved = 0;

	// Play buffer
	wave->waveFile.Read(wave->whdr.lpData, wave->whdr.dwBufferLength);

	mmres = waveOutPrepareHeader(hwo, &wave->whdr, sizeof(WAVEHDR));	
	if (mmres != MMSYSERR_NOERROR) {
		return mmres;
	}

	mmres = waveOutWrite(hwo, &wave->whdr, sizeof(WAVEHDR));	
//	if (mmres != MMSYSERR_NOERROR) {
		return mmres;
//	}
}

#if 0
void IdleWave(Wave& wave)
{
	// Wait for audio to finish playing
	while (!(wave.whdr.dwFlags & WHDR_DONE)) {
		WaitForSingleObject(wave.hDoneEvent, INFINITE);
	}
}
#endif

MMRESULT EndWave(SkOSSoundWave* wave)
{
	HWAVEOUT hwo = wave->hwo;
	MMRESULT mmres;
	// Clean up
	mmres = waveOutUnprepareHeader(hwo, &wave->whdr, sizeof(WAVEHDR));	
	if (mmres != MMSYSERR_NOERROR) {
		return mmres;
	}

	waveOutSetVolume(hwo, wave->dwOldVolume);
	if (mmres != MMSYSERR_NOERROR) {
		return mmres;
	}

	mmres = waveOutClose(hwo);
	if (mmres != MMSYSERR_NOERROR) {
		return mmres;
	}

	delete [] wave->whdr.lpData;
	wave->waveFile.Close();

	return MMSYSERR_NOERROR;
}

#endif	/* SK_BUILD_FOR_WIN */

