/****************************************************************************
** Implementation of class QDVDAuthorInit
**
** Created: Wed Jun 02 07:53:05 2004
**      by: Varol Okan using the kate editor
**
** This class initialises the QDVDAuthor application with the
** last used settings.
**
** It is mainly used, to handle the CommandQueueDialogs options
** which can now be changed by the user.
**
****************************************************************************/

#include "utils.h"
#include "execute.h"
#include "qdvdauthorinit.h"
#include "messagebox.h"
#include "sourcefileentry.h"
#include "dragndropcontainer.h"
#include "qplayer/mediainfo.h"
#include "qplayer/mediacreator.h"
#include "qplayer/MEDIA_CONFIG.h"
 
QDVDAuthorInit::MenuBlock::MenuBlock ()
{ 
	bValid  = false;
	bHidden = false;
	blockMovieBackground.qsBlockTag = QString ( BLOCK_MOVIE_BACKGROUND );
	blockImageBackground.qsBlockTag = QString ( BLOCK_IMAGE_BACKGROUND );
	blockEmptySound.qsBlockTag = QString ( BLOCK_EMPTY_SOUND );
	blockMplex.qsBlockTag  = QString ( BLOCK_MPLEX );
	blockSpumux.qsBlockTag = QString ( BLOCK_SPUMUX );
	blockOthers.qsBlockTag = QString ( BLOCK_OTHERS );
	iKeyset = Keyword::Keys;
};

// o Loading of init file.
// o Saving the MenuBlock stored data back to the ini - file.
// o Saving of default init file.
// o The function to store an init file depending on the users modifications.
// o Added buttons to the CommandQueueDialog (DialogExecute)
// o The function convertSoundFile ()
// o Finalized class requires only bug fixes. 21'st May 2005 (bad weather outside)
//////////////////////////////////////////////////////////////////////////////////////////////

QDVDAuthorInit::QDVDAuthorInit()
{
	initMe();
	m_pDragNDropContainer    = new DragNDropContainer;
	m_bOwnDragNDropContainer = true;
	readIniFile();
}

QDVDAuthorInit::QDVDAuthorInit(DragNDropContainer *pDNDContainer)
{
	initMe();
	m_pDragNDropContainer = pDNDContainer;
	readIniFile();
}

QDVDAuthorInit::QDVDAuthorInit(QValueList<Utils::toolsPaths *> &listPaths, DragNDropContainer *pDNDContainer)
{
	// First we init some data
	initMe();
	// Then we load the current ini - file and set all Internals to those values
	readIniFile();
	// And here we set the dragNDropContainer AFTER laoding to keep the values preserved !
	m_pDragNDropContainer = pDNDContainer;
	// Here we indicate that we do not want to delete the objects when deleting this object ...
	m_bProtectToolsObjects = true;
	// and then we set the paths list to the one we want it to be ...
	setToolsPaths (listPaths);
}

QDVDAuthorInit::~QDVDAuthorInit()
{
  int t;

  for (t=0;t<(int)m_listToBeDeleted.count();t++)
    delete m_listToBeDeleted[t];
  m_listToBeDeleted.clear ();
  m_listExecute.clear ();
  for (t=0;t<(int)m_arrayColors.count();t++)
    delete m_arrayColors[t];
  if (m_bOwnerOfHistoryPix)	{
    // If this flag is not set means that some other object (QDVDAuthor e.g.) is the master of these.
    for (t=0;t<(int)m_listHistoryPix.count();t++)
      delete m_listHistoryPix[t];
    m_listHistoryPix.clear ( );
  }
  // Note: Since we clear the list every time getToolsPaths list is called we can delete 
  //       All objects which are at this time still in the list. 
  if (!m_bProtectToolsObjects)	{
    int  iCount = m_listToolsPaths.count() - 2;
    if ( iCount >= 0 ) {
      for (t=0;t<iCount;t++)
	delete m_listToolsPaths[t];
    }
    m_listToolsPaths.clear ( );
  }
  if ( m_bOwnDragNDropContainer )
    delete m_pDragNDropContainer;
  m_pDragNDropContainer = NULL;
  m_bOwnDragNDropContainer = false;
}

bool QDVDAuthorInit::initMe()
{
	int t;
	Utils theUtils;
	m_iMaxHistoryFiles     = 10;
	m_bOwnerOfHistoryPix   = true;
	m_iAutosave            = 300;
 	m_iColorCounter        = 0;
	m_iCurrentBlockID      = 0;	// To uniquely identify each block of commands ...
	m_bProtectToolsObjects = false;
	m_bVisibleRegion       = false;
	m_qsStyle              = theUtils.currentStyleName ( );

	m_qsTempPath           = Global::qsTempPath + QString ("/") + Global::qsProjectName;
	m_qsProjectPath        = Global::qsProjectPath;
	m_qsDvdauthorFile      = m_qsTempPath + QString ("/") + QString(DVDAUTHOR_XML);
	m_pDragNDropContainer  = NULL;
	m_bOwnDragNDropContainer = false;

	m_bFirstApplicationStart       = false;
	m_convertMenuBlock.qsMenuTag   = QString (TAG_CONVERT);
	m_convertMenuBlock.iKeyset     = Keyword::TransKeys;
	m_subtitlesMenuBlock.qsMenuTag = QString (TAG_SUBTITLES);
	m_subtitlesMenuBlock.iKeyset   = Keyword::SubKeys;
	m_palMenuBlock.qsMenuTag       = QString (TAG_PAL);
	m_ntscMenuBlock.qsMenuTag      = QString (TAG_NTSC);
	m_dvdauthorMenuBlock.qsMenuTag = QString (TAG_DVDAUTHOR);
	m_burningMenuBlock.qsMenuTag   = QString (TAG_BURNING);
	for (t=0;t<(int)m_listToBeDeleted.count()-2;t++)
		delete m_listToBeDeleted[t];
	m_listToBeDeleted.clear ();
	m_listExecute.clear ();

	return true;
}

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

bool QDVDAuthorInit::visibleRegion()
{
	return m_bVisibleRegion;
}

void QDVDAuthorInit::setToolsPaths (QValueList<Utils::toolsPaths *> &listPaths)
{
	// Note: Deletion of the objects in the list only because we know where this function is called from.
	// I.e. every time QDVDAuthorInit is called it'll create a new list and new objects. Thus when setting 
	//      the list manually then we have to get rid of the created Objects.
	uint t;
	if (m_listToolsPaths.count() > 0)	{
		for (t=0;t<m_listToolsPaths.count();t++)
			delete m_listToolsPaths[t];
		m_listToolsPaths.clear();
	}
	m_listToolsPaths = listPaths;
}

QValueList<Utils::toolsPaths *> &QDVDAuthorInit::getToolsPaths ()
{
	static QValueList<Utils::toolsPaths *> listNew;
	listNew = m_listToolsPaths;
	// Note: Here we return the list and reset the member list. 
	// We do this because we want to ensure the objects in this list are
	// created/deleted only once.
	m_listToolsPaths.clear();
	return listNew;
}

void QDVDAuthorInit::mergeToolsPaths (QValueList<Utils::toolsPaths *> listToolsPaths)
{
	// This function will merge the information found in the init file with the information in the 
	// static structure found in global.h
	uint t, i;
	QValueList<Utils::toolsPaths *> newToolsPathsList;
	Utils::toolsPaths *pNewEntry;
	// Okay first we create a fresh and clean list form the static list defined in global.h
	struct structTools {
		char *pExecutableName;
		char *pDisplayName;
		char *pDescription;
	};
	const structTools toolsArray[] = { EXTERNAL_TOOLS };
	uint iNrOfTools = sizeof (toolsArray) / ((sizeof (char *) * 3));
	for (t=0;t<iNrOfTools;t++)	{
		pNewEntry = new Utils::toolsPaths;
		pNewEntry->qsExecutableName = QString (toolsArray[t].pExecutableName);
		newToolsPathsList.append (pNewEntry);
	}
	// then we copy all values over from the current list
	for (t=0;t<newToolsPathsList.count();t++)	{
		for (i=0;i<m_listToolsPaths.count();i++)	{
			if (m_listToolsPaths[i]->qsExecutableName == newToolsPathsList[t]->qsExecutableName)	{
				newToolsPathsList[t]->qsFullPath = m_listToolsPaths[i]->qsFullPath;
				newToolsPathsList[t]->bPresent = m_listToolsPaths[i]->bPresent;
				i = m_listToolsPaths.count();
			}
		}
	}
	// finally we copy all values over found in the ini file list ...
	for (t=0;t<listToolsPaths.count();t++)	{
		for (i=0;i<newToolsPathsList.count();i++)	{
			if (newToolsPathsList[i]->qsExecutableName == listToolsPaths[t]->qsExecutableName)	{
				newToolsPathsList[i]->qsFullPath = listToolsPaths[t]->qsFullPath;
				i = newToolsPathsList.count();
			}
		}
	}
	// And at the end we check if the executable exists in the place specified ...
	QString qsPath;
	QFileInfo fileInfo;
	for (t=0;t<newToolsPathsList.count();t++)	{
		fileInfo.setFile(newToolsPathsList[t]->qsFullPath);
		if (newToolsPathsList[t]->qsExecutableName == QString ("bash")) {
			if ( newToolsPathsList[t]->qsFullPath.isEmpty () ||  newToolsPathsList[t]->qsFullPath == "bash" )
				Global::qsBashString = QString ("#!/bin/bash\n\n");
			else
				Global::qsBashString = QString ("#!%1 \n\n").arg(newToolsPathsList[t]->qsFullPath);
		}
		if (fileInfo.exists())
			newToolsPathsList[t]->bPresent = true;
		else
			newToolsPathsList[t]->bPresent = false;
	}
	// Okay now we can delete the entries in the current list ...
	for (t=0;t<m_listToolsPaths.count();t++)
		delete m_listToolsPaths[t];
	m_listToolsPaths.clear ();
	// now copy the new list over and make it the current list
	m_listToolsPaths = newToolsPathsList;
	// Done here, lets go home ...
}

QStringList QDVDAuthorInit::getHistory ()
{
	return m_listHistory;
}

QValueList<QPixmap *> QDVDAuthorInit::getHistoryPix ()
{
	// This flag indicates that we moved all Pixmaps to the caller.
	m_bOwnerOfHistoryPix = false;
	return m_listHistoryPix;
}

int QDVDAuthorInit::maxHistoryFiles ()
{
	return m_iMaxHistoryFiles;
}

void QDVDAuthorInit::setStyle (QString qsStyle)
{
	m_qsStyle = qsStyle;
}

QString QDVDAuthorInit::getStyle ()
{
	return m_qsStyle;
}

void QDVDAuthorInit::setTemplateAuthor ( QString &qsAuthor )
{
  m_qsTemplateAuthor = qsAuthor;
}

QString &QDVDAuthorInit::getTemplateAuthor ( )
{
  return m_qsTemplateAuthor;
}

void QDVDAuthorInit::setTemplateContact ( QString &qsContact )
{
  m_qsTemplateContact = qsContact;
}

QString &QDVDAuthorInit::getTemplateContact ( )
{
  return m_qsTemplateContact;
}

int QDVDAuthorInit::getAutosave ()
{
	return m_iAutosave;
}

void QDVDAuthorInit::setAutosave (int iAutosave)
{
	m_iAutosave = iAutosave;
}

bool QDVDAuthorInit::firstApplicationStart ( ) 
{
  return m_bFirstApplicationStart;
}

void QDVDAuthorInit::setVisibleRegion (bool bVisibleRegion)
{
	m_bVisibleRegion = bVisibleRegion;
}

void QDVDAuthorInit::setHistory (int iMaxHistoryFiles, QStringList listHistory, QValueList<QPixmap *> listHistoryPix)
{
	m_iMaxHistoryFiles   = iMaxHistoryFiles;
	m_listHistory        = listHistory;
	m_listHistoryPix     = listHistoryPix;
	m_bOwnerOfHistoryPix = false;
}

bool QDVDAuthorInit::readIniFile ()
{
	// This function reads in the xml - init - file for 'Q' DVD-Author and
	// generates the neccesary data structures to be used by appendMenu.
	float fStoredVersion;
	int iReturn;
	QString qsChildTag;
	uint t, i, k;
	// Assign the file
	QString qsInitFile = QDir::homeDirPath();
	qsInitFile.append(INIT_DIR_NAME);
	QDir iniDir (qsInitFile);
	if (!iniDir.exists())
		iniDir.mkdir (qsInitFile);

	qsInitFile.append(INIT_FILE_NAME);
	QFile initFile(qsInitFile);
	if (!initFile.open(IO_ReadWrite))
		return false;

	QDomDocument xmlDoc( INIT_DOCTYPE );
	if (!xmlDoc.setContent (&initFile))	{
		// Error handling ...
		initFile.close();

		iReturn = MessageBox::warning ( NULL, QObject::tr ("QDVDAuthor - init file seems to be defective."),
			   QObject::tr ("The file %1%2 seems  to have a problem. Do you want to reset this file ?").arg(INIT_DIR_NAME).arg(INIT_FILE_NAME),
			   QMessageBox::Yes|QMessageBox::Default, QMessageBox::No|QMessageBox::Escape );
		if (iReturn == QMessageBox::Yes)	{
			resetInitFile ();
			return initMe ();
		}
	}
	// And at last lets try to read the information of the file.
	QDomElement docElem = xmlDoc.documentElement();
	// Sanity check ...
	if (docElem.tagName() != QString (TAG_INIT))
		return false;

	QDomAttr a = docElem.attributeNode ( ATTRIB_VERSION );
	fStoredVersion = a.value().toFloat();
	a = docElem.attributeNode ( ATTRIB_STYLE );
	if (!a.value().isEmpty())
		m_qsStyle = a.value();
	a = docElem.attributeNode ( ATTRIB_LANGUAGE );
	if (!a.value().isEmpty())
	  Global::qsLanguage = a.value();
	a = docElem.attributeNode ( ATTRIB_FIRST_START );
	if (!a.value().isEmpty())
	  m_bFirstApplicationStart = (bool) a.value().toInt ();
	a = docElem.attributeNode ( ATTRIB_VISIBLE_REGION );
	m_bVisibleRegion = false;
	if (a.value() == QString ("true"))
		m_bVisibleRegion = true;
	a = docElem.attributeNode ( ATTRIB_MAX_HISTORY );
	if (a.value().toInt() > 0)
		m_iMaxHistoryFiles = a.value().toInt();
	a = docElem.attributeNode ( ATTRIB_MAX_THREADS );
	if (a.value().toInt() > -1)
		Global::iMaxRunningThreads = a.value().toInt();
	a = docElem.attributeNode ( ATTRIB_DELETE_OLDER_THAN );
	Global::iDeleteTempOlderThan = a.value().toInt();
	a = docElem.attributeNode ( ATTRIB_AUTOSAVE );
	if (a.value().toInt() > 0)
		m_iAutosave = a.value().toInt();
	if (fStoredVersion > (float)INIT_VERSION)	{
		iReturn = MessageBox::warning ( NULL, QObject::tr ("QDVDAuthor - init file is newer than the current version of 'Q' DVD-Author."),
			QObject::tr ("The file %1%2 was created with a more recent version.\nThis could lead to problems.\nDo you want to reset this file ?").arg(INIT_DIR_NAME).arg(INIT_FILE_NAME),
			QMessageBox::Yes, QMessageBox::No);
		if (iReturn == QMessageBox::Yes)	{
			resetInitFile ();
			return initMe ();
		}
	}
	else if (fStoredVersion < (float)INIT_VERSION)	{
		// Here we tell the user and then reset the initfile.
		iReturn = MessageBox::warning ( NULL, QObject::tr ("QDVDAuthor - init file is outdated."),
			QObject::tr ("The file %1%2 was created with an older version of 'Q' DVD-Author.\nThis could lead to problems.\n\nDo you want to reset this file ?").arg(INIT_DIR_NAME).arg(INIT_FILE_NAME),
			QMessageBox::Yes, QMessageBox::No);
		if (iReturn == QMessageBox::Yes)	{
			resetInitFile ();
			return initMe ();
		}
	}

	// Here we get the next step in the tree down ... ExecuteInterface
	QStringList listCommands;
	QValueList<QString> listColors;
	QValueList<int>     listOrder;
	QDomNode xmlNode;
	QDomElement childElem;
	QValueList<Utils::toolsPaths *> listToolsPaths;
	QDVDAuthorInit::MenuBlock::SubBlock *pSubBlock;
	QDVDAuthorInit::MenuBlock::Block *pSubSubBlock;
	QDomNode xmlExecuteInterfaceNode = docElem.firstChild();
	bool bHidden;
	MenuBlock *pMenuBlock;
	m_listHistory.clear ();
	m_iCurrentBlockID = 0;
	// Okay
	listCommands.clear();
	while (!xmlExecuteInterfaceNode.isNull())	{
		bHidden = false;
		childElem  = xmlExecuteInterfaceNode.toElement ( );
		qsChildTag = childElem.tagName ( );
		if (qsChildTag == QString(TAG_EXECUTE))	{
			// Correctly detects a ExecuteInterface - tag
			// So lets get the only attribute for ExecuteInterface
			a = childElem.attributeNode ( ATTRIB_HIDDEN );
			if (a.value() == QString ("true"))
				bHidden = true;
			// Here we get the next step in the tree down ... Pal, or Ntsc or Dvdauthor or Burning
			xmlNode = childElem.firstChild();
			while (!xmlNode.isNull())	{
				childElem  = xmlNode.toElement ( );
				qsChildTag = childElem.tagName ( );
				pMenuBlock = NULL;
				if (qsChildTag == QString (TAG_CONVERT))
					pMenuBlock = &m_convertMenuBlock;
				if (qsChildTag == QString (TAG_SUBTITLES))
					pMenuBlock = &m_subtitlesMenuBlock;
				else if (qsChildTag == QString (TAG_PAL))
					pMenuBlock = &m_palMenuBlock;
				else if (qsChildTag == QString (TAG_NTSC))
					pMenuBlock = &m_ntscMenuBlock;
				else if (qsChildTag == QString (TAG_DVDAUTHOR))
					pMenuBlock = &m_dvdauthorMenuBlock;
				else if (qsChildTag == QString (TAG_BURNING))
					pMenuBlock = &m_burningMenuBlock;
				if (!pMenuBlock)
					continue;
				if (!readMenuBlock (pMenuBlock, &childElem))
					return false;
				pMenuBlock->bHidden = bHidden;
				xmlNode = xmlNode.nextSibling();
			}
		}
		else if (qsChildTag == QString(TAG_PREFERRED_ENGINE))
			m_qsPreferredEngine = childElem.text();
		else if (qsChildTag == QString(TAG_TEMPLATE_AUTHOR))
			m_qsTemplateAuthor = childElem.text();
		else if (qsChildTag == QString(TAG_TEMPLATE_CONTACT))
			m_qsTemplateContact = childElem.text();
		else if (qsChildTag == QString(TAG_EXTERNAL_PLAYER))
			Global::qsExternalPlayer = childElem.text();
		else if (qsChildTag == QString(TAG_COLOR))	{
			QDomAttr a = childElem.attributeNode ( ATTRIB_NUMBER );
			listOrder.append(a.value().toInt());
			listColors.append(childElem.text());
			m_arrayColors.append(new QColor());
		}
		else if (qsChildTag == QString(TAG_PATH))	{
			QDomAttr a = childElem.attributeNode ( ATTRIB_NAME );
			Utils::toolsPaths *pPath = new Utils::toolsPaths;
			pPath->qsFullPath = childElem.text();
			pPath->qsExecutableName = a.value ();
			listToolsPaths.append(pPath);
		}
		else if (qsChildTag == QString(TAG_HISTORY))	{
			QPixmap *pPixmap = new QPixmap;
			Utils theUtil;
			QDomAttr a = childElem.attributeNode ( ATTRIB_NAME );
			QString qsImage = childElem.text();
			pPixmap->load (qsImage);
			m_listHistory.append(a.value());
			m_listHistoryPix.append(pPixmap);
/* The original version when we stored the images in the ini - file.
			QPixmap *pPixmap = new QPixmap;
			Utils theUtil;
			QDomAttr a = childElem.attributeNode ( ATTRIB_NAME );
			QString qsImage = childElem.text();
			m_listHistory.append(a.value());
			m_listHistoryPix.append(pPixmap);
			// And now we convert the string to a QImage - object
			QImage theImage = theUtil.convertStringToImage (qsImage);
			pPixmap->convertFromImage(theImage);
*/
		}
		else if (qsChildTag == QString(TAG_DRAGNDROP))	{
			if (m_pDragNDropContainer)	{
				DragNDropContainer *p = m_pDragNDropContainer;
				int iSizeWidth, iSizeHeight;
				// Here we add the DragNDrop - stuff to the init - file ...
				QDomAttr a = childElem.attributeNode ( ATTRIB_DND_THUMBNAIL );
				// The size is something like 50x50 so we ought to split
				int iXPos = a.value().find ("x");
				if (iXPos)	{
					iSizeWidth  = a.value().left(iXPos).toInt();
					iSizeHeight = a.value().right(a.value().length()-iXPos-1).toInt();
					if (iSizeWidth && iSizeHeight)
						p->sizeThumbnail = QSize (iSizeWidth, iSizeHeight);
				}

				a = childElem.attributeNode ( ATTRIB_DND_BUTTON );
				// The size is something like 50x50 so we ought to split
				iXPos = a.value().find ("x");
				if (iXPos)	{
					iSizeWidth  = a.value().left(iXPos).toInt();
					iSizeHeight = a.value().right(a.value().length()-iXPos-1).toInt();
					if (iSizeWidth && iSizeHeight)
						p->sizeButton = QSize (iSizeWidth, iSizeHeight);
				}
				a = childElem.attributeNode ( ATTRIB_DND_BUTTON_TYPE );
				p->bImageButton = a.value().toInt();

				a = childElem.attributeNode ( ATTRIB_DND_WITH_TEXT );
				p->bWithText = a.value().toInt();

				a = childElem.attributeNode ( ATTRIB_DND_TEXT_POS );
				p->iTextPosition = a.value().toInt();

				a = childElem.attributeNode ( ATTRIB_DND_START );
				if (!a.value().isNull())
					p->timeStartOffset = QTime::fromString(a.value());

				a = childElem.attributeNode ( ATTRIB_DND_DURATION );
				if (!a.value().isNull())
					p->timeDuration = QTime::fromString (a.value());

				a = childElem.attributeNode ( ATTRIB_DND_COLOR );
				p->colorForeground.setNamedColor(a.value());

				a = childElem.attributeNode ( ATTRIB_DND_START_WHEN );
				p->bStartAfterDropEvent = true;
				if (a.value() == QString ("false"))
					p->bStartAfterDropEvent = false;

				a = childElem.attributeNode ( ATTRIB_DND_NICE );
				p->iHowNiceShouldIBe = a.value().toInt();

				QDomElement fontElem = xmlExecuteInterfaceNode.toElement();
				if (fontElem.firstChild().toElement().tagName() == QString(TAG_FONT))
					p->font.fromString(fontElem.text());
			}
		}
		// Get the next "ExecuteInterface"
		xmlExecuteInterfaceNode = xmlExecuteInterfaceNode.nextSibling();
	}

	// Okay, next we sort out the colors ...
	for (t=0;t<m_arrayColors.count();t++)
		m_arrayColors[listOrder[t]]->setNamedColor(listColors[t]);

	// Next we take care that the tools we loaded are a tight fit for this program on this computer with the version of QDVDAuthor.
	mergeToolsPaths ( listToolsPaths );
	// Okay, we can get rid of all entries in the list we got form the ini - file ...
	for (t=0;t<listToolsPaths.count();t++)
		delete listToolsPaths[t];

	// Next in order to create the dvdauthor, and burn - block we need some data in the keywords to be used in resolvString()
	m_keyword.clear    ( Keyword::Keys );
	m_keyword.setValue ( Keyword::Keys, Keyword::KeyDVDAuthorXML, m_qsDvdauthorFile ); // +DVDAUTHOR_XML+
	m_keyword.setValue ( Keyword::Keys, Keyword::KeyProjectPath,  m_qsProjectPath );   // +PROJECT_PATH+
	m_keyword.setValue ( Keyword::Keys, Keyword::KeyTempPath,     m_qsTempPath );      // +TEMP_PATH+

	listCommands.clear ();
	// And finally we get the information for the dvdauthor block, and the burning block ...
	m_dvdauthorInterface.qsBlockName = m_keyword.resolvString( Keyword::Keys, m_dvdauthorMenuBlock.qsBlockName);
	m_dvdauthorInterface.backgroundColor = m_dvdauthorMenuBlock.colorBackground;
	for (t=0;t<m_dvdauthorMenuBlock.blockOthers.listComments.count();t++)
	  m_dvdauthorInterface.commentList.append( m_keyword.resolvString( Keyword::Keys, m_dvdauthorMenuBlock.blockOthers.listComments[t] ) );
	for (t=0;t<m_dvdauthorMenuBlock.blockOthers.listCommands.count();t++)
	  listCommands.append ( m_keyword.resolvString( Keyword::Keys, m_dvdauthorMenuBlock.blockOthers.listCommands[t] ) );
	m_dvdauthorInterface.listCommandList.append(listCommands);
	m_dvdauthorInterface.listDefaults.append(m_dvdauthorMenuBlock.blockOthers.iDefaultCommand);
	m_dvdauthorInterface.bShowBlock = !m_dvdauthorMenuBlock.bHidden;
	m_dvdauthorInterface.listBlockIDs.append (m_dvdauthorMenuBlock.blockOthers.iBlockID);

	listCommands.clear ();
	m_burnInterface.qsBlockName = m_keyword.resolvString( Keyword::Keys, m_burningMenuBlock.qsBlockName);
	m_burnInterface.backgroundColor = m_burningMenuBlock.colorBackground;
	m_burnInterface.bShowBlock = !m_burningMenuBlock.bHidden;
	for (i=0;i<m_burningMenuBlock.blockOthers.listSubBlocks.count();i++)	{
		pSubBlock = m_burningMenuBlock.blockOthers.listSubBlocks[i];
		for (t=0;t<pSubBlock->listBlocks.count();t++)	{
			pSubSubBlock = pSubBlock->listBlocks[t];
			for (k=0;k<pSubSubBlock->listComments.count ();k++)  
			  m_burnInterface.commentList.append( m_keyword.resolvString( Keyword::Keys, pSubSubBlock->listComments[k] ) );
			for (k=0;k<pSubSubBlock->listCommands.count ();k++)
			  listCommands.append ( m_keyword.resolvString( Keyword::Keys, pSubSubBlock->listCommands[k] ) );
			m_burnInterface.listBlockIDs.append (pSubSubBlock->iBlockID );
			m_burnInterface.listCommandList.append(listCommands);
			m_burnInterface.listDefaults.append(pSubSubBlock->iDefaultCommand);
			listCommands.clear ();
		}
	}

	return true;
}

bool QDVDAuthorInit::saveIniFile ()
{
	uint t;
	// This function writes in the xml - init - file for 'Q' DVD-Author.
	// the input for the file is taken from the structure stored in this class
	// and alsoo from the uses input.
	
	// Assign the file
	QString qsInitFile = QDir::homeDirPath();
	qsInitFile.append(INIT_DIR_NAME);
	qsInitFile.append(INIT_FILE_NAME);

	QFile initFile(qsInitFile);
	if (!initFile.open(IO_WriteOnly))
		return false;

	QDomDocument xmlDoc( INIT_DOCTYPE );
	// Okay the document is set, now let us write into the document ...
	QDomElement rootInit = xmlDoc.createElement( TAG_INIT );	// <QDVDAuthorInitFile>
	rootInit.setAttribute( ATTRIB_VERSION, QString ("%1").arg((float)INIT_VERSION));
	rootInit.setAttribute( ATTRIB_STYLE, m_qsStyle);
	rootInit.setAttribute( ATTRIB_LANGUAGE, Global::qsLanguage);
	if ( m_bFirstApplicationStart )
	  rootInit.setAttribute( ATTRIB_FIRST_START, (int)m_bFirstApplicationStart);
	QString qsVisibleRegion ("false");
	if (m_bVisibleRegion)
		qsVisibleRegion = QString("true");
	rootInit.setAttribute( ATTRIB_VISIBLE_REGION, qsVisibleRegion);
	rootInit.setAttribute( ATTRIB_MAX_HISTORY, QString ("%1").arg(m_iMaxHistoryFiles));
	rootInit.setAttribute( ATTRIB_AUTOSAVE, QString ("%1").arg(m_iAutosave));
	rootInit.setAttribute( ATTRIB_MAX_THREADS, QString ("%1").arg(Global::iMaxRunningThreads));
	rootInit.setAttribute( ATTRIB_DELETE_OLDER_THAN, QString ("%1").arg(Global::iDeleteTempOlderThan));

	xmlDoc.appendChild( rootInit );
	
	QDomElement preferredElement = xmlDoc.createElement( TAG_PREFERRED_ENGINE );	// <PreferredEngine>
	QDomText domText = xmlDoc.createTextNode (MediaCreator::preferredEngine());
	preferredElement.appendChild( domText );
	rootInit.appendChild ( preferredElement );
	
	QDomElement externalElement = xmlDoc.createElement( TAG_EXTERNAL_PLAYER );	// <ExternalPlayer>
	domText = xmlDoc.createTextNode (Global::qsExternalPlayer);
	externalElement.appendChild( domText );
	rootInit.appendChild ( externalElement );

	QDomElement templateAuthor = xmlDoc.createElement( TAG_TEMPLATE_AUTHOR );	// <TemplateAuthor>
	domText = xmlDoc.createTextNode ( m_qsTemplateAuthor );
	templateAuthor.appendChild( domText );
	rootInit.appendChild ( templateAuthor );
	
	QDomElement templateContact = xmlDoc.createElement( TAG_TEMPLATE_CONTACT );	// <TemplateContact>
	domText = xmlDoc.createTextNode ( m_qsTemplateContact );
	templateContact.appendChild( domText );
	rootInit.appendChild ( templateContact );
	
	// First things first ... the color table ...
	for (t=0;t<m_arrayColors.count();t++)	{
		QDomElement colorElement = xmlDoc.createElement( TAG_COLOR );	// <Color>
		domText = xmlDoc.createTextNode (m_arrayColors[t]->name());
		colorElement.setAttribute( ATTRIB_NUMBER, QString ("%1").arg(t));
		colorElement.appendChild( domText );
		rootInit.appendChild ( colorElement );
	}
	for (t=0;t<m_listToolsPaths.count();t++)	{
		QDomElement pathElement = xmlDoc.createElement( TAG_PATH );	// <Path>
		domText = xmlDoc.createTextNode (m_listToolsPaths[t]->qsFullPath);
		pathElement.setAttribute( ATTRIB_NAME, m_listToolsPaths[t]->qsExecutableName);
		pathElement.appendChild( domText );
		rootInit.appendChild ( pathElement );
	}
	for (t=0;t<m_listHistory.count();t++)	{
		QString qsFileName = QDir::homeDirPath() + QString (INIT_DIR_NAME) + QString ("history%1.png").arg (t);
		m_listHistoryPix[t]->save(qsFileName, "PNG", 100);
		QDomElement historyElement = xmlDoc.createElement( TAG_HISTORY );	// <History>
		domText = xmlDoc.createTextNode (qsFileName);
		historyElement.setAttribute( ATTRIB_NAME, m_listHistory[t]);
		historyElement.appendChild( domText );
		rootInit.appendChild ( historyElement );
/* The original code when we had the images stored in the ini file itself.
		Utils theUtil;
		QImage theImage = m_listHistoryPix[t]->convertToImage();
		QDomElement historyElement = xmlDoc.createElement( TAG_HISTORY );	// <History>
		domText = xmlDoc.createTextNode (theUtil.convertImageToString(theImage));
		historyElement.setAttribute( ATTRIB_NAME, m_listHistory[t]);
		historyElement.appendChild( domText );
		rootInit.appendChild ( historyElement );
*/
	}
	// Here we add the DragNDrop - stuff to the init - file ...
	DragNDropContainer *p = m_pDragNDropContainer;
	if ( p ) {
	  QDomElement dndElement  = xmlDoc.createElement( TAG_DRAGNDROP );  // <DragNDrop>
	  QDomElement fontElement = xmlDoc.createElement( TAG_FONT );       // <Font>
	  domText = xmlDoc.createTextNode (p->font.toString());
	  dndElement.setAttribute( ATTRIB_DND_THUMBNAIL  , QString ("%1x%2").arg(p->sizeThumbnail.width()).arg(p->sizeThumbnail.height()));
	  dndElement.setAttribute( ATTRIB_DND_BUTTON     , QString ("%1x%2").arg(p->sizeButton.width()).arg(p->sizeButton.height()));
	  dndElement.setAttribute( ATTRIB_DND_BUTTON_TYPE, QString ("%1").arg(p->bImageButton));
	  dndElement.setAttribute( ATTRIB_DND_WITH_TEXT  , QString ("%1").arg(p->bWithText));
	  dndElement.setAttribute( ATTRIB_DND_TEXT_POS   , QString ("%1").arg(p->iTextPosition));
	  dndElement.setAttribute( ATTRIB_DND_START      , QString ("%1").arg(p->timeStartOffset.toString(Qt::TextDate)));
	  dndElement.setAttribute( ATTRIB_DND_DURATION   , QString ("%1").arg(p->timeDuration.toString(Qt::TextDate)));
	  dndElement.setAttribute( ATTRIB_DND_COLOR      , QString ("%1").arg(p->colorForeground.name()));
	  dndElement.setAttribute( ATTRIB_DND_START_WHEN , QString ("%1").arg(p->bStartAfterDropEvent ? "true" : "false"));
	  dndElement.setAttribute( ATTRIB_DND_NICE       , QString ("%1").arg(p->iHowNiceShouldIBe));

	  fontElement.appendChild( domText );
	  dndElement.appendChild ( fontElement );
	  rootInit.appendChild   ( dndElement );
	}

	// Next are the ExecuteInterface's The convert goes first bien sur ...
	QDomElement convertElement = xmlDoc.createElement( TAG_EXECUTE );	// <ExecuteInterface>
	saveMenuBlock (&m_convertMenuBlock,  &convertElement);
	rootInit.appendChild ( convertElement );

	// Next are the ExecuteInterface's Second is the Subtitles ...
	//	QDomElement subtitlesElement = xmlDoc.createElement( TAG_SUBTITLES );	// <ExecuteInterface>
	saveMenuBlock (&m_subtitlesMenuBlock,  &convertElement);
	//	rootInit.appendChild ( subtitlesElement );

	// Next are the ExecuteInterface's Third are the menus ...
	QDomElement executeElement = xmlDoc.createElement( TAG_EXECUTE );	// <ExecuteInterface>
	saveMenuBlock (&m_palMenuBlock,  &executeElement);
	saveMenuBlock (&m_ntscMenuBlock, &executeElement);
	rootInit.appendChild ( executeElement );
	
	QDomElement dvdauthorElement = xmlDoc.createElement( TAG_EXECUTE );	// <ExecuteInterface>
	saveMenuBlock (&m_dvdauthorMenuBlock, &dvdauthorElement);
	rootInit.appendChild ( dvdauthorElement );

	QDomElement burnElement = xmlDoc.createElement( TAG_EXECUTE );	// <ExecuteInterface>
	saveMenuBlock (&m_burningMenuBlock, &burnElement);
	rootInit.appendChild ( burnElement );

	// And finally we will store the generated string into the init file ...
	QString xml = xmlDoc.toString ();
//printf ("%s", (const char *)xml);
	initFile.writeBlock(xml, qstrlen (xml));

	initFile.close();
	return true;
}

bool QDVDAuthorInit::readMenuBlock (MenuBlock *pMenuBlock, QDomElement *pElem)
{
	QString qsBlockName,qsTemp;
	MenuBlock::Block *pBlock;
	// This function reads in a MenuBlock (with multiple sub-Block)
	// First we get the attributes ...
	QDomAttr a = pElem->attributeNode ( ATTRIB_BLOCKNAME );
	pMenuBlock->qsBlockName = a.value();
	a = pElem->attributeNode ( ATTRIB_COLOR );
	pMenuBlock->colorBackground.setNamedColor(a.value());
	// Next we parse through the associated Blocks.
	QDomNode xmlNode = pElem->firstChild ();

	while (!xmlNode.isNull())	{
		QDomElement searchTree = xmlNode.toElement();
		if (searchTree.tagName() == QString (TAG_BLOCK) )	{
			pBlock = &pMenuBlock->blockOthers;
			// get the name of this block ...
			qsBlockName = searchTree.attributeNode ( ATTRIB_NAME ).value();
			if (qsBlockName == QString (BLOCK_MOVIE_BACKGROUND))
				pBlock = &pMenuBlock->blockMovieBackground;
			else if  (qsBlockName == QString (BLOCK_IMAGE_BACKGROUND))
				pBlock = &pMenuBlock->blockImageBackground;
			else if  (qsBlockName == QString (BLOCK_EMPTY_SOUND))
				pBlock = &pMenuBlock->blockEmptySound;
			else if  (qsBlockName == QString (BLOCK_MPLEX))
				pBlock = &pMenuBlock->blockMplex;
			else if  (qsBlockName == QString (BLOCK_SPUMUX))
				pBlock = &pMenuBlock->blockSpumux;
			if (!readBlock (pBlock, &searchTree)) 
				return false;
		}
		qsBlockName = searchTree.attributeNode ( ATTRIB_NAME ).value();

		xmlNode = xmlNode.nextSibling();
	}
	return true;
}

bool QDVDAuthorInit::readBlock (MenuBlock::Block *pBlock, QDomElement *pElem)
{
	// This function reads in the information of a Block.
	// It is a recursive function as for the listSubBlocks.
	int iCommandNumber = 0;
	MenuBlock::SubBlock *pSubBlock;
	QString qsTemp;
	QDomAttr a;
	// and now we dwelve into reading the rest of the fest ...
	qsTemp = pElem->attributeNode(ATTRIB_NAME).value ();
	if ((!qsTemp.isNull()) && (!qsTemp.isEmpty()) )
		pBlock->qsBlockTag = qsTemp;
	a = pElem->attributeNode(ATTRIB_ACTIVE);
	if (a.value() == QString ("true"))
		pBlock->iActive = 1;
	else if (a.value() == QString ("false"))
		pBlock->iActive = 0;
	pBlock->iBlockID = m_iCurrentBlockID ++;
	a = pElem->attributeNode(ATTRIB_HIDDEN);
	pBlock->bHidden = false;
	if (a.value() == QString ("true"))
		pBlock->bHidden = true;
	a = pElem->attributeNode(ATTRIB_EDITABLE);
	pBlock->bEditable = false;
	if (a.value() == QString ("true"))
		pBlock->bEditable = true;

	QDomNode xmlNode = pElem->firstChild();
	while (!xmlNode.isNull())	{
		QDomElement searchTree = xmlNode.toElement();
		if (searchTree.tagName() == QString (TAG_COMMAND))	{
			a = searchTree.attributeNode(ATTRIB_DEFAULT);
			if (a.value() == QString ("true"))
				pBlock->iDefaultCommand = iCommandNumber;
			pBlock->listCommands.append (searchTree.text());
			iCommandNumber ++;
		}
		else if (searchTree.tagName() == QString (TAG_COMMENT)) 	{
			pBlock->listComments.append(searchTree.text());
		}
		else if (searchTree.tagName() == QString (TAG_SUBBLOCK)) 	{
			// Next we go through the subNodes.
			QDomNode subNode = searchTree.firstChild();
			// Every SubBlock needs a block
			pSubBlock = new MenuBlock::SubBlock;
			while (! subNode.isNull() )	{
				// and now we dwelve into reading the rest of the fest ...
				QDomElement subTree = subNode.toElement();
				// Here we check if the SubBlock has another BLOCK inside.
				if (!readSubBlock (pSubBlock, &subTree))
					return false;

				subNode = subNode.nextSibling();
			}
			pBlock->listSubBlocks.append (pSubBlock);
		}
		else 
			fprintf (stderr, "%s : %d : wrong nodeTag=<%s>\n", 
				__FILE__, __LINE__, (const char *)searchTree.tagName());//return false;
		xmlNode = xmlNode.nextSibling();
	}

 	return true;
}

bool QDVDAuthorInit::readSubBlock (MenuBlock::SubBlock *pSubBlock, QDomElement *pElem)
{
	// This function reads in the information of a Block.
	// It is a recursive function as for the listSubBlocks.
	MenuBlock::Block *pBlock;
	QString qsTemp;
	QDomAttr a;
	// and now we dwelve into reading the rest of the fest ...
	qsTemp = pElem->attributeNode(ATTRIB_NAME).value ();
	if ((!qsTemp.isNull()) && (!qsTemp.isEmpty()) )
		pSubBlock->qsName = qsTemp;
	a = pElem->attributeNode(ATTRIB_NUMBER);
	if (a.value() == QString ("true"))
	  pSubBlock->iNumber = a.value().toInt();

	if (pElem->tagName() == QString (TAG_BLOCK)) 	{
		// Next we go through the subNodes.
		// Every SubBlock needs a block
		pBlock = new MenuBlock::Block;
		// and now we dwelve into reading the rest of the fest ...
		if (!readBlock (pBlock, pElem))
			return false;

		pSubBlock->listBlocks.append (pBlock);
	}
	else
		fprintf (stderr, "%s : %d : wrong nodeTag=<%s>\n", 
			__FILE__, __LINE__, (const char *)pElem->tagName());//return false;
	return true;
}

bool QDVDAuthorInit::saveMenuBlock (MenuBlock *pMenuBlock, QDomElement *pElement)
{
	if (pMenuBlock->bHidden)
		pElement->setAttribute( ATTRIB_HIDDEN, QString ("true") );
	QDomDocument xmlDoc = pElement->ownerDocument();
	QDomElement systemElement = xmlDoc.createElement( pMenuBlock->qsMenuTag );
	systemElement.setAttribute( ATTRIB_BLOCKNAME, pMenuBlock->qsBlockName );
	if (!pMenuBlock->colorBackground.name().isEmpty())
		systemElement.setAttribute( ATTRIB_COLOR, pMenuBlock->colorBackground.name() );
	
	if (pMenuBlock->qsMenuTag == QString (TAG_CONVERT))	{
		// Print some status infos to check. Man unit testing is boring.
//		printBlock(&pMenuBlock->blockMovieBackground, 0);
		saveBlock (&pMenuBlock->blockMovieBackground, &systemElement); // Handling the movie conversion 
		saveBlock (&pMenuBlock->blockImageBackground, &systemElement); // Handling the movie conversion 
		saveBlock (&pMenuBlock->blockEmptySound, &systemElement);      // Handling the sound conversion
	}
	else if ( (pMenuBlock->qsMenuTag == QString (TAG_PAL)) || (pMenuBlock->qsMenuTag == QString (TAG_NTSC)) )	{
		saveBlock (&pMenuBlock->blockMovieBackground, &systemElement);
		saveBlock (&pMenuBlock->blockImageBackground, &systemElement);
		saveBlock (&pMenuBlock->blockEmptySound, &systemElement);
		saveBlock (&pMenuBlock->blockMplex, &systemElement);
		saveBlock (&pMenuBlock->blockSpumux, &systemElement);
	}
	else 
		saveBlock (&pMenuBlock->blockOthers, &systemElement);

	pElement->appendChild (systemElement);
	
	return true;
}

int QDVDAuthorInit::printBlock (MenuBlock::Block *pBlock, int iLevel)
{
	uint t, i;
	char cOffset[100];
	MenuBlock::SubBlock *pSubBlock;
	
	memset (cOffset,   0, 100);
	memset (cOffset, ' ', iLevel*4);
	printf ("%s<Block> MenuTag=<%s> active<%d> blockID<%d> default<%d> hidden<%d> editable<%d>\n",
		cOffset, (const char *)pBlock->qsBlockTag, pBlock->iActive, pBlock->iBlockID,
		pBlock->iDefaultCommand, pBlock->bHidden, pBlock->bEditable);

	if (pBlock->listComments.count() > 0)	{
		printf ("%s  <Comments> Count<%d>\n", cOffset,(int)pBlock->listComments.count());
		for (t=0;t<pBlock->listComments.count();t++)
			printf ("%s    listComment[%d]=<%s>\n", cOffset, t, (const char *)pBlock->listComments[t]);
		printf ("%s  <\\Comments>\n", cOffset);
	}

	if (pBlock->listCommands.count() > 0)	{
		printf ("%s  <Commands> Count<%d>\n", cOffset, (int)pBlock->listCommands.count());
		for (t=0;t<pBlock->listCommands.count();t++)
			printf ("%s    listCommand[%d]=<%s>\n", cOffset, t, (const char *)pBlock->listCommands[t]);
		printf ("%s  <\\Commands>\n", cOffset);
	}

	if (pBlock->listSubBlocks.count() > 0)	{
		for (t=0;t<pBlock->listSubBlocks.count();t++)	{
			pSubBlock = pBlock->listSubBlocks[t];
			printf ("%s  <SubBlocks> Count<%d> name=<%s> number=<%d>\n", cOffset, 
				(int)pBlock->listSubBlocks.count(), (const char *)pSubBlock->qsName,
				pSubBlock->iNumber);
			for (i=0;i<pSubBlock->listBlocks.count();i++)
				printBlock (pSubBlock->listBlocks[i], iLevel+1);
			printf ("%s  <\\SubBlocks>\n", cOffset);
		}
	}

	printf ("%s<\\Block>\n", cOffset);
	return iLevel + 1;
}

bool QDVDAuthorInit::saveBlock (MenuBlock::Block *pBlock, QDomElement *pElement)
{
	uint t;
	QDomElement blockElement;

	QDomDocument xmlDoc = pElement->ownerDocument();
	blockElement = xmlDoc.createElement( TAG_BLOCK );

	if ( (!pBlock->qsBlockTag.isEmpty()) && (!pBlock->qsBlockTag.isNull()) )
		blockElement.setAttribute ( ATTRIB_NAME, pBlock->qsBlockTag );

	if      (pBlock->iActive ==  0)
		blockElement.setAttribute( ATTRIB_ACTIVE, QString ("false"));
	else if (pBlock->iActive ==  1)
		blockElement.setAttribute( ATTRIB_ACTIVE, QString ("true"));
	else if (pBlock->iActive == -1) ; // Do nothing in this case
	
	if      (pBlock->bHidden ==  false)
		blockElement.setAttribute( ATTRIB_HIDDEN, QString ("false") );
	else
		blockElement.setAttribute( ATTRIB_HIDDEN, QString ("true") );

	if      (pBlock->bEditable ==  false)
		blockElement.setAttribute( ATTRIB_EDITABLE, QString ("false") );
	else
		blockElement.setAttribute( ATTRIB_EDITABLE, QString ("true") );

	blockElement.setAttribute( ATTRIB_HIDDEN, QString ("%1").arg(pBlock->iDefaultCommand) );

	for (t=0;t<pBlock->listComments.count();t++)	{
		QDomElement commentElement = xmlDoc.createElement( TAG_COMMENT );
		QDomText commentText = xmlDoc.createTextNode (pBlock->listComments[t]);
		commentElement.appendChild ( commentText );
		blockElement.appendChild ( commentElement );
	}
	for (t=0;t<pBlock->listCommands.count();t++)	{
		QDomElement commandElement = xmlDoc.createElement( TAG_COMMAND );
		if (pBlock->iDefaultCommand == (int)t)
			commandElement.setAttribute( ATTRIB_DEFAULT, QString ("true"));
		QDomText commandText = xmlDoc.createTextNode (pBlock->listCommands[t]);
		commandElement.appendChild ( commandText );
		blockElement.appendChild ( commandElement );
	}
	for (t=0;t<pBlock->listSubBlocks.count();t++)	{
		if (!saveSubBlock(pBlock->listSubBlocks[t] , &blockElement) )
			return false;
	}

	pElement->appendChild ( blockElement );

	return true;
}

bool QDVDAuthorInit::saveSubBlock (MenuBlock::SubBlock *pSubBlock, QDomElement *pElement)
{
	uint t;
	QDomElement subBlockElement;

	QDomDocument xmlDoc = pElement->ownerDocument();
	subBlockElement = xmlDoc.createElement( TAG_SUBBLOCK );

	if ( (!pSubBlock->qsName.isEmpty()) && (!pSubBlock->qsName.isNull()) )
		subBlockElement.setAttribute ( ATTRIB_NAME, pSubBlock->qsName );
	subBlockElement.setAttribute ( ATTRIB_NUMBER, pSubBlock->iNumber );

	for (t=0;t<pSubBlock->listBlocks.count();t++)	{
		if (!saveBlock(pSubBlock->listBlocks[t] , &subBlockElement) )
			return false;
	}

	pElement->appendChild ( subBlockElement );

	return true;
}

void QDVDAuthorInit::printCommandList( char *pFrom )
{
	printf ("%s =-> printCommandList \n", pFrom);
	for (uint t=0;t<m_listExecute.count();t++)  {
		for (uint i=0;i<m_listExecute[t]->listCommandList.count ();i++)  {
			QStringList qsCommandList = m_listExecute[t]->listCommandList[i];
			for (uint j=0;j<qsCommandList.count();j++)  {
				printf ( "QDVDAuthorInit::printCommandList <%d><%d><%d> = <%s>\n", t, i, j, qsCommandList[j].ascii() );
			}
		}
	}
}

QValueList <ExecuteInterface *>&QDVDAuthorInit::getList()
{

	return m_listExecute;
}

Keyword *QDVDAuthorInit::getKeyword ()
{
  return &m_keyword;
}

void QDVDAuthorInit::setDefault(int iBlockID, uint iDefaultCommand)
{
  // This function will search through the MenuBlocks to find the appropriate comment 
  // in order to set the default command correctly.
  MenuBlock::Block *pBlock = getBlock(iBlockID);
  if ( pBlock ) // Sanity check
       pBlock->iDefaultCommand = iDefaultCommand;
}

QDVDAuthorInit::MenuBlock::Block *QDVDAuthorInit::getBlock (int iBlockID, int *piKeyset )
{
  uint t, i, j, k;
  MenuBlock *arrayMenuBlocks[] = {&m_palMenuBlock, &m_ntscMenuBlock, &m_convertMenuBlock, &m_subtitlesMenuBlock, &m_dvdauthorMenuBlock, &m_burningMenuBlock};
  MenuBlock *pMenuBlock;
  MenuBlock::Block *pBlock, *pSubSubBlock, *pReturn = NULL;
  MenuBlock::SubBlock *pSubBlock;
  for (t=0;t<sizeof ( arrayMenuBlocks ) /  sizeof (MenuBlock *);t++)	{
    pMenuBlock = arrayMenuBlocks[t];
    if ( piKeyset )
        *piKeyset = pMenuBlock->iKeyset;
    if (pMenuBlock->blockMovieBackground.iBlockID == iBlockID)
      pReturn = &pMenuBlock->blockMovieBackground;
    else if (pMenuBlock->blockImageBackground.iBlockID == iBlockID)
      pReturn = &pMenuBlock->blockImageBackground;
    else if (pMenuBlock->blockEmptySound.iBlockID == iBlockID)
      pReturn = &pMenuBlock->blockEmptySound;
    else if (pMenuBlock->blockMplex.iBlockID      == iBlockID)
      pReturn = &pMenuBlock->blockMplex;
    else if (pMenuBlock->blockSpumux.iBlockID     == iBlockID)
      pReturn = &pMenuBlock->blockSpumux;
    else if (pMenuBlock->blockOthers.iBlockID     == iBlockID)
      pReturn = &pMenuBlock->blockOthers;
    else 	{	// No luck finding the block, let us check in the subBlocks of the MovieBackground - block 
      pBlock = &pMenuBlock->blockMovieBackground;
      for (k=0;k<3;k++) {
	if ( k == 1 )
	  pBlock = &pMenuBlock->blockImageBackground;
	else if ( k == 2 )
	  pBlock = &pMenuBlock->blockOthers;
	for (i=0;i<pBlock->listSubBlocks.count();i++)	{
	  pSubBlock = pBlock->listSubBlocks[i];
	  for (j=0;j<pSubBlock->listBlocks.count();j++)	{
	    pSubSubBlock = pSubBlock->listBlocks[j];
	    if (pSubSubBlock->iBlockID == iBlockID)	{
	      return  pSubSubBlock;
	    }
	  }
	}  
      }
    }
    if (pReturn)
      return pReturn;
  }
  if ( piKeyset )
      *piKeyset = Keyword::Keys;
  return NULL;
}
/*
      for (i=0;i<pMenuBlock->blockMovieBackground.listSubBlocks.count();i++)	{
	pSubBlock = pMenuBlock->blockMovieBackground.listSubBlocks[i];
	for (j=0;j<pSubBlock->listBlocks.count();j++)	{
	  pSubSubBlock = pSubBlock->listBlocks[j];
	  if (pSubSubBlock->iBlockID == iBlockID)	{
	    return  pSubSubBlock;
	  }
	}
      }  // And since I also use now the blockOthers to store sub-Blocks ...
      for (i=0;i<pMenuBlock->blockOthers.listSubBlocks.count();i++)	{
	pSubBlock = pMenuBlock->blockOthers.listSubBlocks[i];
	for (j=0;j<pSubBlock->listBlocks.count();j++)	{
	  pSubSubBlock = pSubBlock->listBlocks[j];
	  if (pSubSubBlock->iBlockID == iBlockID)	{
	    return  pSubSubBlock;
	  }	  
	}
      }
*/

void QDVDAuthorInit::appendPreProcessing ()
{
	int t;
	// First we clear the 'old' list ...
	for (t=0;t<(int)m_listToBeDeleted.count();t++)
		delete m_listToBeDeleted[t];
	m_listToBeDeleted.clear ();
	m_listExecute.clear();

	m_keyword.clear( Keyword::Keys );
	m_keyword.setValue ( Keyword::Keys, Keyword::KeyDVDAuthorXML, m_qsDvdauthorFile );
	m_keyword.setValue ( Keyword::Keys, Keyword::KeyProjectPath,  m_qsProjectPath);
	m_keyword.setValue ( Keyword::Keys, Keyword::KeyTempPath,     m_qsTempPath);
	// Then we append pre processing (movie conversion if neccesary).
	// Prep the convertInterface for Movie / Audio conversion ...
	m_listExecute.append(&m_convertInterface);
	//printCommandList ("appendPreProcessing");
}

void QDVDAuthorInit::appendConvert (SourceFileEntry *pEntry)
{
  uint t, i, j, k;
  int iXPos, iSplitPos;
  QString qsResolution, qsVideoFormat, qsRatio, qsWidth, qsHeight, qsBaseName;

  TranscodeInterface *pInterface = NULL;
  Subtitles          *pSubtitles = NULL;
  ExecuteInterface   *pExecute   = NULL;
  SourceFileInfo     *pInfo      = NULL;
  QDVDAuthorInit::MenuBlock::Block *pBlock, *pSubSubBlock;
  QDVDAuthorInit::MenuBlock::SubBlock *pSubBlock;
  QStringList listCommands;
  
  if (!pEntry)
    return;

  for (t=0;t<pEntry->listFileInfos.count();t++)	{
    pInfo  = pEntry->listFileInfos[t];
    pInterface = pInfo->pTranscodeInterface;
    pSubtitles = pInfo->pSubtitles;
    // The user wants this one to get converted.
    if ( pInterface ) {
      // It seems that the file is currently beeing transcoded.
      if ( pInterface->bTranscoding )
	continue;
      // Okay, this one needs to be convertsed.
      m_keyword.clear    ( Keyword::TransKeys );
      m_keyword.setValue ( Keyword::TransKeys, Keyword::TransDVDAuthorXML, m_qsDvdauthorFile );
      m_keyword.setValue ( Keyword::TransKeys, Keyword::TransProjectPath,  m_qsProjectPath   );
      m_keyword.setValue ( Keyword::TransKeys, Keyword::TransTempPath,     m_qsTempPath      );
      
      QFileInfo fileInfo ( pInfo->qsFileName );
      m_keyword.setValue ( Keyword::TransKeys, Keyword::TransInputName,   pInfo->qsFileName         );
      m_keyword.setValue ( Keyword::TransKeys, Keyword::TransBaseName,    fileInfo.baseName     ( ) );
      m_keyword.setValue ( Keyword::TransKeys, Keyword::TransFileExt,     fileInfo.extension    ( ) );
      m_keyword.setValue ( Keyword::TransKeys, Keyword::TransAudioFormat, pInterface->qsAudioFormat );
      m_keyword.setValue ( Keyword::TransKeys, Keyword::TransAudioType,   pInterface->qsAudioType   );
      m_keyword.setValue ( Keyword::TransKeys, Keyword::TransAudioBitrate,QString ("%1").arg(pInterface->iAudioBitrate ) );
      m_keyword.setValue ( Keyword::TransKeys, Keyword::TransSampleRate,  QString ("%1").arg(pInterface->iSample       ) );
      m_keyword.setValue ( Keyword::TransKeys, Keyword::TransStartingAt,  QString ("%1").arg(pInterface->iStartingAt   ) );
      m_keyword.setValue ( Keyword::TransKeys, Keyword::TransEndingAt,    QString ("%1").arg(pInterface->iEndingAt     ) );
      
      pExecute = new ExecuteInterface;
      pExecute->qsBlockName = m_keyword.resolvString ( Keyword::TransKeys, m_convertMenuBlock.qsBlockName );
      pExecute->backgroundColor = m_convertMenuBlock.colorBackground;
      listCommands.clear ();
      if (!pEntry->bSoundSource)	{ // here we handle the video sources.
	pBlock = &(m_convertMenuBlock.blockMovieBackground);
	if ( pInterface->bRemuxOnly )
	  pBlock = &(m_convertMenuBlock.blockImageBackground);
	// Note the following line is kept out bc it represents the 
	// Transcode/MEncoder selectionDropDown and not used for conversion itself
	// pExecute->listBlockIDs.append (pBlock->iBlockID);
	qsResolution = pInterface->qsResolution;
	if ( qsResolution.isNull () )
	  qsResolution = pInfo->qsResolution;
	iXPos    = qsResolution.find   ( "x" );
	qsWidth  = qsResolution.left  ( iXPos );
	qsHeight = qsResolution.right ( iXPos );

	qsVideoFormat = "ntsc";
	if ( ( pInterface->qsVideoFormat == "pal" ) || ( pInterface->qsVideoFormat == "PAL" ) )
	  qsVideoFormat = "pal";
	qsRatio = "4:3";
	if ( ( ! pInterface->qsRatio.isEmpty () ) && ( pInterface->qsRatio.find ( "Keep" ) == -1 ) ){
	  qsRatio = pInterface->qsRatio;
	}
	else if ( pInfo->qsRatio.isEmpty () )
	  qsRatio = pInfo->qsRatio;
	
	m_keyword.setValue ( Keyword::TransKeys, Keyword::TransWidth,        qsWidth                 );
	m_keyword.setValue ( Keyword::TransKeys, Keyword::TransHeight,       qsHeight                );
	m_keyword.setValue ( Keyword::TransKeys, Keyword::TransVideoFormat,  qsVideoFormat           );
	m_keyword.setValue ( Keyword::TransKeys, Keyword::TransVideoType,    pInterface->qsVideoType );
	m_keyword.setValue ( Keyword::TransKeys, Keyword::TransVideoBitrate, QString ("%1").arg(pInterface->iVideoBitrate ) );
	m_keyword.setValue ( Keyword::TransKeys, Keyword::TransFrameRate,    QString ("%1").arg(pInterface->fFrameRate    ) );
	m_keyword.setValue ( Keyword::TransKeys, Keyword::TransRatio,        qsRatio                 );
	
	// m_keyword.printf ( Keyword::TransKeys );

	for (j=0;j<pBlock->listSubBlocks.count ();j++)	{
	  pSubBlock = pBlock->listSubBlocks[j];
	  for (k=0;k<pSubBlock->listBlocks.count ();k++)	{
	    pSubSubBlock = pSubBlock->listBlocks[k];
	    for (i=0;i<pSubSubBlock->listComments.count();i++)
	      pExecute->commentList.append( m_keyword.resolvString( Keyword::TransKeys, pSubSubBlock->listComments[i] ) );
	  }
	}
	
	for (i=0;i<pBlock->listCommands.count();i++)
	  listCommands.append( m_keyword.resolvString( Keyword::TransKeys, pBlock->listCommands[i]));
	pExecute->listCommandList.append(listCommands);
	pExecute->listBlockIDs.append    ( pBlock->iBlockID );
	pExecute->listDefaults.append    ( pBlock->iDefaultCommand );
	listCommands.clear ();
	for (j=0, iSplitPos=0;j<pBlock->listSubBlocks.count ();j++)	{
	  pExecute->listSplitAt.append  ( iSplitPos );
	  pSubBlock = pBlock->listSubBlocks[j];
	  for (k=0;k<pSubBlock->listBlocks.count();k++)	{
	    pSubSubBlock = pSubBlock->listBlocks[k];
	    for (i=0;i<pSubSubBlock->listCommands.count();i++)
	      listCommands.append( m_keyword.resolvConvert( pSubSubBlock->listCommands[i], pSubBlock->qsName ) );
	    iSplitPos ++;
	    pExecute->listCommandList.append ( listCommands );
	    pExecute->listBlockIDs.append    ( pSubSubBlock->iBlockID );
	    pExecute->listDefaults.append    ( pSubSubBlock->iDefaultCommand );
	    listCommands.clear ();
	  }
	}
	// Next we check if the output file name already exists
	// This is to prevent re-encoding if already existant.
	fileInfo.setFile ( QString ("%1/%2.mpg").arg( Global::qsTempPath ).arg( m_keyword.value ( Keyword::TransKeys, Keyword::TransBaseName ) ) ); 
	if ( fileInfo.exists ( ) )	
	  pExecute->bShowBlock = false;
	pExecute->listKeywords = m_keyword.getValues ( Keyword::TransKeys );
      }
      else	{	// and here we handle the sound sources.
	pBlock = &(m_convertMenuBlock.blockEmptySound);
	
	pExecute->listDefaults.append (pBlock->iDefaultCommand);
	pExecute->listBlockIDs.append (pBlock->iBlockID);
	for (i=0;i<pBlock->listCommands.count();i++)
	  listCommands.append( m_keyword.resolvString( Keyword::TransKeys, pBlock->listCommands[i] ) );
	for (i=0;i<pBlock->listComments.count();i++)
	  pExecute->commentList.append( m_keyword.resolvString( Keyword::TransKeys, pBlock->listComments[i] ) );
	pExecute->listCommandList.append(listCommands);
	// Next we check if the output file name already exists
	// This is to prevent re-encoding if already existant.
	fileInfo.setFile (QString ("%1/%2.mp2").arg(Global::qsTempPath).arg( m_keyword.value ( Keyword::TransKeys, Keyword::TransBaseName ) ) );
	if (fileInfo.exists())	
	  pExecute->bShowBlock = false;
      }
      m_listExecute.append(pExecute);
      m_listToBeDeleted.append (pExecute);
    }// end if pInterface ...
    if ( pSubtitles ) {
      QFileInfo fileInfo    ( pInfo->qsFileName );
      //      if ( ! pInterface ) {
      m_keyword.clear    ( Keyword::SubKeys );
      m_keyword.setValue ( Keyword::SubKeys, Keyword::SubProjectPath,   m_qsProjectPath        );
      m_keyword.setValue ( Keyword::SubKeys, Keyword::SubTempPath,      m_qsTempPath           );
      m_keyword.setValue ( Keyword::SubKeys, Keyword::SubInputFileName, pInfo->qsFileName      );
      m_keyword.setValue ( Keyword::SubKeys, Keyword::SubBaseName,      fileInfo.baseName  ( ) );
      m_keyword.setValue ( Keyword::SubKeys, Keyword::SubFileExt,       fileInfo.extension ( ) );
      //      }

      pBlock = &(m_subtitlesMenuBlock.blockOthers);
      pExecute = new ExecuteInterface;
      pExecute->qsBlockName = m_keyword.resolvString ( Keyword::SubKeys, m_subtitlesMenuBlock.qsBlockName );
      pExecute->backgroundColor = m_subtitlesMenuBlock.colorBackground;
      if (m_arrayColors.count() > 0)
	pExecute->backgroundColor = *m_arrayColors[++m_iColorCounter%m_arrayColors.count()];
      else
	pExecute->backgroundColor.setNamedColor("#9EEE81");
      //      if (m_iColorCounter > (int)m_arrayColors.count())
      //m_iColorCounter = 0;

      listCommands.clear ();

      pExecute->listDefaults.append (pBlock->iDefaultCommand);
      pExecute->listBlockIDs.append (pBlock->iBlockID);
      for (i=0;i<pBlock->listCommands.count();i++)
	listCommands.append( m_keyword.resolvString( Keyword::SubKeys, pBlock->listCommands[i] ) );
      for (i=0;i<pBlock->listComments.count();i++)
	pExecute->commentList.append( m_keyword.resolvString( Keyword::SubKeys, pBlock->listComments[i] ) );
      pExecute->listCommandList.append(listCommands);

      m_listExecute.append(pExecute);
      m_listToBeDeleted.append (pExecute);
    }
  }
  //printCommandList ("appendConvert");
}

void QDVDAuthorInit::appendMenu (DVDMenu *pMenu, QString qsMenuName, QString qsBackgroundFileName)
{
	// This function will generate the Commands needed per Menu.
	// The information comes from the menu on the one hand and on the other 
	// it comes from the init - file. This is the mating ground ...
	uint t, i;
	MenuBlock *pMenuBlock;
	MenuBlock::Block *pBlock;
	MenuBlock::SubBlock *pSubBlock;
	ExecuteInterface *pInterface = new ExecuteInterface;
	
	// First things first, here we determine the Format ...
	// iFormat > 4 equals PAL, otherwise NTSC
	int iFormat = pMenu->getFormat (pMenu->getInterface()->iWidth, pMenu->getInterface()->iHeight);

	// Next is to create the keyword list ... needed for resolvString() ...
	m_keyword.clear    ( Keyword::Keys );
	m_keyword.setValue ( Keyword::Keys, Keyword::KeyDVDAuthorXML, m_qsDvdauthorFile );
	m_keyword.setValue ( Keyword::Keys, Keyword::KeyProjectPath,  m_qsProjectPath   );
	m_keyword.setValue ( Keyword::Keys, Keyword::KeyTempPath,     m_qsTempPath      );
	m_keyword.setValue ( Keyword::Keys, Keyword::KeyWidth,        QString ("%1").arg(pMenu->getInterface()->iWidth  ) );
	m_keyword.setValue ( Keyword::Keys, Keyword::KeyHeight,       QString ("%1").arg(pMenu->getInterface()->iHeight ) );

	if (iFormat > 4)	{	// PAL
		pMenuBlock = &m_palMenuBlock;
		m_keyword.setValue ( Keyword::Keys, Keyword::KeyFormat, "PAL"  );
	}
	else	{
		pMenuBlock = &m_ntscMenuBlock;
		m_keyword.setValue ( Keyword::Keys, Keyword::KeyFormat, "NTSC" );
	}
	QFileInfo fileInfo ( qsBackgroundFileName );
	m_keyword.setValue ( Keyword::Keys, Keyword::KeyMenuName,  pMenu->name ( ) );
	m_keyword.setValue ( Keyword::Keys, Keyword::KeyStartPos,  pMenu->getInterface( )->timeOffset.toString   ( ) );
	m_keyword.setValue ( Keyword::Keys, Keyword::KeyDuration,  pMenu->getInterface( )->timeDuration.toString ( ) );
	m_keyword.setValue ( Keyword::Keys, Keyword::KeyBackgroundFileName, fileInfo.fileName ( ) );
	m_keyword.setValue ( Keyword::Keys, Keyword::KeyBackgroundFullName, qsBackgroundFileName );
	m_keyword.setValue ( Keyword::Keys, Keyword::KeySoundList, m_qsTempPath );

	// Sanity check ...
//	if ( (!pMenuBlock) || (!pMenuBlock->bValid) )
	if (!pMenuBlock)
		return;

	pInterface->qsBlockName = m_keyword.resolvString ( Keyword::Keys, pMenuBlock->qsBlockName);
//	pInterface->backgroundColor = pMenuBlock->colorBackground;
	if (m_arrayColors.count() > 0)
		pInterface->backgroundColor = *m_arrayColors[++m_iColorCounter%m_arrayColors.count()];
	else
		pInterface->backgroundColor.setNamedColor("#9EEE81");

	if (m_iColorCounter > (int)m_arrayColors.count())
		m_iColorCounter = 0;

	// Here we check if the background is a movie or an image.
	QFileInfo backgroundInfo (qsBackgroundFileName);
	pBlock = &pMenuBlock->blockImageBackground;
	     
	MediaInfo *pMediaInfo = pMenu->getDVDAuthor()->getMediaInfo ();
	QString qsExtensions  = pMediaInfo->getExtensions (true);
	if (qsExtensions.find (QString (".")+backgroundInfo.extension(FALSE)) > -1)	{
		// Okay we have a movieBackground. Now every frame of that background has to be rendered
		// so we need to run quite some commands in here ...
		// Fortunately all we need is stored in the blockMovieBackground structure.
		for (t=0;t<pMenuBlock->blockMovieBackground.listSubBlocks.count();t++)	{
			pSubBlock = pMenuBlock->blockMovieBackground.listSubBlocks[t];
			for (i=0;i<pSubBlock->listBlocks.count();i++)	{
				addBlock (pInterface, pSubBlock->listBlocks[i]);
			}
		}
		// After we have the movie extracted, we check if the user added sound files
		if ( (pMenu->getInterface()->bMovieBackgroundHasSound) && (pMenu->getInterface()->listSoundEntries.count() == 0) )	{
			QString qsBackgroundAudio = QString ("%1/%2/clip.wav").arg(qsMenuName).arg(backgroundInfo.fileName ());
			backgroundInfo.setFile(qsBackgroundAudio);
			pMenu->getInterface()->listSoundEntries.append (qsBackgroundAudio);
		}
	}
	else if (pMenu->isMovieMenu ())	{
		// The difference here is that the background is a image
		// So we need everything from the point of the rendering of the menu.
		bool bAddBlocks = false;
		for (t=0;t<pMenuBlock->blockMovieBackground.listSubBlocks.count();t++)	{
			pSubBlock = pMenuBlock->blockMovieBackground.listSubBlocks[t];
			pBlock = pSubBlock->listBlocks[0];
			if (!bAddBlocks) {  // Only need to check up till we find the render command
				for (i=0;i<pBlock->listCommands.count();i++)	{
					// Check every command for the RENDER_MENU - string
					if (pBlock->listCommands[i].find( QString(RENDER_MENU)) > -1)
						bAddBlocks = true;
				}
			}
			if (bAddBlocks)
				addBlock (pInterface, pBlock); //pMenuBlock->blockMovieBackground.listSubBlocks[t]);
		}
	}
	else 
		addBlock (pInterface, pBlock);

	// Note, spumux > button 'label' is ought to be 'name' now ??? (spumux from 19 Feb 2004)
	m_soundList.clear();
	if (pMenu->getInterface()->listSoundEntries.count() == 0)	{
		// This is the only instance where we need a hardcoded naming scheme ...
		m_soundList.append (QString ("\"%1/menu.mp2\"").arg(qsMenuName));
		//		m_listKeywords[m_listKeys.count() - 1] = m_soundList[0];
		m_keyword.setValue ( Keyword::Keys, Keyword::KeySoundList, m_soundList[0] );
		addBlock(pInterface, &pMenuBlock->blockEmptySound);
	}
	else	{
		QString qsConvertedSound;
		for (t=0;t<pMenu->getInterface()->listSoundEntries.count();t++)	{
			QString qsEntryName = pMenu->getInterface()->listSoundEntries[t];
			SourceFileEntry *pEntry = pMenu->getDVDAuthor()->getSourceEntryByDisplayName(qsEntryName);
			if (!pEntry)
				continue;
			for (i=0;i<pEntry->listFileInfos.count();i++)	{
				qsConvertedSound = convertSoundFile (pEntry->listFileInfos[i]->qsFileName);
				m_soundList.append (QString ("\"%1\"").arg(qsConvertedSound));
			}
		}
		m_keyword.setValue ( Keyword::Keys, Keyword::KeySoundList, m_soundList.join (" ") );
		//		m_listKeywords[m_listKeys.count() - 1] = m_soundList.join (" ");
	}
	addBlock(pInterface, &pMenuBlock->blockMplex);
	addBlock(pInterface, &pMenuBlock->blockSpumux);

	pInterface->bShowBlock = !pMenuBlock->bHidden;
	pInterface->listKeywords = m_keyword.getValues ( Keyword::Keys );
	m_listExecute.append     ( pInterface );
	m_listToBeDeleted.append ( pInterface );
}

void QDVDAuthorInit::appendPostProcessing ()
{
	// Here we check if transcoding was requested ...
	if (m_convertInterface.listCommandList.count () < 1)
		m_listExecute.remove (&m_convertInterface);

	m_listExecute.append(&m_dvdauthorInterface);
	m_listExecute.append(&m_burnInterface);
}

void QDVDAuthorInit::addBlock(ExecuteInterface *pInterface, MenuBlock::Block *pBlock)
{
	uint t;
	QStringList stringList;
	// Currently not supported more then one comment per block ...
//	for (t=0;t<pBlock->listComments.count(); stringList.append(resolvString(pMenu, pBlock->listComments[t++])));
	pInterface->commentList.append( m_keyword.resolvString( Keyword::Keys, pBlock->listComments[0] ) ); //stringList);
//	stringList.clear();
	for (t=0;t<pBlock->listCommands.count(); stringList.append( m_keyword.resolvString( Keyword::Keys, pBlock->listCommands[t++] ) ) );
	pInterface->listCommandList.append(stringList);
	pInterface->listDefaults.append (pBlock->iDefaultCommand);
	pInterface->listBlockIDs.append (pBlock->iBlockID);

	stringList.clear();
}

QString QDVDAuthorInit::convertSoundFile (QString qsOriginalSoundFile)
{
	// TODO : 
	// This function is supposed to detect the sound preferences of the sound files
	// and convert them to the propper mp2, pcm, or ac3 layer format for usage with the DVD
	QString qsReturn;

	qsReturn = qsOriginalSoundFile;

	return qsReturn;
}

/**
 * This function will set the ini - file to the default values.
 */
void QDVDAuthorInit::resetInitFile ()
{
  
  QString qsPreferedMediaEngine = "QMPlayerWidget";
#ifndef MPLAYER_SUPPORT
  qsPreferedMediaEngine = "KXineWidget";
  #ifndef XINE_SUPPORT
    qsPreferedMediaEngine = "QVLCWidget";
    #ifndef VLC_SUPPORT
      qsPreferedMediaEngine = "DummyWidget";
    #endif
  #endif
#endif

  QString qsInitFile = QDir::homeDirPath();
  qsInitFile.append(INIT_DIR_NAME);
  qsInitFile.append(INIT_FILE_NAME);
  
  QFile initFile(qsInitFile);
  if ( initFile.open( IO_WriteOnly ) )	{
    QTextStream stream( &initFile );
    QString qsResetInitFile = QString ("<QDVDAuthorInitFile version=\"%1\" delete_older_than=\"30\" first_start=\"1\" >\n").arg((float)INIT_VERSION);
    qsResetInitFile += QString (
" <PreferredEngine>"+qsPreferedMediaEngine+"</PreferredEngine>\n"
"  <Color number=\"0\">#9EEE81</Color>\n"
"  <Color number=\"1\">#8FEED3</Color>\n"
"  <Color number=\"2\">#E0EE8F</Color>\n"
"  <Color number=\"3\">#ED97EE</Color>\n"
"  <Color number=\"4\">#9EEE81</Color>\n"
"  <Color number=\"5\">#8FEED3</Color>\n"
"  <Color number=\"6\">#E0EE8F</Color>\n"
"  <Color number=\"7\">#ED97EE</Color>\n"
"  <Color number=\"8\">#9EEE81</Color>\n"
"  <Color number=\"9\">#8FEED3</Color>\n"
"  <Color number=\"10\">#E0EE8F</Color>\n"
"  <Color number=\"11\">#F92F5E</Color>\n"
" <Path name=\"bash\" ></Path>\n"
" <Path name=\"dvdauthor\" ></Path>\n"
" <Path name=\"spumux\" ></Path>\n"
" <Path name=\"mplex\" ></Path>\n"
" <Path name=\"arecord\" ></Path>\n"
" <Path name=\"transcode\" ></Path>\n"
" <Path name=\"movie-to-dvd\" ></Path>\n"
" <Path name=\"png2yuv\" ></Path>\n"
" <Path name=\"oggdec\" ></Path>\n"
" <Path name=\"mp2enc\" ></Path>\n"
" <Path name=\"lame\" ></Path>\n"
" <Path name=\"mplayer\" ></Path>\n"
" <Path name=\"mencoder\" ></Path>\n"
" <Path name=\"jpegtopnm\" ></Path>\n"
" <Path name=\"ppmtoy4m\" ></Path>\n"
" <Path name=\"mpeg2enc\" ></Path>\n"
" <Path name=\"jpeg2yuv\" ></Path>\n"
" <Path name=\"pcm2aiff\" ></Path>\n"
" <Path name=\"toolame\" ></Path>\n"
" <Path name=\"mctoolame\" ></Path>\n"
" <Path name=\"dd\" ></Path>\n"
" <Path name=\"dvd-slideshow\" ></Path>\n"
" <Path name=\"sox\" ></Path>\n"
" <Path name=\"pngtopnm\" ></Path>\n"
" <Path name=\"convert\" ></Path>\n"
" <Path name=\"growisofs\" ></Path>\n"
" <Path name=\"dvd+rw-format\" ></Path>\n"
" <Path name=\"mkisofs\" ></Path>\n"
" <Path name=\"dvdrecord\" ></Path>\n"
"  <DragNDrop start_offset=\"00:00:00\" thumbnail_size=\"50x50\" button_type=\"1\" text_pos=\"1\" duration=\"00:00:00\" color=\"#ff0000\" with_text=\"1\" button_size=\"150x150\" >\n"
"    <Font>Sans Serif,24,-1,5,75,0,0,0,0,0</Font>\n"
"  </DragNDrop>\n"
" <ExecuteInterface>\n"
"  <Convert color=\"#f92f5e\" blockname=\"Conversion Block\" >\n"
"   <Block editable=\"false\" hidden=\"0\" name=\"MOVIE_BACKGROUND\" >\n"
"    <Comment>Choose Conversion Tool.</Comment>\n"
"    <Command default=\"true\" >"CONVERT_VIDEOTRANS" +INPUT_NAME+</Command>\n"
"    <Command>"CONVERT_TRANSCODE" +INPUT_NAME+</Command>\n"
"    <Command>"CONVERT_MENCODER" +INPUT_NAME+</Command>\n"
"    <Command>+BASE_NAME+.+FILE_EXT+</Command>\n"
"    <SubBlock number=\"0\" name=\""SUB_BLOCK_VIDEOTRANS"\" >\n"
"     <Block editable=\"false\" hidden=\"0\" name=\""SUB_BLOCK_VIDEOTRANS"\" >\n"
"      <Comment>This will convert the input movie file from into DVD (+VIDEO_FORMAT+) conforming material.</Comment>\n"
"      <Command default=\"true\" >movie-to-dvd -M -a +RATIO+ -f audio -m +VIDEO_FORMAT+ -o \"+TEMP_PATH+/+BASE_NAME+/\" \"+INPUT_NAME+\" &amp;&amp; mv \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.vob\" \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mpeg2\"</Command>\n"
"     </Block>\n"
"    </SubBlock>\n"
"    <SubBlock number=\"0\" name=\"Transcode\" >\n"
"     <Block editable=\"false\" hidden=\"1\" name=\"Transcode\" >\n"
"      <Comment>This will convert the input movie file from DV - format into DVD (PAL) conforming material.</Comment>\n"
"      <Comment>This will convert the input movie file from mpeg1 - format into DVD conform material.</Comment>\n"
"      <Command>transcode -i \"+INPUT_NAME+\" -x ffmpeg -V -w +VIDEO_BITRATE+ --encode_fields b --export_asr +RATIO+ -F \"8,-c -q 6 -4 2 -2 1 -N 0.5 -E -10\" -K tmpgenc -R 2 -y mpeg2enc,mp2enc -b +AUDIO_BITRATE+ -m \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mpa\" -o \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.m2v\" --print_status 10</Command>\n"
"      <Command default=\"true\" >transcode -i \"+INPUT_NAME+\" --export_prof dvd -o \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+\"</Command>\n"
"     </Block>\n"
"     <Block editable=\"false\" hidden=\"0\" name=\"Transcode2\" >\n"
"      <Comment>And then we multiplexing the audio and video stream into one file.</Comment>\n"
"      <Command default=\"true\" >mplex -f 8 -o \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mpeg2\" \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.m2v\" \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mpa\"</Command>\n"
"     </Block>\n"
"    </SubBlock>\n"
"    <SubBlock number=\"0\" name=\"MEncoder\" >\n"
"     <Block editable=\"false\" hidden=\"0\" name=\"MEncoder1\" >\n"
"      <Comment>First extract and scale the video to the propper values.</Comment>\n"
"      <Command default=\"true\" >mencoder -oac copy -nosound -ovc lavc -ss +STARTING_AT+ -endpos +ENDING_AT+ -lavcopts vcodec=mpeg2video:mbd=1:vbitrate=+VIDEO_BITRATE+ -vf scale=+WIDTH+:+HEIGHT+ -ofps +FRAME_RATE+ -o \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mpg\" \"+INPUT_NAME+\"</Command>\n"
"     </Block>\n"
"     <Block editable=\"false\" hidden=\"0\" name=\"MEncoder2\" >\n"
"      <Comment>Next we get the audio file from the input movie.</Comment>\n"
"      <Command default=\"true\" >mplayer -ao pcm:file=/dev/stdout -af resample=+SAMPLE_RATE+:16:8 -srate +SAMPLE_RATE+ -vo null -vc null \"+INPUT_NAME+\" | mp2enc  -b +AUDIO_BITRATE+ -r +SAMPLE_RATE+ -o \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mp2\"</Command>\n"
"      <Command>mplayer -ao pcm -af resample=+SAMPLE_RATE+:16:8 -srate +SAMPLE_RATE+ -vo null -vc null \"+INPUT_NAME+\" -aofile /dev/stdout | mp2enc  -b +AUDIO_BITRATE+ -r +SAMPLE_RATE+ -o \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mp2\"</Command>\n"
"     </Block>\n"
"     <Block editable=\"false\" hidden=\"0\" name=\"MEncoder3\" >\n"
"      <Comment>And then we multiplexing the audio and video stream into one file.</Comment>\n"
"      <Command default=\"true\" >mplex -f 8 -o \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mpeg2\" \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mpg\" \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mp2\"</Command>\n"
"     </Block>\n"
"    </SubBlock>\n"
"   </Block>\n"
"   <Block editable=\"false\" hidden=\"0\" name=\"IMAGE_BACKGROUND\" >\n"
"    <Comment>Choose Conversion Tool.</Comment>\n"
"    <Command default=\"true\" >"CONVERT_VIDEOTRANS" +INPUT_NAME+</Command>\n"
"    <Command>"CONVERT_TRANSCODE" +INPUT_NAME+</Command>\n"
"    <Command>"CONVERT_MENCODER" +INPUT_NAME+</Command>\n"
"    <Command>+BASE_NAME+.+FILE_EXT+</Command>\n"
"    <SubBlock number=\"0\" name=\""SUB_BLOCK_VIDEOTRANS"\" >\n"
"     <Block editable=\"false\" hidden=\"0\" name=\""SUB_BLOCK_VIDEOTRANS"\" >\n"
"      <Comment>This will convert the input movie file into DVD (+VIDEO_FORMAT+) conforming material.</Comment>\n"
"      <Command default=\"true\" >movie-to-dvd -M -a +RATIO+ -f audio -m +VIDEO_FORMAT+ -o \"+TEMP_PATH+/+BASE_NAME+/\" \"+INPUT_NAME+\" &amp;&amp; mv \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.vob\" \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mpeg2\"</Command>\n"
"     </Block>\n"
"    </SubBlock>\n"
"    <SubBlock number=\"0\" name=\"Transcode\" >\n"
"     <Block editable=\"false\" hidden=\"1\" name=\"Transcode\" >\n"
"      <Comment>These commands will re-multiplex the mpeg2 video to include VOBUs.</Comment>\n"
"      <Command default=\"true\" >transcode -i \"+INPUT_NAME+\" --export_prof dvd -o \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+\"</Command>\n"
"      <Command>transcode -i \"+INPUT_NAME+\" -x ffmpeg -V -w +VIDEO_BITRATE+ --encode_fields b --export_asr +RATIO+ -F \"8,-c -q 6 -4 2 -2 1 -N 0.5 -E -10\" -K tmpgenc -R 2 -y mpeg2enc,mp2enc -b +AUDIO_BITRATE+ -m \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mpa\" -o \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.m2v\" --print_status 10</Command>\n"
"     </Block>\n"
"     <Block editable=\"false\" hidden=\"0\" name=\"Transcode2\" >\n"
"      <Comment>And then we multiplexing the audio and video stream into one file.</Comment>\n"
"      <Command default=\"true\" >mplex -f 8 -o \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mpeg2\" \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.m2v\" \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mpa\"</Command>\n"
"     </Block>\n"
"    </SubBlock>\n"
"    <SubBlock number=\"0\" name=\"MEncoder\" >\n"
"     <Block editable=\"false\" hidden=\"0\" name=\"MEncoder1\" >\n"
"      <Comment>These commands will re-multiplex the mpeg2 video to include VOBUs.</Comment>\n"
"      <Command default=\"true\" >mplayer -dumpfile \"+INPUT_NAME+\" -dumpaudio \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mpa\" </Command>\n"
"      <Command>mencoder -oac copy -nosound -ovc lavc -ss +STARTING_AT+ -endpos +ENDING_AT+ -lavcopts vcodec=mpeg2video:mbd=1:vbitrate=+VIDEO_BITRATE+ -vf scale=+WIDTH+:+HEIGHT+ -ofps +FRAME_RATE+ -o \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mpg\" \"+INPUT_NAME+\"</Command>\n"
"     </Block>\n"
"     <Block editable=\"false\" hidden=\"0\" name=\"MEncoder2\" >\n"
"      <Comment>Next we get the video file from the input movie.</Comment>\n"
"      <Command default=\"true\" >mplayer -dumpfile \"+INPUT_NAME+\" -dumpvideo \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.m2v\" </Command>\n"
"      <Command>mencoder -oac copy -nosound -ovc lavc -ss +STARTING_AT+ -endpos +ENDING_AT+ -lavcopts vcodec=mpeg2video:mbd=1:vbitrate=+VIDEO_BITRATE+ -vf scale=+WIDTH+:+HEIGHT+ -ofps +FRAME_RATE+ -o \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mpg\" \"+INPUT_NAME+\"</Command>\n"
"     </Block>\n"
"     <Block editable=\"false\" hidden=\"0\" name=\"MEncoder3\" >\n"
"      <Comment>And then we multiplexing the audio and video stream into one file.</Comment>\n"
"      <Command default=\"true\" >mplex -f 8 -o \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mpeg2\" \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.m2v\" \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mpa\"</Command>\n"
"      <Command default=\"true\" >mplex -f 8 -o \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mpeg2\" \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.m2v\" \"+TEMP_PATH+/+BASE_NAME+/+BASE_NAME+.mp2\"</Command>\n"
"     </Block>\n"
"    </SubBlock>\n"
"   </Block>\n"
"   <Block editable=\"false\" hidden=\"0\" name=\"EMPTY_SOUND\" >\n"
"    <Comment>We need to convert from OGG-Vorbis format to mp2.</Comment>\n"
"    <Comment>We need to convert from mp3 format to mp2.</Comment>\n"
"    <Command default=\"true\" >oggdec &quot;test.ogg&quot; -o - | mp2enc -o &quot;test2.mp2&quot;</Command>\n"
"    <Command>lame --decode &quot;blues.mp3&quot; - | mp2enc -o &quot;blues.mp2&quot;</Command>\n"
"    <Command>mplayer &quot;mymusicfile.mp3&quot; -vo null -ao pcm:file=&quot;menu_audio.pcm&quot; ; mp2enc -r 48000 -o &quot;menu_audio.mpa&quot; &lt; &quot;menu_audio.pcm&quot;</Command>\n"
"    <Command>mplayer &quot;mymusicfile.mp3&quot; -vo null -ao pcm -aofile &quot;menu_audio.pcm&quot; ; mp2enc -r 48000 -o &quot;menu_audio.mpa&quot; &lt; &quot;menu_audio.pcm&quot;</Command>\n"
"   </Block>\n"
"  </Convert>\n"
"  <Subtitles blockname=\"Subtitles\" >\n"
"   <Block editable=\"false\" hidden=\"0\" name=\"OTHERS\" >\n"
"    <Comment>&lt;p align=&quot;center&quot;>This is to add multiplex subtitles into the video stream.&lt;/p></Comment>"
"    <Command default=\"true\" >spumux &quot;+TEMP_PATH+/+BASE_NAME+/subtitles.xml&quot; &lt; &quot;+INPUT_FILE_NAME+&quot; > &quot;+TEMP_PATH+/+BASE_NAME+/subtitles.vob&quot;</Command>\n"
"   </Block>\n"
"  </Subtitles>\n"
"  </ExecuteInterface>\n"
"  <ExecuteInterface>\n"
"    <Pal blockname=\"+MENU_NAME+ (PAL +WIDTH+x+HEIGHT+)\">\n"
"      <Block name=\"MOVIE_BACKGROUND\">\n"
"        <SubBlock number=\"1\">\n"
"         <Block>\n"
"          <Comment>&lt;p align=\"center\"&gt;This Command will extract the timeframe of interest.&lt;/p&gt;</Comment>\n"
"          <Command default=\"true\">mkdir -p \"+TEMP_PATH+/+MENU_NAME+/background\"; mencoder -oac copy -ovc copy -ss +START_POS+ -endpos +DURATION+ -o \"+TEMP_PATH+/+MENU_NAME+/background/clip.avi\" \"+BACKGROUND_FULL_NAME+\"</Command>\n"
"          <Command>mkdir -p \"+TEMP_PATH+/+MENU_NAME+/background\"; ln -s \"+BACKGROUND_FULL_NAME+\" \"+TEMP_PATH+/+MENU_NAME+/background/clip.avi\"; echo \"Skipping cleaning of source file\"</Command>\n"
"         </Block>\n"
"        </SubBlock>\n"
"        <SubBlock number=\"2\" active=\"false\">\n"
"         <Block>\n"
"          <Comment>&lt;p align=\"center\"&gt;This line of command will clean up the source movie&lt;BR&gt;&lt;U&gt;Note :&lt;/U&gt;Might not be needed.&lt;/p&gt;</Comment>\n"
"          <Command default=\"true\">ln -s \"+TEMP_PATH+/+MENU_NAME+/background/clip.avi\" \"+TEMP_PATH+/+MENU_NAME+/background/clean.avi\"; echo \"Skipping cleaning of source file\"</Command>\n"
"          <Command>mencoder -oac null -ovc lavc -o \"+TEMP_PATH+/+MENU_NAME+/background/clean.avi\" \"+TEMP_PATH+/+MENU_NAME+/background/clip.avi\"</Command>\n"
"         </Block>\n"
"        </SubBlock>\n"
"        <SubBlock number=\"3\">\n"
"         <Block>\n"
"          <Comment>&lt;p align=\"center\"&gt;Here we extract the audio part of the source background&lt;/p&gt;</Comment>\n"
"          <Command default=\"true\">mplayer -ao pcm:file=\"+TEMP_PATH+/+MENU_NAME+/background/clean.wav\" -vo null -vc dummy \"+TEMP_PATH+/+MENU_NAME+/background/clip.avi\"</Command>\n"
"          <Command>mplayer -ao pcm -vo null -vc dummy -aofile \"+TEMP_PATH+/+MENU_NAME+/background/clean.wav\" \"+TEMP_PATH+/+MENU_NAME+/background/clip.avi\"</Command>\n"
"         </Block>\n"
"        </SubBlock>\n"
"        <SubBlock number=\"4\">\n"
"         <Block>\n"
"          <Comment>&lt;p align=\"center\"&gt;And now we extract the image files of the source movie&lt;/p&gt;</Comment>\n"
"          <Command default=\"true\">mplayer -ao null -vo jpeg:outdir=\"+TEMP_PATH+/+MENU_NAME+/background\" \"+TEMP_PATH+/+MENU_NAME+/background/clean.avi\"</Command>\n"
"         </Block>\n"
"        </SubBlock>\n"
"        <SubBlock number=\"6\">\n"
"         <Block>\n"
"          <Comment>&lt;p align=\"center\"&gt;And this is the place where we internally render the images&lt;/p&gt;</Comment>\n"
"          <Command default=\"true\" canmodify=\"false\">"RENDER_MENU"+MENU_NAME+</Command>\n"
"         </Block>\n"
"        </SubBlock>\n"
"        <SubBlock number=\"5\">\n"
"         <Block>\n"
"          <Comment>&lt;p align=\"center\"&gt;We can remove the big temp files&lt;/p&gt;</Comment>\n"
"          <Command default=\"true\">cd \"+TEMP_PATH+/+MENU_NAME+/\"; find . -name clip.avi -exec rm {} \\;; find . -name clean.avi -exec rm {} \\;</Command>\n"
"         </Block>\n"
"        </SubBlock>\n"
"        <SubBlock number=\"6\">"
"         <Block>\n"
"          <Comment>&lt;p align=\"center\"&gt;This line of command will convert the extracted frames &lt;BR&gt;into a MPEG2 stream in PAL format +WIDTH+x+HEIGHT+&lt;/p&gt;</Comment>\n"
"          <Command>png2yuv -j \"+TEMP_PATH+/+MENU_NAME+/background/rendered_%08d.png\" -I p -f 25 -b 1 | mpeg2enc -f 8 -n p -F 3 -M 1 -o \"+TEMP_PATH+/+MENU_NAME+/menu.m2v\"</Command>\n"
"         </Block>\n"
"        </SubBlock>"
"      </Block>\n"
"      <Block name=\"IMAGE_BACKGROUND\">\n"
"        <Comment>&lt;p align=\"center\"&gt;This line of command will convert the background image&lt;BR&gt;into a MPEG2 stream in PAL format +WIDTH+x+HEIGHT+&lt;/p&gt;</Comment>\n"
"        <Command default=\"true\" >jpegtopnm \"+BACKGROUND_FULL_NAME+\" | ppmtoy4m -n 50 -r -S 420mpeg2 -F25:1 -A59:54 -I t -L | mpeg2enc -f 8 -n p -o \"+TEMP_PATH+/+MENU_NAME+/menu.m2v\"</Command>\n"
"        <Command>jpeg2yuv -n 50 -I p -f 25 -j \"+BACKGROUND_FULL_NAME+\" | mpeg2enc -n p -f 8 -o \"+TEMP_PATH+/+MENU_NAME+/menu.m2v\"</Command>\n"
"      </Block>\n"
"      <Block name=\"EMPTY_SOUND\">\n"
"        <Comment>&lt;p align=\"center\"&gt;This line creates an empty sound file to mix into the menu-movie.&lt;/p&gt;</Comment>\n"
"        <Command>arecord -f dat -twav -d 1 | mp2enc -r 48000 -o \"+TEMP_PATH+/+MENU_NAME+/menu.mp2\"</Command>\n"
"        <Command>arecord -S -M -t 1 -w /dev/stdout | mp2enc -r 48000 -o \"+TEMP_PATH+/+MENU_NAME+/menu.mp2\"</Command>\n"
"        <Command>sox -t raw -s -w -c 2 -r 48000 /dev/zero -t wav -c 2 -r 48000 /dev/stdout trim 0 1 | mp2enc -r 48000 -o \"+TEMP_PATH+/+MENU_NAME+/menu.mp2\"</Command>\n"
"        <Command default=\"true\">dd if=/dev/zero bs=4 count=1920 | toolame -b128 -s 48000 /dev/stdin \"+TEMP_PATH+/+MENU_NAME+/menu.mp2\"</Command>\n"
"      </Block>\n"
"      <Block name=\"MPLEX\">\n"
"        <Comment>&lt;p align=\"center\"&gt;The following command will multiplex the sound file into the menu-movie.&lt;/p&gt;</Comment>\n"
"        <Command default=\"true\">mplex -f 8 -o \"+TEMP_PATH+/+MENU_NAME+/menu.mpg\" \"+TEMP_PATH+/+MENU_NAME+/menu.m2v\" +SOUND_LIST+</Command>\n"
"      </Block>\n"
"      <Block name=\"SPUMUX\">\n"
"        <Comment>&lt;p align=\"center\"&gt;Here we use spumux to add the subpicture (buttons) the the mpeg2 video.&lt;/p&gt;</Comment>\n"
"        <Command default=\"true\">spumux \"+TEMP_PATH+/+MENU_NAME+/menu.xml\" &lt; \"+TEMP_PATH+/+MENU_NAME+/menu.mpg\" &gt; \"+TEMP_PATH+/+MENU_NAME+_menu.mpg\"</Command>\n"
"      </Block>\n"
"    </Pal>\n"
"    <Ntsc blockname=\"+MENU_NAME+ (NTSC +WIDTH+x+HEIGHT+)\">\n"
"      <Block name=\"MOVIE_BACKGROUND\">\n"
"        <SubBlock number=\"1\">\n"
"         <Block>\n"
"          <Comment>&lt;p align=\"center\"&gt;This Command will extract the requested timeframe.&lt;/p&gt;</Comment>\n"
"          <Command default=\"true\">mkdir -p \"+TEMP_PATH+/+MENU_NAME+/background\"; mencoder -oac copy -ovc copy -ss +START_POS+ -endpos +DURATION+ -o \"+TEMP_PATH+/+MENU_NAME+/background/clip.avi\" \"+BACKGROUND_FULL_NAME+\"</Command>\n"
"          <Command>mkdir -p \"+TEMP_PATH+/+MENU_NAME+/background\"; ln -s \"+BACKGROUND_FULL_NAME+\" \"+TEMP_PATH+/+MENU_NAME+/background/clip.avi\"; echo \"Skipping cleaning of source file\"</Command>\n"
"         </Block>\n"
"        </SubBlock>\n"
"        <SubBlock number=\"2\" active=\"false\">\n"
"         <Block>\n"
"          <Comment>&lt;p align=\"center\"&gt;This line of command will clean up the source movie&lt;BR&gt;Might not be needed.&lt;/p&gt;</Comment>\n"
"          <Command default=\"true\">ln -s \"+TEMP_PATH+/+MENU_NAME+/background/clip.avi\" \"+TEMP_PATH+/+MENU_NAME+/background/clean.avi\"; echo \"Skipping cleaning of source file\"</Command>\n"
"          <Command>mencoder -oac null -ovc lavc -o \"+TEMP_PATH+/+MENU_NAME+/background/clean.avi\" \"+TEMP_PATH+/+MENU_NAME+/background/clip.avi\"</Command>\n"
"         </Block>\n"
"        </SubBlock>\n"
"        <SubBlock number=\"3\">\n"
"         <Block>\n"
"          <Comment>&lt;p align=\"center\"&gt;Here we extract the audio part of the source background&lt;/p&gt;</Comment>\n"
"          <Command default=\"true\">mplayer -ao pcm:file=\"+TEMP_PATH+/+MENU_NAME+/background/clip.wav\" -vo null -vc dummy \"+TEMP_PATH+/+MENU_NAME+/background/clip.avi\"</Command>\n"
"          <Command>mplayer -ao pcm -vo null -vc dummy -aofile \"+TEMP_PATH+/+MENU_NAME+/background/clip.wav\" \"+TEMP_PATH+/+MENU_NAME+/background/clip.avi\"</Command>\n"
"         </Block>\n"
"        </SubBlock>\n"
"        <SubBlock number=\"4\">\n"
"         <Block>\n"
"          <Comment>&lt;p align=\"center\"&gt;And now we extract the image files of the source movie&lt;/p&gt;</Comment>\n"
"          <Command default=\"true\">mplayer -ao null -vo jpeg:outdir=\"+TEMP_PATH+/+MENU_NAME+/background\" \"+TEMP_PATH+/+MENU_NAME+/background/clean.avi\"</Command>\n"
"         </Block>\n"
"        </SubBlock>\n"
"        <SubBlock number=\"6\">\n"
"         <Block>\n"
"          <Comment>&lt;p align=\"center\"&gt;And this is the place where we internally render the images&lt;/p&gt;</Comment>\n"
"          <Command default=\"true\" canmodify=\"false\">"RENDER_MENU"+MENU_NAME+</Command>\n"
"         </Block>\n"
"        </SubBlock>\n"
"        <SubBlock number=\"5\">\n"
"         <Block>\n"
"          <Comment>&lt;p align=\"center\"&gt;We can remove the big temp files&lt;/p&gt;</Comment>\n"
"          <Command default=\"true\">cd \"+TEMP_PATH+/+MENU_NAME+/\"; find . -name clip.avi -exec rm {} \\;; find . -name clean.avi -exec rm {} \\;</Command>\n"
"         </Block>\n"
"        </SubBlock>\n"
"        <SubBlock number=\"6\">"
"         <Block>\n"
"          <Comment>&lt;p align=\"center\"&gt;This line of command will convert the extracted frames &lt;BR&gt;into a MPEG2 stream in NTSC format +WIDTH+x+HEIGHT+&lt;/p&gt;</Comment>\n"
"          <Command>png2yuv -j \"+TEMP_PATH+/+MENU_NAME+/background/rendered_%08d.png\" -I p -f 29.97 -b 1 | mpeg2enc -f 8 -n n -F 4 -M 1 -o \"+TEMP_PATH+/+MENU_NAME+/menu.m2v\"</Command>\n"
"         </Block>\n"
"        </SubBlock>"
"      </Block>\n"
"      <Block name=\"IMAGE_BACKGROUND\">\n"
"        <Comment>&lt;p align=\"center\"&gt;This line of command will convert the background image&lt;BR&gt;into a MPEG2 stream in NTSC format +WIDTH+x+HEIGHT+&lt;/p&gt;</Comment>\n"
"        <Command>jpegtopnm \"+BACKGROUND_FULL_NAME+\" | ppmtoy4m -n 50 -r -S 420mpeg2 -F30000:1001 -A10:11 -I t -L | mpeg2enc -f 8 -n n -o \"+TEMP_PATH+/+MENU_NAME+/menu.m2v\"</Command>\n"
"        <Command default=\"true\">jpeg2yuv -n 50 -I p -f 29.97 -j \"+BACKGROUND_FULL_NAME+\" | mpeg2enc -n n -f 8 -o \"+TEMP_PATH+/+MENU_NAME+/menu.m2v\"</Command>\n"
"      </Block>\n"
"      <Block name=\"EMPTY_SOUND\">\n"
"        <Comment>&lt;p align=\"center\"&gt;This line creates an empty sound file to mix into the menu-movie.&lt;/p&gt;</Comment>\n"
"        <Command default=\"true\">arecord -f dat -twav -d 1 | mp2enc -r 48000 -o \"+TEMP_PATH+/+MENU_NAME+/menu.mp2\"</Command>\n"
"        <Command>arecord -S -M -t 1 -w /dev/stdout | mp2enc -r 48000 -o \"+TEMP_PATH+/+MENU_NAME+/menu.mp2\"</Command>\n"
"        <Command>sox -t raw -s -w -c 2 -r 48000 /dev/zero -t wav -c 2 -r 48000 /dev/stdout trim 0 1 | mp2enc -r 48000 -o \"+TEMP_PATH+/+MENU_NAME+/menu.mp2\"</Command>\n"
"        <Command>dd if=/dev/zero bs=4 count=1601 | toolame -b128 -s 48000 /dev/stdin \"+TEMP_PATH+/+MENU_NAME+/menu.mp2\"</Command>\n"
"      </Block>\n"
"      <Block name=\"MPLEX\">\n"
"        <Comment>&lt;p align=\"center\"&gt;The following command will multiplex the sound file into the menu-movie.&lt;/p&gt;</Comment>\n"
"        <Command default=\"true\">mplex -f 8 -o \"+TEMP_PATH+/+MENU_NAME+/menu.mpg\" \"+TEMP_PATH+/+MENU_NAME+/menu.m2v\" +SOUND_LIST+</Command>\n"
"      </Block>\n"
"      <Block name=\"SPUMUX\">\n"
"        <Comment>&lt;p align=\"center\"&gt;Here we use spumux to add the subpicture (buttons) the the mpeg2 video.&lt;/p&gt;</Comment>\n"
"        <Command default=\"true\">spumux \"+TEMP_PATH+/+MENU_NAME+/menu.xml\" &lt; \"+TEMP_PATH+/+MENU_NAME+/menu.mpg\" &gt; \"+TEMP_PATH+/+MENU_NAME+_menu.mpg\"</Command>\n"
"      </Block>\n"
"    </Ntsc>\n"
"  </ExecuteInterface>\n"
"  <ExecuteInterface>\n"
"    <Dvdauthor blockname=\"dvdauthor\" color=\"#F92F5E\">\n"
"      <Block>\n"
"        <Comment>Here we start dvdauthor with the generated xml file.</Comment>\n"
"        <Command>dvdauthor -x \"+DVDAUTHOR_XML+\"</Command>\n"
"      </Block>\n"
"    </Dvdauthor>\n"
"  </ExecuteInterface>\n"
"  <ExecuteInterface hidden=\"true\">\n"
"    <Burning blockname=\"Burn DVD\" color=\"#E0EE8F\">\n"
"      <Block>\n"
"        <SubBlock number=\"1\" active=\"true\">\n"
"         <Block>\n"
"          <Comment>Last we burn the DVD.</Comment>\n"
"          <Command>growisofs -Z /dev/dvd -dvd-video +PROJECT_PATH+/</Command>\n"
"         </Block>\n"
"        </SubBlock>\n"
"        <SubBlock number=\"2\" active=\"false\">\n"
"         <Block>\n"
"          <Comment>This command will format a empty -RW DVD (only needed for older drives).</Comment>\n"
"          <Command>dvd+rw-format -f /dev/srcd0</Command>\n"
"         </Block>\n"
"        </SubBlock>\n"
"        <SubBlock number=\"3\" active=\"false\">\n"
"         <Block>\n"
"          <Comment>This command generates an iso image of the DVD.</Comment>\n"
"          <Command>mkisofs -dvd-video -udf -o +TEMP_PATH+/dvd.iso +PROJECT_PATH+/</Command>\n"
"         </Block>\n"
"        </SubBlock>\n"
"        <SubBlock number=\"4\" active=\"false\">\n"
"         <Block>\n"
"          <Comment>This command burns the iso DVD image to DVD</Comment>\n"
"          <Command>dvdrecord -dao speed=2 dev=0,0,0 +TEMP_PATH+/dvd.iso</Command>\n"
"         </Block>\n"
"        </SubBlock>\n"
"      </Block>\n"
"    </Burning>\n"
"  </ExecuteInterface>\n"
"</QDVDAuthorInitFile>\n");
  		stream << qsResetInitFile << "\n";
		initFile.flush ( );
		initFile.close ( );
	}
}

