/***************************************************************************
** Class hirachy ...
**
**
**   QXineWidget            => Found on the web widget ...
**	   |
**	   +-> XineWidget       => implementation of interface to the QXineWidget
**	   |
** MediaInterface	=> pure virtual interface description
**	   |
**	   +-> MPLayerWidget    => implementation of interface to KmpMPlayerWidget
**	   |
**  KmpMPLayerWidget        => Found on the web widget ...
** 
** we have the following class hirarchiy:
**
** QXineWidget : public QWidget, public QThread (Xine player widget found on the web)
** +-> XineWidget : protected QXineWidget, public MediaInterface
**
** KmpMPlayer : public QWidget  (MPlayer player widget found on the web)
** +-> MPlayerWidget : protected KmpMPlayer, public MediaInterface
**
** VLCWindow : public QWidget  (VLC player widget found on the web)
** +-> VLCWidget : protected VLCWindow, public MediaInterface
 ***************************************************************************/
 
#include "mediacreator.h"
#include "../mediascanner.h"
//#include "engines/mediainterface.h" already included in the header ...

// Here we include the header according to the set-up
#include "MEDIA_CONFIG.h"

#if (MPLAYER_SUPPORT == 1)
	#include "engines/mplayerinfo.h"
	#include "engines/mplayerwidget.h"
	#include "engines/qmplayerwidget.h"
#endif
#if (XINE_SUPPORT == 1)
	#include "engines/xineinfo.h"
	#include "engines/xinewidget.h"
	#include "engines/kxinewidget.h"
	#include "engines/qxinewidget.h"
	#include "engines/kaffeineswidget.h"
#endif
#if (VLC_SUPPORT == 1)
	#include "engines/vlcinfo.h"
	#include "engines/vlcwidget.h"
#endif
#include "engines/dummywidget.h"


QString MediaCreator::m_qsPreferredEngine = QString ("QXineWidget");
MediaScanner *MediaCreator::pPreviewObject = NULL;

MediaCreator::MediaCreator () 
{
}

MediaCreator::~MediaCreator () 
{
}

QString MediaCreator::getEngineDescription (QString qsEngineName)
{
	QString qsEngineInfo;
	if (qsEngineName == QString ("DummyWidget"))
		qsEngineInfo = QString ("This class is a empty implementation which does nothing.\n"
		"Choose Xine, MPlayer or VLC instead for some usefull functionality.");
	else if (qsEngineName == QString ("QMPlayerWidget"))
		qsEngineInfo = QString ("Using the MPlayer engine in shell wrappers\n"
		"Note: As of this version of MPlayer you can not display DVDMenus with it.\n"
		"Choose Xine or VLC instead for this task");
	else if (qsEngineName == QString ("QXineWidget"))
		qsEngineInfo = QString ("From an older version of the QDVDAuthor project.\n"
		"This version is working but no longer actively maintained.\n"
		"KXineWidget is preffered over this widget.");
	else if (qsEngineName == QString ("KXineWidget"))
		qsEngineInfo = QString ("From the kaffeine - project.\n"
		"This is the real widget form the kaffeine project and actively maintained.\n"
		"I will try to keep this version in synch with the lates version from kaffeine.");
	else if (qsEngineName == QString ("VLCWidget"))
		qsEngineInfo = QString ("From the Videolan - project.\n"
		"This widget is using the videolan media engine.\n"
		"It is also the least tested media engine in 'Q' DVD-Author.");
	else 
		qsEngineInfo = QString ("Engine <%1> unknown.").arg (qsEngineName);
	return qsEngineInfo;
}

QStringList MediaCreator::getAvailableEngines ()
{
	// Note: 1) The first entry needs to stay the DummyWidget
	//       2) The order will create the best match if the requested engine can not be created
	static QStringList listEngines;
	listEngines.clear();
	listEngines.append(QString("DummyWidget"));	// Dummy interface in case we encounter an error
#if (MPLAYER_SUPPORT == 1)
	listEngines.append(QString("QMPlayerWidget"));	// Self designed Widget -> interface class = MPlayerWidget
#endif
#if (XINE_SUPPORT == 1)
	listEngines.append(QString("KXineWidget"));	// From the kaffeine - project -> interface class = KaffeinesWidget
	listEngines.append(QString("QXineWidget"));	// From an older version of the QDVDAuthor project -> interface class = XineWidget
#endif
#if (VLC_SUPPORT == 1)
	listEngines.append(QString("QVLCWidget"));	// interface class = VLCWidget
#endif
	return listEngines;
}

bool MediaCreator::setPreferredEngine (QString qsPreferredEngine)
{
	QStringList listEngines = MediaCreator::getAvailableEngines();
	bool bFound = false;
	int t=0;
	// Sanity check if the requested engine is supported.
	for (t=0;t<(int)listEngines.count();t++)	{
		if (qsPreferredEngine == listEngines[t])
			bFound = true;
	}
	if (!bFound)	{
		// Here we put som brains into this.
		// SO we can not give the user what he wants
		// Lets check if we have a replacement ...
		m_qsPreferredEngine = listEngines[1];
		// Only if there is no replacement, 
		// then we default to the Dummy no function Widget
		if (listEngines[1] == "")
			m_qsPreferredEngine = listEngines[0];
		printf ("Could not create %s engine, will default to %s\n\n", (const char *)qsPreferredEngine, (const char *)m_qsPreferredEngine);
		return false;
	}
	// All good to set the preferred engine
	m_qsPreferredEngine = qsPreferredEngine;
	return true;
}

QString MediaCreator::preferredEngine ()
{
	return m_qsPreferredEngine;
}

MediaInterface *MediaCreator::createPreferredWidget(QWidget *pParent, const char *pName, void *pExistingEngine)
{
	MediaInterface *pNewInterface = NULL;
	if (m_qsPreferredEngine == QString("QXineWidget"))
		pNewInterface = createXineWidget (pParent, pName, pExistingEngine);
	else if (m_qsPreferredEngine == QString("KXineWidget"))
		pNewInterface = createKXineWidget (pParent, pName, pExistingEngine);
	else if (m_qsPreferredEngine == QString("QMPlayerWidget"))
		pNewInterface = createMPlayerWidget (pParent, pName, pExistingEngine);
	else if (m_qsPreferredEngine == QString("VLCWidget"))
		pNewInterface = createVLCWidget (pParent, pName, pExistingEngine);
	else if (m_qsPreferredEngine == QString("DummyWidget"))
	        pNewInterface = (MediaInterface *) new DummyWidget (pParent, "DummyWidget", pExistingEngine);
	if (!pNewInterface)	{
		printf ("\nError could not create preferred MediaEngine.\nCreate Dummy MediaWidget with no functionality\n\n");
		pNewInterface = (MediaInterface *) new DummyWidget (pParent, "DummyWidget", pExistingEngine);
	}
	return pNewInterface;
}

MediaInterface *MediaCreator::createMPlayerWidget(QWidget *pParent, const char *pName, void *pExistingEngine)
{
	MediaInterface *pMediaInterface = NULL;
	pParent = pParent;
	pName = pName;
	pExistingEngine = pExistingEngine;
#if (MPLAYER_SUPPORT == 1)
	pMediaInterface = (MediaInterface *) new MPlayerWidget (pParent, "MPlayerPart", pExistingEngine);
#endif
	return pMediaInterface;
}

MediaInterface *MediaCreator::createXineWidget(QWidget *pParent, const char *pName, void *pExistingEngine)
{
	MediaInterface *pMediaInterface = NULL;
	pParent = pParent;
	pName = pName;
	pExistingEngine = pExistingEngine;
#if (XINE_SUPPORT == 1)
	pMediaInterface = (MediaInterface *) new XineWidget (pParent, "XineWidget", pExistingEngine);
#endif
	return pMediaInterface;
}

MediaInterface *MediaCreator::createKXineWidget(QWidget *pParent, const char *pName, void *pExistingEngine)
{
	MediaInterface *pMediaInterface = NULL;
	pParent = pParent;
	pName = pName;
	pExistingEngine = pExistingEngine;
#if (XINE_SUPPORT == 1)
	pMediaInterface = (MediaInterface *) new KaffeinesWidget (pParent, "KaffeinesWidget", pExistingEngine);
#endif
	return pMediaInterface;
}

MediaInterface *MediaCreator::createVLCWidget (QWidget *pParent, const char *pName, void *pExistingEngine)
{
	MediaInterface *pMediaInterface = NULL;
	pParent = pParent;
	pName = pName;
	pExistingEngine = pExistingEngine;
#if (VLC_SUPPORT == 1)
	pMediaInterface = (MediaInterface *) new VLCWidget (pParent, "VLCPart", pExistingEngine);
#endif
	return pMediaInterface;
}

MediaInfo *MediaCreator::createInfo(void *pVoid)
{
	MediaInfo *pInfo = NULL;
#if (XINE_SUPPORT == 1)
	if ( (m_qsPreferredEngine == "QXineWidget") || (m_qsPreferredEngine == "KXineWidget") )
		pInfo = (MediaInfo *) new XineInfo (pVoid);
#endif
#if (MPLAYER_SUPPORT == 1)
	if (m_qsPreferredEngine == "QMPlayerWidget")
		pInfo = (MediaInfo *) new MPlayerInfo (pVoid);
#endif
#if (VLC_SUPPORT == 1)
	if (m_qsPreferredEngine == "VLCWidget")
		pInfo = (MediaInfo *) new VLCInfo (pVoid);
#endif
	if (m_qsPreferredEngine == "DummyWidget")
		pInfo = (MediaInfo *) new DummyInfo (pVoid);
	return pInfo;
} 

void MediaCreator::registerWithMediaScanner (QObject *pOrigObject, QString &qsFileName, QImage *pImage, long iMSecondsOffset)
{
	// The first action to take is a sanity check ...
	if ( (!pImage) || (!pOrigObject) )
		return;
	// First we create the ExecuteObject (Container to store the information) 
	ExecuteJob *pNewJob = new ExecuteJob (pOrigObject, qsFileName, pImage, iMSecondsOffset);
	
	// Check if we need to create a new object ...
	if (MediaCreator::pPreviewObject == NULL)
		MediaCreator::pPreviewObject = new MediaScanner;
	else if ((!MediaCreator::pPreviewObject->running()) && (MediaCreator::pPreviewObject->hasFinished()))	{
		// If the object already exist and it has finished running, 
		// THEN delete the old and create a new one
		delete MediaCreator::pPreviewObject;
		MediaCreator::pPreviewObject = new MediaScanner;
	}
	MediaCreator::pPreviewObject->append (pNewJob);
}

void MediaCreator::unregisterFromMediaScanner (QObject *pObject)
{
  if ( MediaCreator::pPreviewObject )
       MediaCreator::pPreviewObject->remove ( pObject );
}

void MediaCreator::unregisterFromMediaScanner (SourceFileInfo *pSourceFileInfo)
{
  if ( MediaCreator::pPreviewObject )
       MediaCreator::pPreviewObject->remove ( pSourceFileInfo );
}

void MediaCreator::registerWithMediaScanner (QObject *pOrigObject, SourceFileInfo *pSourceFileInfo, long iMSecondsOffset, bool bUpdateAllInfo )
{
	// THe first action to take is a sanity check ...
	if ( (!pSourceFileInfo) || (!pOrigObject) )
		return;
	// First we create the ExecuteObject (Container to store the information) 
	ExecuteJob *pNewJob = new ExecuteJob (pOrigObject, pSourceFileInfo, iMSecondsOffset, bUpdateAllInfo );
	
	// Check if we need to create a new object ...
	if (MediaCreator::pPreviewObject == NULL)
		MediaCreator::pPreviewObject = new MediaScanner;
	else if ((!MediaCreator::pPreviewObject->running()) && (MediaCreator::pPreviewObject->hasFinished()))	{
		// If the object already exist and it has finished running, 
		// THEN delete the old and create a new one
		delete MediaCreator::pPreviewObject;
		MediaCreator::pPreviewObject = new MediaScanner;
	}
	MediaCreator::pPreviewObject->append (pNewJob);
}

