#define INCL_OS2MM
#define INCL_MMIOOS2
#define INCL_MMIO_CODEC
#define INCL_MCIOS2
#define INCL_MACHDR

#include "XVideo.h"
#include "XFrmWnd.h"
#include "XMsgBox.h"
#include "XSound.h"
#include "XCntrEvn.h"

#include "os2me.h"
#include "string.h"
#include "stdlib.h"
#include "stdio.h"


#ifndef WC_GRAPHICBUTTON
#define WC_GRAPHICBUTTON ((PSZ)0xffff0040L)
#endif

//defines for sound-class, it can handle *.mid and *.wav
#define MIDI 1
#define WAVE 2

ULONG mediaCounter = 0;


LONG XMediaWindow::SendMCIString(const USHORT notify)
{
	char errorBuffer[CCHMAXPATH];

	return mciSendString((PSZ) commandString, (PSZ) errorBuffer, (USHORT) CCHMAXPATH, owner->GetHandle(), notify);
}


XMediaWindow :: XMediaWindow(const XFrameWindow * res):XObjectWindow(res)
{
	mediaId = ++mediaCounter;
	errorEnabled = FALSE;
	owner = (XFrameWindow *) res;
	commandString = (char *) malloc(CCHMAXPATH + 100);
}


XMediaWindow :: ~XMediaWindow()
{
	free(commandString);
}



/*@ 
@class XVideo
@parent XMediaWindow
@type overview
@symbol _
*/


/*@ XVideo :: XVideo(const XFrameWindow * ow)
@group constructors/destructors
@remarks Construct a video-window. To use this control you must invoke the multimedia-library!
@parameters XFrameWindow * owner    the owner of the video
*/
XVideo :: XVideo(const XFrameWindow * ow):XMediaWindow(ow)
{
	sprintf(idString, "OOL_Movie%u", (unsigned int) mediaId);
}


/*@ XVideo::CloseDevice(void)
@group open/close
@remarks Close the device
@returns LONG resultcode
*/
LONG XVideo::CloseDevice(void)
{
	strcpy(commandString, "close digitalvideo");
	return SendMCIString();
}


/*@ XVideo::OpenDevice(void)
@group open/close
@remarks Open the device
@returns LONG resultcode
*/
LONG XVideo::OpenDevice(void)
{
	strcpy(commandString, "open digitalvideo alias ");
	strcat(commandString, idString);
	strcat(commandString, " wait shareable");
	return SendMCIString();
}


LONG XVideo::Restore(void)
{
	strcpy(commandString, "window ");
	strcat(commandString, idString);
	strcat(commandString, " state restore");
	return SendMCIString();
}


/*@ XVideo::SetViewPort(const XFrameWindow * w)
@group misc
@remarks Set a framewindow as the viewport where videos are displayed
@parameters XFrameWindow * window   the window to show the video
@returns LONG resultcode
*/
LONG XVideo::SetViewPort(const XFrameWindow * w)
{
	SWP swp;

	CHAR szHandle[10] = "";
	CHAR szcx[5] = "";
	CHAR szcy[5] = "";

	strcpy(commandString, "window ");
	strcat(commandString, idString);
	strcat(commandString, " handle ");

	sprintf(szHandle, "%lu", (ULONG) (WinQueryWindow(w->GetHandle(), QW_PARENT)));
	strcat(commandString, szHandle);
	strcat(commandString, " ");
	strcat(commandString, "wait");

	LONG res = SendMCIString();

	if (res)
		return res;

	strcpy(commandString, "put ");
	strcat(commandString, idString);
	strcat(commandString, " destination at ");
	char str[20];

	WinQueryWindowPos(w->GetHandle(), &swp);
	sprintf(str, "%i", (int) swp.x);
	strcat(commandString, str);
	strcat(commandString, " ");
	sprintf(str, "%i", (int) swp.y);
	strcat(commandString, str);
	strcat(commandString, " ");

	sprintf(szcx, "%i", (int) (swp.cx + swp.x));
	sprintf(szcy, "%i", (int) (swp.cy + swp.y));
	strcat(commandString, szcx);
	strcat(commandString, " ");
	strcat(commandString, szcy);
	strcat(commandString, " wait");

	return SendMCIString();
}


/*@ XVideo::SetVolume(const USHORT volumePercent)
@group misc
@remarks Set volume
@parameters USHORT volume  volume in percent
@returns LONG resultcode
*/
LONG XVideo::SetVolume(const USHORT volumePercent)
{
	strcpy(commandString, "set ");
	strcat(commandString, idString);
	strcat(commandString, " audio volume ");
	char bu[4];

	sprintf(bu, "%i", volumePercent);
	strcat(commandString, bu);
	strcat(commandString, " wait");
	return SendMCIString();
}



LONG XMediaWindow::SetDataFile(const char *p)
{
	strcpy(commandString, "load ");
	strcat(commandString, idString);
	strcat(commandString, " ");
	strcat(commandString, p);
	strcat(commandString, " wait");
	return SendMCIString();
}



/*@ XVideo :: ~XVideo()
@group construtors/destructors
@remarks The destructor MUST be called before the message-loop of an aplication is
destroyed. Therefore overwrite QueryForClose() of the owning framewindow and call
the destructor of XVideo in that function.
*/
XVideo :: ~XVideo()
{
	strcpy(commandString, "close ");
	strcat(commandString, idString);
	SendMCIString();
}


/*@ XMediaWindow::Play(void)
@group play functions
@remarks Play the file loaded by SetDataFile
@returns LONG resultcode
*/
LONG XMediaWindow::Play(void)
{
	strcpy(commandString, "play ");
	strcat(commandString, idString);
	strcat(commandString, " notify");
	return SendMCIString(MEDIA_PLAYED);
}


/*@ XMediaWindow::Pause(void)
@group play functions
@remarks Pause
@returns LONG resultcode
*/
LONG XMediaWindow::Pause(void)
{
	strcpy(commandString, "pause ");
	strcat(commandString, idString);
	strcat(commandString, " notify");
	return SendMCIString(MEDIA_PAUSED);
}


/*@ XMediaWindow::Rewind(void)
@group play functions
@remarks Seek to the beginning
@returns LONG resultcode
*/
LONG XMediaWindow::Rewind(void)
{
	strcpy(commandString, "seek ");
	strcat(commandString, idString);
	strcat(commandString, " to start notify");
	return SendMCIString(MEDIA_REWINDED);
}


LONG XMediaWindow::Acquire(void)
{
	strcpy(commandString, "acquire ");
	strcat(commandString, idString);
	return SendMCIString();
}


/*@ 
@class XSound
@parent XMediaWindow
@type overview
@symbol _
*/


/*@ XSound::SetVolume(const USHORT volPercent)
@group misc
@remarks Set volume
@parameters USHORT volume  volume in percent
@returns LONG resultcode
*/
LONG XSound::SetVolume(const USHORT volPercent)
{
	if (type == 0)
		return 0;

	strcpy(commandString, "set ");
	strcat(commandString, idString);
	if (type == WAVE)
		strcat(commandString, " audio");
	strcat(commandString, " volume ");
	char bu[4];

	sprintf(bu, "%i", volPercent);
	strcat(commandString, bu);
	strcat(commandString, " wait");
	return SendMCIString();
}


/*@ XSound::SetDataFile(const char *p)
@group misc
@remarks Play a new file
@parameters char * p    the file to play
@returns LONG resultcode
*/
LONG XSound::SetDataFile(const char *p)
{
	if (((strstr(p, ".MID") || strstr(p, ".mid")) && type != MIDI) || ((strstr(p, ".WAV") || strstr(p, ".wav")) && type != WAVE))
		OpenDevice(p);

	return XMediaWindow::SetDataFile(p);
}



/*@ XSound :: ~XSound()
@group constructors/destructors
@remarks The destructor MUST be called before the message-loop of an aplication is
destroyed. Therefore overwrite QueryForClose() of the owning framewindow and call
the destructor of XSound in that function.
*/
XSound :: ~XSound()
{
	if (type != 0)
	{
		strcpy(commandString, "close ");
		strcat(commandString, idString);
		type = 0;
		SendMCIString();
	}
}


/*@ XSound :: XSound(const XFrameWindow * w)
@group constructors/destructors
@remarks Construct a sound-device. XSound can play MIDI and WAV-files. To use this control you must invoke the multimedia-library!
@parameters XFrameWindow * owner    the owner of the device
*/
XSound :: XSound(const XFrameWindow * w):XMediaWindow(w)
{
	sprintf(idString, "OOL_Audio%u", (unsigned int) mediaId);
}



/*@ XSound::OpenDevice(const char *p)
@group open/close
@remarks Open the device
@parameters char * p    file to play
@returns LONG resultcode
*/
LONG XSound::OpenDevice(const char *p)
{
	LONG res = 0;

	if (type != 0)
	{
		strcpy(commandString, "close ");
		strcat(commandString, idString);
		type = 0;
		SendMCIString();
	}

	if (p)
	{
		if (strstr(p, ".WAV"))
		{
			type = WAVE;
			strcpy(commandString, "open waveaudio alias ");
		}
		else if (strstr(p, ".MID"))
		{
			strcpy(commandString, "open sequencer alias ");
			type = MIDI;
		}
	}

	if (type)
	{
		strcat(commandString, idString);
		strcat(commandString, " wait shareable");
		if ((res = SendMCIString()) != 0)
			return res;
		strcpy(commandString, "capability ");
		strcat(commandString, idString);
		strcat(commandString, " can play wait");
		res = SendMCIString();
	}
	return res;
}
