//
// VLC player scol plugin
// Bastien BOURINEAU
//

#include "scolplugin.h"
#include "ObjVlcMediaPlayer.h"

//!Scol machine declaration for MM macros
cbmachine ww;

//#define		_SCOL_DEBUG_

// Scol object types
int OBJ_TYPE_VLC_PLAYER;

// Scol object events
int VLCMEDIA_EVENT;


/** destroyVlcPlayer (internal)
  * called on Scol ObjVlcPlayer object destroy
  * destroy the Scol object and the libvlc media player
  *
  * return 0
**/
int destroyVlcPlayer(mmachine m,int handsys,int vlcplayer)
{
	ObjVlcMediaPlayer* VlcOBJPlayer =(ObjVlcMediaPlayer*)MMfetch(m, MTOP(vlcplayer), 0);
	
	SAFE_DELETE(VlcOBJPlayer);	

	MMstore(m, MTOP(vlcplayer), 0, NULL);
	return 0;
}


/** _dsVlcPlayer
  * destroy the Scol vlc media player
  *	fun [ObjVlcPlayer] I	
  *
  * return 0 on success
**/
int _dsVlcPlayer(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_dsVlcPlayer\n");
#endif

	int vlcplayer = MMget(m, 0);
	if (vlcplayer == NIL)
  {
    MMset(m, 0, NIL);
    return 0;
  }

	OBJdelTM(m, OBJ_TYPE_VLC_PLAYER, vlcplayer);

	MMset(m, 0, 0);

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _crVlcVmenPlayer
  * create a Scol vlc instance
  *	fun [Chn ObjBitmap] ObjVlcInstance
  *
  * return ObjVlcInstance, NIL on error
**/
int _crVlcVmenPlayer(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_crVlcVmenPlayer\n");
#endif
	
	PtrObjVoid OB;
	PtrObjBitmap B;

	int bmp = MMpull(m);
	
	if (bmp == NIL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
	OB = (PtrObjVoid) MMstart(m, MTOP(bmp));
	B = (PtrObjBitmap) MMstart(m, MTOP(OB->Buffer));
	
  ObjVlcMediaPlayer* VlcOBJPlayer = new ObjVlcMediaPlayer(B, B->TailleW, B->TailleH, B->TailleW * B->BytesPP);
	if (VlcOBJPlayer == NULL) { MMset(m,0,NIL); return 0;}

	int vlc = MMmalloc(m,1,TYPETAB);
	if (vlc == NIL)
	{
		SAFE_DELETE(VlcOBJPlayer);
		MMset(m, 0, NIL);
		return MERRMEM;
	}
  
	MMstore(m, vlc, 0, (int)VlcOBJPlayer);
	MMpush(m, PTOM(vlc));

	int k = OBJcreate(m, OBJ_TYPE_VLC_PLAYER, (int)VlcOBJPlayer, OBJtypebyname("OBJTYPBITMAP"), (int)B->handler);

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif
	return k ;
}


/** _crVlcStream
  * create a Scol vlc stream
  *	fun [Chn S S I I I S I] ObjVlcPlayer
  *
  * return Int OBJcreate
**/
int _crVlcStream(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_crVlcStream\n");
#endif

	int iport = MTOI(MMpull(m));
	int sip = MMpull(m);
	int ivrate = MTOI(MMpull(m));
	int iheight = MTOI(MMpull(m));
	int iwidth = MTOI(MMpull(m));
	int sdevice = MMpull(m);
	int sname = MMget(m,0);
	
	if (iwidth == NIL) iwidth = 160;
	if (iheight == NIL) iheight = 120;
	if (ivrate == NIL) ivrate = 128;
	
  if ((sdevice == NIL) || (sip == NIL) || (iport == NIL) || (sname == NIL))
  {
    MMset(m, 0, NIL);
    return 0;
  }

  std::string vlmName(MMstartstr(m, MTOP(sname)));
	std::string device(MMstartstr(m,MTOP(sdevice)));
	std::string ip(MMstartstr(m,MTOP(sip)));
  if (vlmName.empty() || device.empty() || ip.empty())
  {
    MMechostr(MSKRUNTIME, "_crVlcStream : name or param empty\n");
    MMset(m, 0, NIL);
    return 0;
  }

	ObjVlcMediaPlayer* VlcOBJPlayer = new ObjVlcMediaPlayer(ip, iport, device, vlmName, iwidth, iheight, ivrate);
	if (VlcOBJPlayer == 0)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
	int vlc = MMmalloc(m,1,TYPETAB);
	if (vlc == NIL)
  {
    SAFE_DELETE(VlcOBJPlayer);
    MMset(m, 0, NIL);
    return MERRMEM;
  }
	
	MMstore(m, vlc, 0, (int)VlcOBJPlayer);
	MMpush(m, PTOM(vlc));

	int k = OBJcreate(m, OBJ_TYPE_VLC_PLAYER, (int)VlcOBJPlayer, NIL, NIL);

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif
	return k ;
}


/** _crVlcPlayer
  * create a Scol vlc media player
  *	fun [Chn] ObjVlcPlayer
  *
  * return Int OBJcreate
**/
int _crVlcPlayer(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_crVlcPlayer\n");
#endif

	ObjVlcMediaPlayer* VlcOBJPlayer = new ObjVlcMediaPlayer();
	if (VlcOBJPlayer == NULL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
		
	int vlc = MMmalloc(m,1,TYPETAB);
	if (vlc == NIL)
  {
    SAFE_DELETE(VlcOBJPlayer);
    MMset(m, 0, NIL);
    return MERRMEM;
  }

	MMstore(m, vlc, 0, (int)VlcOBJPlayer);
	MMpush(m, PTOM(vlc));

	int k = OBJcreate(m, OBJ_TYPE_VLC_PLAYER, (int)VlcOBJPlayer, NIL, NIL);

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif
	return k ;
}

/** _setVlcPlayerWindow
  * Attach a Scol vlc media player to a window
  *	fun [ObjVlcPlayer ObjWin] ObjVlcPlayer
  *
  * return same ObjVlcPlayer
**/
int _setVlcPlayerWindow(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_setVlcPlayerWindow\n");
#endif

	HWND parent;
	PtrObjVoid OB;
	PtrObjWindow W;
	
	int pWin = MMpull (m);
	int vlcplayer = MMget(m,0);

	if ((vlcplayer == NIL) || (pWin == NIL))
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
	ObjVlcMediaPlayer* VlcOBJPlayer = (ObjVlcMediaPlayer*)MMfetch(m, MTOP(vlcplayer), 0);
	if (VlcOBJPlayer == NULL)
  {
    MMset(m, 0, NIL);
    return 0;
  }

	OB = (PtrObjVoid) MMstart(m, MTOP(pWin));
	W = (PtrObjWindow) MMstart(m, (OB->Buffer>>1));
	parent = W->WHandler;
	
	if (((parent == NULL) && (pWin != NIL)) || (VlcOBJPlayer == 0) || (VlcOBJPlayer->isVmem()) || (VlcOBJPlayer->isVlm()))
  {
    MMset(m, 0, NIL);
    return 0;
  }
  
	/* on windows */
  VlcOBJPlayer->setWindow(parent);

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif
	
	return 0;
}


/** _setVlcPlayerFile
  * set the media url to the media player
  *	fun [ObjVlcPlayer P] ObjVlcPlayer
  *
  * return 0
**/
int _setVlcPlayerFile(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_setVlcPlayerFile\n");
#endif
	
	int path = MMpull(m);
	int vlcplayer = MMget(m, 0);

	if ((vlcplayer == NIL) || (path == NIL))
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
	ObjVlcMediaPlayer* VlcOBJPlayer = (ObjVlcMediaPlayer*)MMfetch(m, MTOP(vlcplayer), 0);
	if (VlcOBJPlayer == NULL)
  {
    MMset(m, 0, NIL);
    return 0;
  }

  std::string spath(MMstartstr(m, MTOP(path)));
  VlcOBJPlayer->setMediaPath(spath);

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif
	
	return 0;
}


/** _setVlcPlayerUrl
  * set the media url to the media player
  *	fun [ObjVlcPlayer S] ObjVlcPlayer
  *
  * return 0
**/
int _setVlcPlayerUrl(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_setVlcPlayerUrl\n");
#endif
	
	int path = MMpull(m);
	int vlcplayer = MMget(m, 0);

	if ((vlcplayer == NIL) || (path == NIL))
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
	ObjVlcMediaPlayer* VlcOBJPlayer = (ObjVlcMediaPlayer*)MMfetch(m, MTOP(vlcplayer), 0);
	if (VlcOBJPlayer == NULL)
  {
    MMset(m, 0, NIL);
    return 0;
  }

  std::string spath(MMstartstr(m, MTOP(path)));
  VlcOBJPlayer->setMediaPath(spath);

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif
	
	return 0;
}


/** _playVlcPlayer
  * start playing the media player
  *	fun [ObjVlcPlayer] ObjVlcPlayer
  *
  * return 0
**/
int _playVlcPlayer(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_playVlcPlayer\n");
#endif
	
	int vlcplayer = MMget(m, 0);
	if (vlcplayer == NIL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
	ObjVlcMediaPlayer* VlcOBJPlayer = (ObjVlcMediaPlayer*)MMfetch(m, MTOP(vlcplayer), 0);
	if (VlcOBJPlayer == NULL)
  {
    MMset(m, 0, NIL);
    return 0;
  }

  VlcOBJPlayer->play();

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _pauseVlcPlayer
  * pause / play the media player
  *	fun [ObjVlcPlayer] ObjVlcPlayer
  *
  * return 0
**/
int _pauseVlcPlayer(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_pauseVlcPlayer\n");
#endif

	int vlcplayer = MMget(m, 0);
	if (vlcplayer == NIL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
	ObjVlcMediaPlayer* VlcOBJPlayer = (ObjVlcMediaPlayer*)MMfetch(m, MTOP(vlcplayer), 0);
	if (VlcOBJPlayer == NULL)
  {
    MMset(m, 0, NIL);
    return 0;
  }

  VlcOBJPlayer->pause();

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _stopVlcPlayer
  * stop the media player
  *	fun [ObjVlcPlayer] ObjVlcPlayer
  *
  * return 0
**/
int _stopVlcPlayer(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_stopVlcPlayer\n");
#endif
	
	int vlcplayer = MMget(m, 0);
	if (vlcplayer == NIL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
	ObjVlcMediaPlayer* VlcOBJPlayer = (ObjVlcMediaPlayer*)MMfetch(m, MTOP(vlcplayer), 0);
	if (VlcOBJPlayer == NULL)
  {
    MMset(m, 0, NIL);
    return 0;
  }

  VlcOBJPlayer->stop();

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _setVlcPlayerFullScreenState
  * change the media player fullscreen state
  *	fun [ObjVlcPlayer I] I
  * if the bool param is nil then the function switch the state
  * the I return param is the new fullscreen state
  *
  * return 0
**/
int _setVlcPlayerFullScreenState(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_setVlcPlayerFullScreenState\n");
#endif
	
	int mode = MMpull(m);
	int vlcplayer = MMget(m, 0);
	if (vlcplayer == NIL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
  bool state = false;
  if ((mode != NIL) && (MTOI(mode) > 0))
    state = true;

	ObjVlcMediaPlayer* VlcOBJPlayer = (ObjVlcMediaPlayer*)MMfetch(m, MTOP(vlcplayer), 0);
	if (VlcOBJPlayer == NULL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
  /* toggle fullscreen of media_player */
	if (mode == NIL)
		VlcOBJPlayer->toggleFullScreen();
	else
		VlcOBJPlayer->setFullScreen(state);

  MMset(m, 0, ITOM(VlcOBJPlayer->getFullScreenState() ? 1 : 0));

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _getVlcPlayerFullScreenState
  * get the media player fullscreen state
  *	fun [ObjVlcPlayer] I
  * the I return param is the current fullscreen state
  *
  * return 0
**/
int _getVlcPlayerFullScreenState(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_getVlcPlayerFullScreenState\n");
#endif
	
	int vlcplayer = MMget(m, 0);
	if (vlcplayer == NIL)
  {
    MMset(m, 0, NIL);
    return 0;
  }

	ObjVlcMediaPlayer* VlcOBJPlayer = (ObjVlcMediaPlayer*)MMfetch(m, MTOP(vlcplayer), 0);
	if (VlcOBJPlayer == NULL)
  {
    MMset(m, 0, NIL);
    return 0;
  }

  MMset(m, 0, ITOM(VlcOBJPlayer->getFullScreenState() ? 1 : 0));
	
#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _seekVlcPlayer
  * seek the vlc media player
  *	fun [ObjVlcPlayer F] F
  * the F param is a 0.0 to 1.0 percentage
  * the F return param is the new player position
  *
  * return 0
**/
int _seekVlcPlayer(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_seekVlcPlayer\n");
#endif
	
	int iseek = MMpull(m);
	int vlcplayer = MMget(m, 0);
	if ((vlcplayer == NIL) || (iseek == NIL))
  {
    MMset(m, 0, NIL);
    return 0;
  }
  
	ObjVlcMediaPlayer* VlcOBJPlayer = (ObjVlcMediaPlayer*)MMfetch(m, MTOP(vlcplayer), 0);
	if (VlcOBJPlayer == NULL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
  if (VlcOBJPlayer->seek(MTOF(iseek)))
    MMset(m, 0, FTOM(VlcOBJPlayer->getPosition()));
	else
		MMset(m, 0, NIL);
	
#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _getVlcPlayerPosition
  * seek the vlc media player
  *	fun [ObjVlcPlayer] F
  * the F return param is the curent player position
  *
  * return 0
**/
int _getVlcPlayerPosition(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_getVlcPlayerPosition\n");
#endif
	
	int vlcplayer = MMget(m, 0);
	if (vlcplayer == NIL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
  
	ObjVlcMediaPlayer* VlcOBJPlayer = (ObjVlcMediaPlayer*)MMfetch(m, MTOP(vlcplayer), 0);
	if (VlcOBJPlayer == NULL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
  MMset(m, 0, FTOM(VlcOBJPlayer->getPosition()));	

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _setVlcPlayerPosition
  * set the vlc media player position 
  *	fun [ObjVlcPlayer F] F
  * the F param is a 0.0 to 1.0 percentage
  * the F return param is the new player position
  *
  * return 0
**/
int _setVlcPlayerPosition(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_setVlcPlayerPosition\n");
#endif
	
	int ipos = MMpull(m);
	int vlcplayer = MMget(m, 0);
	if ((vlcplayer == NIL) || (ipos == NIL))
  {
    MMset(m, 0, NIL);
    return 0;
  }
  
	ObjVlcMediaPlayer* VlcOBJPlayer = (ObjVlcMediaPlayer*)MMfetch(m, MTOP(vlcplayer), 0);
	if (VlcOBJPlayer == NULL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
  if (VlcOBJPlayer->setPosition(MTOF(ipos)))
    MMset(m, 0, FTOM(VlcOBJPlayer->getPosition()));
	else
		MMset(m, 0, NIL);	

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _getVlcPlayerTime
  * get the current vlc media player time
  *	fun [ObjVlcPlayer] I
  * the I return param is the current time pos in ms
  *
  * return 0
**/
int _getVlcPlayerTime(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_getVlcPlayerTime\n");
#endif
	
	int vlcplayer = MMget(m, 0);
	if (vlcplayer == NIL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
  
	ObjVlcMediaPlayer* VlcOBJPlayer = (ObjVlcMediaPlayer*)MMfetch(m, MTOP(vlcplayer), 0);
	if (VlcOBJPlayer == NULL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
  MMset(m, 0, ITOM(VlcOBJPlayer->getTime()));	

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _setVlcPlayerTime
  * get the current vlc media player time
  *	fun [ObjVlcPlayer I] I
  * the I param is the time pos in ms 
  * the I return param is the new time pos in ms
  *
  * return 0
**/
int _setVlcPlayerTime(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_setVlcPlayerTime\n");
#endif
	
	int ipos = MMpull(m);
	int vlcplayer = MMget(m, 0);
	if ((vlcplayer == NIL) || (ipos == NIL))
  {
    MMset(m, 0, NIL);
    return 0;
  }
  
	ObjVlcMediaPlayer* VlcOBJPlayer = (ObjVlcMediaPlayer*)MMfetch(m, MTOP(vlcplayer), 0);
	if (VlcOBJPlayer == NULL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
  if (VlcOBJPlayer->setTime(MTOI(ipos)))
    MMset(m, 0, ITOM(VlcOBJPlayer->getTime()));
	else
		MMset(m, 0, NIL);	
	

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _getVlcPlayerDuration
  * get the vlc media player duration in ms
  *	fun [ObjVlcPlayer] I
  * the I return param is the duration in ms
  *
  * return 0
**/
int _getVlcPlayerDuration(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_getVlcPlayerDuration\n");
#endif

	int vlcplayer = MMget(m, 0);
	if (vlcplayer == NIL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
  
	ObjVlcMediaPlayer* VlcOBJPlayer = (ObjVlcMediaPlayer*)MMfetch(m, MTOP(vlcplayer), 0);
	if (VlcOBJPlayer == NULL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
  MMset(m, 0, ITOM(VlcOBJPlayer->getDuration()));

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _getVlcPlayerState
  * get the vlc media player state
  *	fun [ObjVlcPlayer] I
  * the I return param is the current state
  *
  * return 0
**/
int _getVlcPlayerState(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_getVlcPlayerState\n");
#endif

	int vlcplayer = MMget(m, 0);
	if (vlcplayer == NIL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
  
	ObjVlcMediaPlayer* VlcOBJPlayer = (ObjVlcMediaPlayer*)MMfetch(m, MTOP(vlcplayer), 0);
	if (VlcOBJPlayer == NULL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
  MMset(m, 0, ITOM(VlcOBJPlayer->getState()));
	
#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _saveVlcPlayerSnapShot
  * write a snapshot file of the video
  *	fun [ObjVlcPlayer W I I] I
  * the I return param is the current state
  *
  * return 0
**/
int _saveVlcPlayerSnapShot(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_saveVlcPlayerSnapShot\n");
#endif
	
	int h = MTOI(MMpull(m));
	int w = MTOI(MMpull(m));
	int path = MTOP(MMpull(m));
	int vlcplayer = MTOP(MMget(m, 0));
	
	char* filename = (char*)MMstartstr(m,path);	
	
	if (vlcplayer == NIL || h == NIL || w == NIL || path == NIL) { MMset(m,0,NIL); return 0 ; }

	ObjVlcMediaPlayer* VlcOBJPlayer =(ObjVlcMediaPlayer*)MMfetch(m, vlcplayer, 0);
	
	if(!VlcOBJPlayer || !VlcOBJPlayer->getMediaPlayer()) { MMset(m,0,NIL); return 0 ; }

	libvlc_media_t *media = (libvlc_media_player_get_media (VlcOBJPlayer->getMediaPlayer()));
	
	if (media != NULL)
	{
		libvlc_video_take_snapshot(VlcOBJPlayer->getMediaPlayer(), 0, filename, w, h);
		
		MMset(m, 0, ITOM(1));
	}
	else
		MMset(m, 0, NIL);

	libvlc_media_release(media);
	
	
#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _getVlcAudioVolume
  * get the vlc instance setted volume
  *	fun [ObjVlcPlayer] I
  * the I return param is the volume
  *
  * return 0
**/
int _getVlcAudioVolume(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_getVlcAudioVolume\n");
#endif
	
	int vlcplayer = MMget(m, 0);
	if (vlcplayer == NIL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
	ObjVlcMediaPlayer* VlcOBJPlayer =(ObjVlcMediaPlayer*)MMfetch(m, vlcplayer, 0);
	if(!VlcOBJPlayer)
  {
    MMset(m, 0, NIL);
    return 0;
  }

  MMset(m, 0, ITOM(VlcOBJPlayer->getVolume()));

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _setVlcAudioVolume
  * set the vlc instance volume
  *	fun [ObjVlcPlayer I] ObjVlcPlayer
  * the I param is the new volume
  *
  * return 0
**/
int _setVlcAudioVolume(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_setVlcAudioVolume\n");
#endif
	
	int vol = MTOI(MMpull(m));
	int vlcplayer = MMget(m, 0);
	if (vlcplayer == NIL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
	ObjVlcMediaPlayer* VlcOBJPlayer =(ObjVlcMediaPlayer*)MMfetch(m, vlcplayer, 0);
	if(!VlcOBJPlayer)
  {
    MMset(m, 0, NIL);
    return 0;
  }

	if (vol == NIL || vol < 0)
		vol = 0;
	else if (vol > 200)
		vol = 200;

  VlcOBJPlayer->setVolume(vol);

	MMset(m, 0, ITOM(VlcOBJPlayer->getVolume()));

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _setVlcAudioMute
  * set the vlc instance mute state
  *	fun [ObjVlcPlayer I] ObjVlcPlayer
  * the I param is the new state
  *
  * return 0
**/
int _setVlcAudioMute(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_setVlcAudioMute\n");
#endif
	
	int imute = MTOI(MMpull(m));
	if (imute == NIL)
		imute = 0;

	int vlcplayer = MMget(m, 0);
	if (vlcplayer == NIL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
	ObjVlcMediaPlayer* VlcOBJPlayer =(ObjVlcMediaPlayer*)MMfetch(m, vlcplayer, 0);
	if(!VlcOBJPlayer)
  {
    MMset(m, 0, NIL);
    return 0;
  }

  VlcOBJPlayer->setMute((imute == 1) ? true : false);

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _getVlcAudioMute
  * get the vlc instance mute state
  *	fun [ObjVlcPlayer] I
  * the I return param is the current mute state
  *
  * return 0
**/
int _getVlcAudioMute(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_getVlcAudioMute\n");
#endif
	
	int vlcplayer = MMget(m, 0);
	if (vlcplayer == NIL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
	ObjVlcMediaPlayer* VlcOBJPlayer =(ObjVlcMediaPlayer*)MMfetch(m, vlcplayer, 0);
	if(!VlcOBJPlayer)
  {
    MMset(m, 0, NIL);
    return 0;
  }

  MMset(m, 0, ITOM(VlcOBJPlayer->getMute() ? 1 : 0));

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}

/** _setVlcPlayerLoop
  * set the vlc instance loop state
  *	fun [ObjVlcPlayer I] ObjVlcPlayer
  * the I param is the new state
  *
  * return 0
**/
int _setVlcPlayerLoop(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_setVlcPlayerLoop\n");
#endif
	
	int iloop = MTOI(MMpull(m));
	if (iloop == NIL)
		iloop = 0;

	int vlcplayer = MMget(m, 0);
	if (vlcplayer == NIL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
	ObjVlcMediaPlayer* VlcOBJPlayer =(ObjVlcMediaPlayer*)MMfetch(m, vlcplayer, 0);
	if(!VlcOBJPlayer)
  {
    MMset(m, 0, NIL);
    return 0;
  }

  VlcOBJPlayer->setLoop((iloop == 1) ? true : false);

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _getVlcPlayerLoop
  * get the vlc instance loop state
  *	fun [ObjVlcPlayer] I
  * the I return param is the current loop state
  *
  * return 0
**/
int _getVlcPlayerLoop(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_getVlcPlayerLoop\n");
#endif
	
	int vlcplayer = MMget(m, 0);
	if (vlcplayer == NIL)
  {
    MMset(m, 0, NIL);
    return 0;
  }
	
	ObjVlcMediaPlayer* VlcOBJPlayer =(ObjVlcMediaPlayer*)MMfetch(m, vlcplayer, 0);
	if(!VlcOBJPlayer)
  {
    MMset(m, 0, NIL);
    return 0;
  }

  MMset(m, 0, ITOM(VlcOBJPlayer->getLoop() ? 1 : 0));

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _cbVlcMediaEvent
  * set the media event callback
  *	fun [ObjVlcPlayer fun [ObjVlcPlayer u0 I] u1 u0] I
  * return new reflex
**/
int _cbVlcMediaEvent(mmachine m)
{
	return OBJaddreflex(m, OBJ_TYPE_VLC_PLAYER, RFL_EVT_VLCMEDIA);
}


/** getVlcMediaEvent (internal)
  *
  * return new reflex
**/
int getVlcMediaEvent(mmachine m,HWND h,unsigned msg,UINT id,LONG param,int *ret)
{
	int k ;

  // manage loop here to make sur we get this in the main thread to avoid crash
  ObjVlcMediaPlayer* VlcOBJPlayer = (ObjVlcMediaPlayer*)id;
  if (((int)param == libvlc_MediaPlayerEndReached) && VlcOBJPlayer->getLoop())
    VlcOBJPlayer->play();

	if(!(k = OBJbeginreflex(m, OBJ_TYPE_VLC_PLAYER, id, RFL_EVT_VLCMEDIA)))
	{
		if (k=MMpush(m, ITOM((int)param))) return k;
		// 1 nb params
		k = OBJcallreflex(m,1);
	}

	return k ;
}


/** _getVlcVideoDevices
  * get the Dshow video capture list
  *	fun [] [S r1]
  * return the list of video capture device name
  *
  * return 0
**/
int _getVlcVideoDevices(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_getVlcVideoDevices\n");
#endif

    IBaseFilter *p_base_filter = NULL;
    IMoniker *p_moniker = NULL;
    ULONG i_fetched;
    HRESULT hr;

	/*Create the system device enumerator*/
    ICreateDevEnum *p_dev_enum = NULL;

    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
                           IID_ICreateDevEnum, (void **)&p_dev_enum);

	if(FAILED(hr)) { MMset(m,0,NIL); return 0 ; }

    /* Create an enumerator for the video capture devices */
    IEnumMoniker *p_class_enum = NULL;
    hr = p_dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &p_class_enum, 0);

    p_dev_enum->Release();
    if(FAILED(hr)) { MMset(m,0,NIL); return 0 ; }

    /* If there are no enumerators for the requested type, then
     * CreateClassEnumerator will succeed, but p_class_enum will be NULL */
    if(p_class_enum == NULL) { MMset(m,0,NIL); return 0 ; }

   /* Enumerate the devices */

    /* Note that if the Next() call succeeds but there are no monikers,
     * it will return S_FALSE (which is not a failure). Therefore, we check
     * that the return code is S_OK instead of using SUCCEEDED() macro. */
	
	int n = 0 ;
	int k;

    while(p_class_enum->Next(1, &p_moniker, &i_fetched) == S_OK)
    {
        /* Getting the property page to get the device name */
        IPropertyBag *p_bag;
        hr = p_moniker->BindToStorage(0, 0, IID_IPropertyBag,
                                       (void **)&p_bag);
        if(SUCCEEDED(hr))
        {
            VARIANT var;
            var.vt = VT_BSTR;
            hr = p_bag->Read(L"FriendlyName", &var, NULL);
            p_bag->Release();
            if(SUCCEEDED(hr))
            {
                int i_convert = WideCharToMultiByte(CP_ACP, 0, var.bstrVal,
                        SysStringLen(var.bstrVal), NULL, 0, NULL, NULL);
                char *p_buf = (char *)malloc(i_convert+1); p_buf[0] = 0;
                WideCharToMultiByte(CP_ACP, 0, var.bstrVal,
                        SysStringLen(var.bstrVal), p_buf, i_convert, NULL, NULL);
                SysFreeString(var.bstrVal);
                p_buf[i_convert] = '\0';

				char *devname = p_buf;

				if (k=Mpushstrbloc(m, p_buf)) return k;
				n++;
            }
        }

        p_moniker->Release();
    }

    p_class_enum->Release();

	if(MMpush(m,NIL))		return MERRMEM;

	for(int j=0;j<n;j++)
	{
		if (MMpush(m,2*2)) return MERRMEM;
		if (k=MBdeftab(m)) return k;
	}


#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


/** _getVlcAudioDevices
  * get the Dshow audio capture list
  *	fun [] [S r1]
  * return the list of audio capture device name
  *
  * return 0
**/
int _getVlcAudioDevices(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_getVlcAudioDevices\n");
#endif

    IBaseFilter *p_base_filter = NULL;
    IMoniker *p_moniker = NULL;
    ULONG i_fetched;
    HRESULT hr;

	/*Create the system device enumerator*/
    ICreateDevEnum *p_dev_enum = NULL;

    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
                           IID_ICreateDevEnum, (void **)&p_dev_enum);

	if(FAILED(hr)) { MMset(m,0,NIL); return 0 ; }

    /* Create an enumerator for the video capture devices */
    IEnumMoniker *p_class_enum = NULL;
	hr = p_dev_enum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &p_class_enum, 0);

    p_dev_enum->Release();
    if(FAILED(hr)) { MMset(m,0,NIL); return 0 ; }

    /* If there are no enumerators for the requested type, then
     * CreateClassEnumerator will succeed, but p_class_enum will be NULL */
    if(p_class_enum == NULL) { MMset(m,0,NIL); return 0 ; }

   /* Enumerate the devices */

    /* Note that if the Next() call succeeds but there are no monikers,
     * it will return S_FALSE (which is not a failure). Therefore, we check
     * that the return code is S_OK instead of using SUCCEEDED() macro. */
	
	int n = 0 ;
	int k;

    while(p_class_enum->Next(1, &p_moniker, &i_fetched) == S_OK)
    {
        /* Getting the property page to get the device name */
        IPropertyBag *p_bag;
        hr = p_moniker->BindToStorage(0, 0, IID_IPropertyBag,
                                       (void **)&p_bag);
        if(SUCCEEDED(hr))
        {
            VARIANT var;
            var.vt = VT_BSTR;
            hr = p_bag->Read(L"FriendlyName", &var, NULL);
            p_bag->Release();
            if(SUCCEEDED(hr))
            {
                int i_convert = WideCharToMultiByte(CP_ACP, 0, var.bstrVal,
                        SysStringLen(var.bstrVal), NULL, 0, NULL, NULL);
                char *p_buf = (char *)malloc(i_convert+1); p_buf[0] = 0;
                WideCharToMultiByte(CP_ACP, 0, var.bstrVal,
                        SysStringLen(var.bstrVal), p_buf, i_convert, NULL, NULL);
                SysFreeString(var.bstrVal);
                p_buf[i_convert] = '\0';

				char *devname = p_buf;

				if (k=Mpushstrbloc(m, p_buf)) return k;
				n++;
            }
        }

        p_moniker->Release();
    }

    p_class_enum->Release();

	if(MMpush(m,NIL))		return MERRMEM;

	for(int j=0;j<n;j++)
	{
		if (MMpush(m,2*2)) return MERRMEM;
		if (k=MBdeftab(m)) return k;
	}


#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////																											   ////
///										DECLARATION DES FONCTIONS POUR SCOL											///
////																											   ////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define NbTplPKG	45


//////////////////////////////////////////////////////////////////////////////////////////////
///		Definition des noms de fonction SCOL
//////////////////////////////////////////////////////////////////////////////////////////////
char	*TplName[NbTplPKG] =
{
	"ObjVlcPlayer",
	"VLC_MEDIAPLAYER_END_REACHED",
	"VLC_MEDIAPLAYER_PAUSED",
	"VLC_MEDIAPLAYER_STOPPED",
	"VLC_MEDIAPLAYER_BUFFERING",
	"VLC_MEDIAPLAYER_POSITION_CHANGED",
	"VLC_MEDIAPLAYER_TIME_CHANGED",
	"VLC_MEDIAPLAYER_FORWARD",
	"VLC_MEDIAPLAYER_BACKWARD",
	"VLC_MEDIAPLAYER_ERROR",

	"VLC_OPENING_STATE",
	"VLC_BUFFERING_STATE",
	"VLC_PLAYING_STATE",
	"VLC_PAUSED_STATE",
	"VLC_STOPPED_STATE",
	"VLC_ENDED_STATE",
	"VLC_ERROR_STATE",
	
	"_crVlcVmenPlayer",
	"_crVlcPlayer",
	"_dsVlcPlayer",
	"_setVlcPlayerFile",
  "_setVlcPlayerUrl",
	"_playVlcPlayer",
	"_pauseVlcPlayer",
	"_stopVlcPlayer",
	"_setVlcPlayerFullScreenState",
	"_getVlcPlayerFullScreenState",
	"_setVlcAudioVolume",
	"_getVlcAudioVolume",
	"_seekVlcPlayer",
	"_getVlcPlayerDuration",
	"_getVlcPlayerPosition",
	"_setVlcPlayerPosition",
	"_getVlcPlayerTime",
	"_setVlcPlayerTime",
	"_cbVlcMediaEvent",
	"_getVlcAudioMute",
	"_setVlcAudioMute",
	"_getVlcPlayerState",
  "_setVlcPlayerLoop",
  "_getVlcPlayerLoop",
	"_saveVlcPlayerSnapShot",
	"_setVlcPlayerWindow",
	"_getVlcVideoDevices",
	"_getVlcAudioDevices"
};




//////////////////////////////////////////////////////////////////////////////////////////////
///		Definition des pointeurs sur fonctions
//////////////////////////////////////////////////////////////////////////////////////////////
int (*TplFunc[NbTplPKG])(mmachine m)=
{
	NULL,
	(scolIntFlag)ITOM(libvlc_MediaPlayerEndReached),		// VLC_MEDIAPLAYER_END_REACHED
	(scolIntFlag)ITOM(libvlc_MediaPlayerPaused),			// VLC_MEDIAPLAYER_PAUSED
	(scolIntFlag)ITOM(libvlc_MediaPlayerStopped),			// VLC_MEDIAPLAYER_STOPPED
	(scolIntFlag)ITOM(libvlc_MediaPlayerBuffering),			// VLC_MEDIAPLAYER_BUFFERING
	(scolIntFlag)ITOM(libvlc_MediaPlayerPositionChanged),	// VLC_MEDIAPLAYER_POSITION_CHANGED
	(scolIntFlag)ITOM(libvlc_MediaPlayerTimeChanged),		// VLC_MEDIAPLAYER_TIME_CHANGED
	(scolIntFlag)ITOM(libvlc_MediaPlayerForward),			// VLC_MEDIAPLAYER_FORWARD
	(scolIntFlag)ITOM(libvlc_MediaPlayerBackward),			// VLC_MEDIAPLAYER_BACKWARD
	(scolIntFlag)ITOM(libvlc_MediaPlayerEncounteredError),	// VLC_MEDIAPLAYER_ERROR

	(scolIntFlag)ITOM(libvlc_Opening),						// VLC_OPENING_STATE
	(scolIntFlag)ITOM(libvlc_Buffering),					// VLC_BUFFERING_STATE
	(scolIntFlag)ITOM(libvlc_Playing),						// VLC_PLAYING_STATE
	(scolIntFlag)ITOM(libvlc_Paused),						// VLC_PAUSED_STATE
	(scolIntFlag)ITOM(libvlc_Stopped),						// VLC_STOPPED_STATE
	(scolIntFlag)ITOM(libvlc_Ended),						// VLC_ENDED_STATE
	(scolIntFlag)ITOM(libvlc_Error),						// VLC_ERROR_STATE
	
	_crVlcVmenPlayer,								
	_crVlcPlayer,										
	_dsVlcPlayer,										
	_setVlcPlayerFile,              
  _setVlcPlayerUrl,               
	_playVlcPlayer,					        
	_pauseVlcPlayer,				        
	_stopVlcPlayer,					        
	_setVlcPlayerFullScreenState,		
	_getVlcPlayerFullScreenState,		
	_setVlcAudioVolume,							
	_getVlcAudioVolume,							
	_seekVlcPlayer,									
	_getVlcPlayerDuration,					
	_getVlcPlayerPosition,					
	_setVlcPlayerPosition,					
	_getVlcPlayerTime,							
	_setVlcPlayerTime,							
	_cbVlcMediaEvent,								
	_getVlcAudioMute,								
	_setVlcAudioMute,								
	_getVlcPlayerState,							
  _setVlcPlayerLoop,
  _getVlcPlayerLoop,
	_saveVlcPlayerSnapShot,					
	_setVlcPlayerWindow,						
	_getVlcVideoDevices,						
	_getVlcAudioDevices							
};



//////////////////////////////////////////////////////////////////////////////////////////////
///		Definition du nombre de paramètres
//////////////////////////////////////////////////////////////////////////////////////////////
int TplNArg[NbTplPKG]=
{
	TYPTYPE,
	TYPVAR,													// VLC_MEDIAPLAYER_END_REACHED
	TYPVAR,													// VLC_MEDIAPLAYER_PAUSED
	TYPVAR,													// VLC_MEDIAPLAYER_STOPPED
	TYPVAR,													// VLC_MEDIAPLAYER_BUFFERING
	TYPVAR,													// VLC_MEDIAPLAYER_POSITION_CHANGED
	TYPVAR,													// VLC_MEDIAPLAYER_TIME_CHANGED
	TYPVAR,													// VLC_MEDIAPLAYER_FORWARD
	TYPVAR,													// VLC_MEDIAPLAYER_BACKWARD
	TYPVAR,													// VLC_MEDIAPLAYER_ERROR

	TYPVAR,													// VLC_OPENING_STATE
	TYPVAR,													// VLC_BUFFERING_STATE
	TYPVAR,													// VLC_PLAYING_STATE
	TYPVAR,													// VLC_PAUSED_STATE
	TYPVAR,													// VLC_STOPPED_STATE
	TYPVAR,													// VLC_ENDED_STATE
	TYPVAR,													// VLC_ERROR_STATE
	
	2,														// _crVlcVmenPlayer
	1,														// _crVlcPlayer
	1,														// _dsVlcPlayer
	2,                            // _setVlcPlayerFile
  2,                            // _setVlcPlayerUrl
	1,                            // _playVlcPlayer
	1,                            // _pauseVlcPlayer
	1,                            // _stopVlcPlayer
	2,														// _setVlcPlayerFullScreenState
	1,														// _getVlcPlayerFullScreenState
	2,														// _setVlcAudioVolume
	1,														// _getVlcAudioVolume
	2,														// _seekVlcPlayer
	1,														// _getVlcPlayerDuration
	1,														// _getVlcPlayerPosition
	2,														// _setVlcPlayerPosition
	1,														// _getVlcPlayerTime
	2,														// _setVlcPlayerTime
	3,														// _cbVlcMediaEvent
	1,														// _getVlcAudioMute
	2,														// _setVlcAudioMute
	1,														// _getVlcPlayerState
  2,                            // _setVlcPlayerLoop
  1,                            // _getVlcPlayerLoop
	4,														// _saveVlcPlayerSnapShot
	2,														// _setVlcPlayerWindow
	0,														// _getVlcVideoDevices
	0														  // _getVlcAudioDevices
};



//////////////////////////////////////////////////////////////////////////////////////////////
///		Definition des grammaires fontionnelles
//////////////////////////////////////////////////////////////////////////////////////////////
char* TplType[NbTplPKG]=
{
	NULL,
	"I",																			// VLC_MEDIAPLAYER_END_REACHED
	"I",																			// VLC_MEDIAPLAYER_PAUSED
	"I",																			// VLC_MEDIAPLAYER_STOPPED
	"I",																			// VLC_MEDIAPLAYER_BUFFERING
	"I",																			// VLC_MEDIAPLAYER_POSITION_CHANGED
	"I",																			// VLC_MEDIAPLAYER_TIME_CHANGED
	"I",																			// VLC_MEDIAPLAYER_FORWARD
	"I",																			// VLC_MEDIAPLAYER_BACKWARD
	"I",																			// VLC_MEDIAPLAYER_ERROR

	"I",																			// VLC_OPENING_STATE
	"I",																			// VLC_BUFFERING_STATE
	"I",																			// VLC_PLAYING_STATE
	"I",																			// VLC_PAUSED_STATE
	"I",																			// VLC_STOPPED_STATE
	"I",																			// VLC_ENDED_STATE
	"I",																			// VLC_ERROR_STATE
	
	"fun [Chn ObjBitmap] ObjVlcPlayer",									// _crVlcVmenPlayer
	"fun [Chn] ObjVlcPlayer",														// _crVlcPlayer
	"fun [ObjVlcPlayer] I",				    								  // _dsVlcPlayer
	"fun [ObjVlcPlayer P] I",														// _setVlcPlayerFile
  "fun [ObjVlcPlayer S] I",														// _setVlcPlayerUrl
	"fun [ObjVlcPlayer] ObjVlcPlayer",				    			// _playVlcPlayer
	"fun [ObjVlcPlayer] ObjVlcPlayer",				    			// _pauseVlcPlayer
	"fun [ObjVlcPlayer] ObjVlcPlayer",				    			// _stopVlcPlayer
	"fun [ObjVlcPlayer I] I",                           // _setVlcPlayerFullScreenState
	"fun [ObjVlcPlayer] I",															// _getVlcPlayerFullScreenState
	"fun [ObjVlcPlayer I] ObjVlcPlayer",							  // _setVlcAudioVolume
	"fun [ObjVlcPlayer] I",															// _getVlcAudioVolume
	"fun [ObjVlcPlayer F] F",														// _seekVlcPlayer
	"fun [ObjVlcPlayer] I",															// _getVlcPlayerDuration
	"fun [ObjVlcPlayer] F",															// _getVlcPlayerPosition
	"fun [ObjVlcPlayer F] F",														// _setVlcPlayerPosition
	"fun [ObjVlcPlayer] I",															// _getVlcPlayerTime
	"fun [ObjVlcPlayer I] I",														// _setVlcPlayerTime
	"fun [ObjVlcPlayer fun [ObjVlcPlayer u0 I] u1 u0] I",							// _cbVlcMediaEvent
	"fun [ObjVlcPlayer] I",															// _getVlcAudioMute
	"fun [ObjVlcPlayer I] ObjVlcPlayer",							  // _setVlcAudioMute
	"fun [ObjVlcPlayer] I",															// _getVlcPlayerState
  "fun [ObjVlcPlayer I] I",														// _setVlcPlayerLoop
	"fun [ObjVlcPlayer] I",															// _getVlcPlayerLoop
	"fun [ObjVlcPlayer W I I] I",												// _saveVlcPlayerSnapShot
	"fun [ObjVlcPlayer ObjWin] ObjVlcPlayer",						// _setVlcPlayerWindow
	"fun [] [S r1]",																// _getVlcVideoDevices
	"fun [] [S r1]"																	// _getVlcAudioDevices
};

// Everything inside _cond and _endcond is ignored by doxygen
//! \cond

/*!
* \brief Load the packages in Scol virtual machine
* \param mmachine : the scol machine
*/
int LoadVlcPlugin(mmachine m)
{
	int			k;

	//MMechostr(0,"\n");
	//MMechostr(0,"*************************    VlcPlugin Support   *************************\n");

	k = PKhardpak(m, "VlcPlugin.pkg", NbTplPKG, TplName, TplFunc, TplNArg, TplType);
	
	OBJ_TYPE_VLC_PLAYER = OBJregister(NB_RFL_VLCMEDIA, 1, destroyVlcPlayer, "OBJ_TYPE_VLC_PLAYER");
	
	VLCMEDIA_EVENT = OBJgetUserEvent();
	OBJdefEvent(VLCMEDIA_EVENT, (int (__cdecl *)(struct Mmachine *,int,unsigned int,int,int,int *))getVlcMediaEvent);
	

	//MMechostr(0,"**********************  Successfully Loaded  **********************\n");
	//MMechostr(0,"\n");

	return k;
}

//! \endcond

/*! 
* \brief Starting point of the DLL
*/
extern "C" __declspec (dllexport) int ScolLoadPlugin(mmachine m, cbmachine w)
{
  // Initializing SDK
 	SCOLinitplugin(w);

	//MMechostr(MSKDEBUG,"SCOLloadVLC trying loading VlcPlugin DLL ...\n");
	LoadVlcPlugin(m);

	return 0;
}

/*! 
* \brief Ending point of the DLL
*/
extern "C" __declspec (dllexport) int ScolUnloadPlugin(){
	MMechostr(MSKDEBUG,"Release VlcPlugin DLL\n");
	VlcSingleton::Kill();
	MMechostr(1, "------ ..VlcPlugin DLL CLOSED\n\n");

	return 0;
}