//////////////////////////////////////////////////////////////////////////////
// Playw32.cpp
//
// Win32 Interface to Virtual MPEG Device
//
// 09/11/1999	fOSSiL		Initial version
//

#include <windows.h>
#include "..\vxd\vmp3d.h"
#include "playw32.h"

HANDLE hDev = INVALID_HANDLE_VALUE;
DWORD LastMpegError = 0;

BOOL MpegOpenDevice()
{
	if (hDev != INVALID_HANDLE_VALUE)
		return TRUE;

	hDev = CreateFile("\\\\.\\vmp3d.vxd", 0, 0, NULL, 0, FILE_FLAG_DELETE_ON_CLOSE, NULL);
	if (hDev == INVALID_HANDLE_VALUE) {
		LastMpegError = GetLastError();
		return FALSE;
	}
	return TRUE;
}

BOOL MpegSetPlayList(MP3PLAYLIST* pList, DWORD ListSize)
{
	DWORD cbRet;
	return DeviceIoControl(hDev, MP3_SETLIST, pList, ListSize, &LastMpegError, sizeof(LastMpegError), &cbRet, NULL);
}

BOOL MpegPlayFile(DWORD Index)
{
	DWORD cbRet;
	return DeviceIoControl(hDev, MP3_PLAY, &Index, sizeof(Index), &LastMpegError, sizeof(LastMpegError), &cbRet, NULL);
}

BOOL MpegStopPlay()
{
	DWORD cbRet;
	return DeviceIoControl(hDev, MP3_STOP, NULL, 0, &LastMpegError, sizeof(LastMpegError), &cbRet, NULL);
}

BOOL MpegPausePlay()
{
	DWORD cbRet;
	return DeviceIoControl(hDev, MP3_PAUSE, NULL, 0, &LastMpegError, sizeof(LastMpegError), &cbRet, NULL);
}

BOOL MpegResumePlay()
{
	DWORD cbRet;
	return DeviceIoControl(hDev, MP3_RESUME, NULL, 0, &LastMpegError, sizeof(LastMpegError), &cbRet, NULL);
}

BOOL MpegGetStreamInfo(MPEGSTREAMINFO* pStream)
{
	DWORD cbRet;
	MPEGINFO Info;
	
	BOOL Ret = DeviceIoControl(hDev, MP3_GETMPEGINFO, NULL, 0, &Info, sizeof(Info), &cbRet, NULL);
	LastMpegError = Info.RetCode;
	
	if (Ret) {
		*pStream = *(MPEGSTREAMINFO*)&Info.Layer;
	
	} else if (LastMpegError == 0) {
		// call failed, but no error code
		LastMpegError = (DWORD)-1;
	}
	
	return Ret;
}

UINT MpegGetStreamPtr()
{
	DWORD cbRet, Ptr;
	if (!DeviceIoControl(hDev, MP3_GETSTREAMPTR, NULL, 0, &Ptr, sizeof(Ptr), &cbRet, NULL)) {
		LastMpegError = (DWORD)-1;
		return (UINT)-1;
	}
	return Ptr;
}

BOOL MpegSetStreamPtr(UINT Ptr)
{
	DWORD cbRet;
	return DeviceIoControl(hDev, MP3_SETSTREAMPTR, &Ptr, sizeof(Ptr), &LastMpegError, sizeof(LastMpegError), &cbRet, NULL);
}

DWORD MpegGetLastError()
{
	return LastMpegError;
}

BOOL MpegCloseDevice()
{
	if (hDev == INVALID_HANDLE_VALUE)
		return FALSE;

	CloseHandle(hDev);
	hDev = INVALID_HANDLE_VALUE;
	return TRUE;
}

BOOL MpegGetStatusInfo(MPEGSTATUSINFO* pStatus)
{
	DWORD cbRet;
	STATUSINFO Info;
	
	BOOL Ret = DeviceIoControl(hDev, MP3_GETSTATUSINFO, NULL, 0, &Info, sizeof(Info), &cbRet, NULL);
	LastMpegError = Info.RetCode;
	
	if (Ret) {
		*pStatus = *(MPEGSTATUSINFO*)&Info.Track;

	} else if (LastMpegError == 0) {
		// call failed, but no error code
		LastMpegError = (DWORD)-1;
	}
	
	return Ret;
}
