/***********************************************************************/
/* Simple CD Player --- 24 October 1992                                */
/* This module provides the CD commands.                               */
/*                                                                     */
/* Written by John A. Junod using code ideas presented in the SDK      */
/* documentation.                                                      */
/*                                                                     */
/* Modify this as much as you wish and redistribute however you wish,  */
/* but I do ask that you give me some of the credit and that you let   */
/* other people use the final product for FREE and don't charge some   */
/* silly shareware fee of $25.                                         */
/***********************************************************************/

#include "cd.h"

extern HWND hMainWnd;
extern char szBuffer[];
extern HCURSOR hHourGlass;
extern BOOL bCanEject;

DWORD CD_GetDeviceInfo(UINT wDeviceID) {
	HCURSOR hSaveCursor;
	DWORD dwReturn;
	MCI_GETDEVCAPS_PARMS mciGDCparms;
	MCI_STATUS_PARMS mciStatusParms;

	WAITON();
    // can this drive eject?
	mciGDCparms.dwItem=MCI_GETDEVCAPS_CAN_EJECT;
	if(dwReturn=mciSendCommand(wDeviceID,MCI_GETDEVCAPS,
			MCI_GETDEVCAPS_ITEM,
			(DWORD)(LPVOID)&mciGDCparms)) {
		WAITOFF();
		return(dwReturn);
	}
	bCanEject=mciGDCparms.dwReturn;
	mciStatusParms.dwItem=MCI_STATUS_MEDIA_PRESENT;
	if(dwReturn=mciSendCommand(wDeviceID,MCI_STATUS,
			MCI_STATUS_ITEM,
			(DWORD)(LPVOID)&mciStatusParms)) {
		WAITOFF();
		return(dwReturn);
	}
	WAITOFF();
	if(!(mciStatusParms.dwReturn))
		MessageBox(hMainWnd,"No media present.","CD Audio Player",MB_OK);
	return(0L);
}

DWORD CD_ShowTrackTimes(UINT wDeviceID,LPSTR szTimeString) {
	HCURSOR hSaveCursor;
	int i, iNumTracks, iStatus;
	DWORD dwReturn;
	DWORD dwPosition;
	DWORD *pMem;
	char szTempString[64];
	MCI_SET_PARMS mciSetParms;
	MCI_STATUS_PARMS mciStatusParms;


	WAITON();

	// set time format to minute/second/frame
	mciSetParms.dwTimeFormat=MCI_FORMAT_MSF;
	if(dwReturn=mciSendCommand(wDeviceID,MCI_SET,MCI_SET_TIME_FORMAT,
		(DWORD)(LPVOID)&mciSetParms)) {
		WAITOFF();
		return(dwReturn);
	}
	// get number of tracks (limit to 20)
	mciStatusParms.dwItem=MCI_STATUS_NUMBER_OF_TRACKS;
	if(dwReturn=mciSendCommand(wDeviceID,MCI_STATUS,MCI_STATUS_ITEM,
		(DWORD)(LPVOID)&mciStatusParms)) {
		WAITOFF();
		return(dwReturn);
	}
	iNumTracks=mciStatusParms.dwReturn;
	wsprintf(szTimeString,"  CD Player\nJohn A. Junod\nTracks: %2d\n",
		iNumTracks);
	// iNumTracks=min(iNumTracks,20);

    // get device status
	mciStatusParms.dwItem=MCI_STATUS_MODE;
	if((dwReturn=mciSendCommand(wDeviceID,MCI_STATUS,MCI_STATUS_ITEM,
			(DWORD)(LPVOID)&mciStatusParms))==0L) {
		iStatus=mciStatusParms.dwReturn;
		wsprintf(szTempString,"Status: %d\nEject: %d\n",iStatus,bCanEject);
		lstrcat(szTimeString,szTempString);

		// alloc memory for start
		if((pMem=(DWORD *)LocalAlloc(LPTR,iNumTracks*sizeof(DWORD)))!=NULL) {
			// for each track, get and save start position and build string
			for(i=1;i<=iNumTracks;i++) {
				mciStatusParms.dwItem=MCI_STATUS_LENGTH;
				mciStatusParms.dwTrack=i;
				if(dwReturn=mciSendCommand(wDeviceID,MCI_STATUS,
						MCI_STATUS_ITEM | MCI_TRACK, (DWORD)(LPVOID)&mciStatusParms)) {
					LocalFree((HANDLE)pMem);
					WAITOFF();
					return(dwReturn);
				}
				pMem[i-1]=mciStatusParms.dwReturn;
				wsprintf(szTempString,"Track %2d - %02d:%02d:%02d\n",
					i,MCI_MSF_MINUTE(pMem[i-1]), MCI_MSF_SECOND(pMem[i-1]),
					MCI_MSF_FRAME(pMem[i-1]));
				lstrcat(szTimeString,szTempString);
			}
			// display results
			MessageBox(hMainWnd,szTimeString,"Track Times",
				MB_OK);
			// free memory and close device
			LocalFree((HANDLE)pMem);
			dwReturn=0L;
		} else dwReturn= -1L; // pMem failed
	}
	WAITOFF();
	return(dwReturn);
}

int CD_GetCurrentTrack(UINT wDeviceID) {
	DWORD dwReturn;
	int iCurrentTrack;
	MCI_SET_PARMS mciSetParms;
	MCI_STATUS_PARMS mciStatusParms;

	// set time format to minute/second/frame
	mciSetParms.dwTimeFormat=MCI_FORMAT_MSF;
	if(dwReturn=mciSendCommand(wDeviceID,MCI_SET,MCI_SET_TIME_FORMAT,
			(DWORD)(LPVOID)&mciSetParms))
		iCurrentTrack= -1;
	else {
		// get current track that we are playing
		mciStatusParms.dwItem=MCI_STATUS_CURRENT_TRACK;
		if(dwReturn=mciSendCommand(wDeviceID,MCI_STATUS,
				MCI_STATUS_ITEM,
				(DWORD)(LPVOID)&mciStatusParms))
			iCurrentTrack= -1;
		else
			iCurrentTrack=mciStatusParms.dwReturn;
	}
//	if(iCurrentTrack== -1) showMCIError(dwReturn);
	return(iCurrentTrack);
}

int CD_GetCurrentStatus(UINT wDeviceID) {
	DWORD dwReturn;
	MCI_STATUS_PARMS mciStatusParms;
	int iRetCode;

	iRetCode=0;
	mciStatusParms.dwItem=MCI_STATUS_MODE;
	if(dwReturn=mciSendCommand(wDeviceID,MCI_STATUS,MCI_STATUS_ITEM,
			(DWORD)(LPVOID)&mciStatusParms)) {
		iRetCode= -1;
	} else {
		switch(mciStatusParms.dwReturn) {
			case MCI_MODE_PLAY:	 iRetCode=1; break;
			case MCI_MODE_PAUSE: iRetCode=2; break;
			case MCI_MODE_OPEN:  iRetCode=4; break;
			case MCI_MODE_SEEK:  iRetCode=3; break;
			case MCI_MODE_NOT_READY: iRetCode=3; break;
		}
	}
//	if(iRetCode== -1) showMCIError(dwReturn);
	return(iRetCode);
}

// play a given cdaudio track
DWORD CD_PlayTrack(UINT wDeviceID,BYTE bStartTrack,BYTE bEndTrack)
{
	HCURSOR hSaveCursor;
	DWORD dwParams;
	DWORD dwReturn;
	MCI_SET_PARMS mciSetParms;
	MCI_PLAY_PARMS mciPlayParms;

	WAITON();
	// set time format to track/minute/second/frame
	mciSetParms.dwTimeFormat=MCI_FORMAT_TMSF;
	if(dwReturn=mciSendCommand(wDeviceID,MCI_SET,MCI_SET_TIME_FORMAT,
			(DWORD)(LPVOID)&mciSetParms))
	{
		WAITOFF();
		return(dwReturn);
	}

	// notify on completion
	dwParams=MCI_NOTIFY;
	mciPlayParms.dwCallback=(DWORD)hMainWnd;
	// if start is not specified, we pick up where we left off
	if(bStartTrack>0) dwParams |= MCI_FROM;
	mciPlayParms.dwFrom=MCI_MAKE_TMSF(bStartTrack,0,0,0);
	// if end is not specified, we play the rest of the cd
	if(bEndTrack>bStartTrack) dwParams |= MCI_TO;
	mciPlayParms.dwTo  =MCI_MAKE_TMSF(bEndTrack,0,0,0);
	// execute the command
	dwReturn=mciSendCommand(wDeviceID,MCI_PLAY,
			dwParams,(DWORD)(LPVOID) &mciPlayParms);
	WAITOFF();
	return(dwReturn);
}

// pause cdaudio
DWORD CD_Pause(UINT wDeviceID) {
	HCURSOR hSaveCursor;
	DWORD dwReturn;
	MCI_GENERIC_PARMS mciGenericParms;

	WAITON();
	mciGenericParms.dwCallback=(DWORD)hMainWnd;
	dwReturn=mciSendCommand(wDeviceID,MCI_PAUSE,MCI_NOTIFY,
		(DWORD)(LPVOID)&mciGenericParms);
	WAITOFF();
	return(dwReturn);
}

DWORD CD_ResumePlay(UINT wDeviceID){
	HCURSOR hSaveCursor;
	DWORD dwReturn;
	MCI_GENERIC_PARMS mciGenericParms;
	MCI_PLAY_PARMS    mciPlayParms;

	WAITON();
	mciGenericParms.dwCallback=(DWORD)hMainWnd;
	mciPlayParms.dwCallback   =(DWORD)hMainWnd;
	// attempt a resume command, if it fails (device doesn't support it),
	// then do a play with no parameters.
	if(dwReturn=mciSendCommand(wDeviceID,MCI_RESUME,MCI_NOTIFY,
		(DWORD)(LPVOID)&mciGenericParms))
		dwReturn=mciSendCommand(wDeviceID,MCI_PLAY,MCI_NOTIFY,
			(DWORD)(LPVOID)&mciPlayParms);
	WAITOFF();
	return(dwReturn);
}

DWORD CD_Stop(UINT wDeviceID){
	HCURSOR hSaveCursor;
	DWORD dwReturn;
	MCI_GENERIC_PARMS mciGenericParms;

	WAITON();
	mciGenericParms.dwCallback=(DWORD)hMainWnd;
	dwReturn=mciSendCommand(wDeviceID,MCI_STOP,MCI_NOTIFY,
			(DWORD)(LPVOID)&mciGenericParms);
	WAITOFF();
	return(dwReturn);
}

DWORD CD_Open(UINT wDeviceID){
	HCURSOR hSaveCursor;
	DWORD dwReturn;
	MCI_SET_PARMS mciSetParms;

	WAITON();
	mciSetParms.dwCallback=(DWORD)hMainWnd;
	dwReturn=mciSendCommand(wDeviceID,MCI_SET_DOOR_OPEN,MCI_NOTIFY,
			(DWORD)(LPVOID)&mciSetParms);
	WAITOFF();
	return(dwReturn);
}

DWORD CD_Close(UINT wDeviceID){
	HCURSOR hSaveCursor;
	DWORD dwReturn;
	MCI_SET_PARMS mciSetParms;

	WAITON();
	mciSetParms.dwCallback=(DWORD)hMainWnd;
	dwReturn=mciSendCommand(wDeviceID,MCI_SET_DOOR_CLOSED,MCI_NOTIFY,
			(DWORD)(LPVOID)&mciSetParms);
	WAITOFF();
	return(dwReturn);
}

DWORD CD_ChangeTrack(UINT wDeviceID,int iNoffs) {
	int iNewTrack;

	iNewTrack=CD_GetCurrentTrack(wDeviceID)+iNoffs;
	if(iNewTrack<1) return(0L);
	return(CD_PlayTrack(wDeviceID,iNewTrack,0));
}
