/****************************************************************************
** templatewizard.cpp file.
**
** This file implements the TemplateWizardDialog.
**
** The following structure is assumed:
** /usr/share/qdvdauthor/template/static/<TemplateName>/<Files>
** /usr/share/qdvdauthor/template/animated/<TemplateName>/<Files>
** /usr/share/qdvdauthor/template/transition/<TemplateName>/<Files>
**
** Here are the files required :
** template.xml -> holds information about the template, such as comment
**                 NrOfDropZones, coordinates of DropZones etc.
** thumbnail.png-> Image to display in selectionBox ( width=200 )
** background/backgroundXXXXX.jpg where XXXXX = sequenceNo. 
** background/background00000.jpg REQUIRED.
** template.mpg -> preview for menus
** dropZone[X].mpg -> default for the dropZone, with X = [1 .. N]
** 
** The requirements are simple: 
** Input, a few user mouse clicks
** Output, one or multiple dvd menu(s)
** 
** Interface to the program : QValueList<DVDMenu *>
** 
*****************************************************************************/

#include <qdir.h>
#include <qtimer.h>
#include <qcursor.h>
#include <qregexp.h>
#include <qlistbox.h>
#include <qpainter.h>
#include <qfileinfo.h>
#include <qiconview.h>
#include <qcombobox.h>

// Include the generated config files ...
#include "CONFIG.h"
#include "xml_dvd.h"
#include "utils.h"
#include "qdvdauthor.h"
#include "dvdmenu.h"
#include "messagebox.h"
#include "filepreviewdialog.h"
#include "buttonobject.h"
#include "movieobject.h"
#include "qplayer/mediainfo.h"
#include "qplayer/mediacreator.h"
#include "qplayer/mediacreator.h"

#include "sourcefileentry.h"
#include "templatewizard.h"

/****************************************************************************
** TemplateFrame - class
**
** Simply there to emit a signal when some one clicks in it.
**
*****************************************************************************/
TemplateFrame::TemplateFrame ( TemplateWizard *pWizard, QWidget *pParent, const char *pName, WFlags flags )
	: QFrame (pParent, pName, flags)
{
	m_pTemplateWizard = pWizard;
	setAcceptDrops (TRUE);
}

TemplateFrame::~TemplateFrame ()
{
}

void TemplateFrame::mouseReleaseEvent ( QMouseEvent *pEvent )
{
	emit (signalMouseReleaseEvent (pEvent));
}

void TemplateFrame::dropEvent (QDropEvent *pDropEvent)
{
	// Simply forward to the main object to handle this event.
	if (m_pTemplateWizard)
		m_pTemplateWizard->droppedSomething (pDropEvent);
}

void TemplateFrame::dragEnterEvent(QDragEnterEvent *pEvent)
{
	// Tell the Widget that we accept QTextDrops ...
	// This is necessary otherwise the dropEvent does not occur.
	pEvent->accept (QTextDrag::canDecode(pEvent));
}

ListBoxToolTip::ListBoxToolTip (QListBox* pListBox) : 
	QToolTip(pListBox->viewport()), 
	m_pListBox(pListBox) 
{
}

void ListBoxToolTip::maybeTip(const QPoint& pos) 
{
	// get pointed item
	QListBoxItem* pItem = m_pListBox->itemAt(pos);
	if (pItem == 0)
		return;
	// show tooltip if item is not fully visible
	QRect r = m_pListBox->itemRect(pItem);
	r.setWidth(pItem->width(m_pListBox));
	if (!m_pListBox->viewport()->rect().contains(r))
		tip(r, pItem->text());
}

TemplateWizard::DropZone::DropZone (int i, QString s, QRect r, QString qsType)
{
	bMovie       = false;
	iNumber      = i; 
	iType        = IgnoreObject;
	qsText       = s; 
	rect         = r;
	pPixmap      = NULL;
	if ( qsType == "ImageObject" )
	  iType = ImageObject;
	else if ( qsType == "MovieObject" )
	  iType = MovieObject;
	else if ( qsType == "TextObject" )
	  iType = TextObject;
	else if ( qsType == "FrameObject" )
	  iType = FrameObject;
}

TemplateWizard::DropZone::~DropZone ()
{
  if ( pPixmap )
    delete pPixmap;
}



TemplateWizard::TemplateWizard( QWidget* parent, const char* name, WFlags fl )
    : uiTemplateWizard( parent, name, fl )
{
	m_pDVDAuthor      = NULL;
	m_pDVDMenu        = NULL;
	m_fScale          = 0.0f;
	m_bDontRestart    = false;
	m_pListBoxToolTip = NULL;
	m_bLocalTemplate  = true;
}

TemplateWizard::~TemplateWizard()
{
	uint t;
	m_bDontRestart = true;
	for (t=0;t<m_listDropZones.count();t++)
		delete m_listDropZones[t];
	if (m_pMediaInterface)	{
		m_pMediaInterface->stop();
		delete m_pMediaInterface;
	}
	if (m_pListBoxToolTip)
		delete m_pListBoxToolTip;
}

void TemplateWizard::hide ()
{
	m_bDontRestart = true;
	if (m_pMediaInterface)
		m_pMediaInterface->stop();

	uiTemplateWizard::hide();
}

// This function refreshes the Templates (in case a new template was added)
// and also the movies on the left side to have the full list of movies available
void TemplateWizard::showDialog ()
{
	show ( );
        initDragList ( );
	initTab ( QString ("static"),     m_pIconViewStatic     );
	initTab ( QString ("animated"),   m_pIconViewAnimated   );
	initTab ( QString ("transition"), m_pIconViewTransition );
}

void TemplateWizard::initMe (QDVDAuthor*pDVDAuthor)
{
	m_pDVDAuthor = pDVDAuthor;
	refreshComboMenu ( );
	setNextEnabled   ( page ( 0 ), false );
	setFinishEnabled ( page ( 1 ), true  );

	// Create the tooltips ...
	m_pListBoxToolTip  = new ListBoxToolTip (m_pListBoxSources);

	// Here we create the main templateFrame
	QGridLayout *WizardPageLayout_2 = new QGridLayout( m_pOuterFrame, 1, 1, 11, 6, "WizardPageLayout_2"); 
	QSpacerItem *spacer1 = new QSpacerItem( 20, 2, QSizePolicy::Minimum, QSizePolicy::Expanding );
	WizardPageLayout_2->addItem( spacer1, 0, 1 );

	m_pFrameProperties = new TemplateFrame( this, m_pOuterFrame, "m_pFrameProperties" );
	m_pFrameProperties->setSizePolicy  ( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)1, 2, 2, m_pFrameProperties->sizePolicy().hasHeightForWidth() ) );
	m_pFrameProperties->setFrameShape  ( QFrame::StyledPanel );
	m_pFrameProperties->setFrameShadow ( QFrame::Raised );
	connect (m_pFrameProperties, SIGNAL(signalMouseReleaseEvent (QMouseEvent *)), this, SLOT(slotTemplateClicked (QMouseEvent *)));

	WizardPageLayout_2->addWidget( m_pFrameProperties, 1, 1 );
	QSpacerItem *spacer1_2 = new QSpacerItem( 20, 2, QSizePolicy::Minimum, QSizePolicy::Expanding );
	WizardPageLayout_2->addItem( spacer1_2, 2, 1 );
	QSpacerItem *spacer3 = new QSpacerItem( 2, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
	WizardPageLayout_2->addItem( spacer3, 1, 2 );
	QSpacerItem *spacer3_2 = new QSpacerItem( 2, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
	WizardPageLayout_2->addItem( spacer3_2, 1, 0 );
    
	connect (m_pComboMenu, SIGNAL(activated (const QString &)), this, SLOT(slotTargetMenuChanged (const QString &)));
	resize( QSize(739, 536).expandedTo(minimumSizeHint()) );
	clearWState( WState_Polished );
	initPreview  ();
	// And finally we connect the listBox to some event handler 
	m_pListBoxSources->setHScrollBarMode(QScrollView::AlwaysOff);
	connect (m_pListBoxSources,    SIGNAL( pressed (QListBoxItem  *)), this, SLOT ( slotListBoxClicked  (QListBoxItem  *)));
	connect (m_pIconViewStatic,    SIGNAL( clicked (QIconViewItem *)), this, SLOT ( slotIconViewClicked (QIconViewItem *)));
	connect (m_pIconViewAnimated,  SIGNAL( clicked (QIconViewItem *)), this, SLOT ( slotIconViewClicked (QIconViewItem *)));
	connect (m_pIconViewTransition,SIGNAL( clicked (QIconViewItem *)), this, SLOT ( slotIconViewClicked (QIconViewItem *)));
	connect (m_pButtonDetails,     SIGNAL( clicked ( ) ),              this, SLOT ( slotTemplateDetails ( ) ) );

	connect (this,                 SIGNAL(helpClicked () ),           this, SLOT(slotHelp () ) );
}

void TemplateWizard::slotPlaybackFinished ()
{
	// TODO: check elapsed time and break this one here if < 2 seconds.
	if ( ! m_bDontRestart )
		m_pMediaInterface->play ();
	m_bDontRestart = false;
}

void TemplateWizard::refreshComboMenu ()
{
	uint t;
	m_pComboMenu->clear ();

	if (m_qsCurrentTemplate.isEmpty())
		m_qsCurrentTemplate = QString ("New Menu");

	if (m_pDVDAuthor)	{
		// Here we ensure we have a unique name
		m_qsCurrentTemplate = m_pDVDAuthor->getUniqueMenuTitle (m_qsCurrentTemplate, 0);
	}
	m_pComboMenu->insertItem (m_qsCurrentTemplate);
	m_pComboMenu->insertItem (VMGM_LABEL);
	if ( ! m_pDVDAuthor )
		return;

	DVDMenu *pMainMenu = m_pDVDAuthor->getVMGMenu ( );
	QValueList<DVDMenu *> listMenus = m_pDVDAuthor->getSubMenus ();
	for (t=0;t<listMenus.count();t++)
		m_pComboMenu->insertItem (listMenus[t]->name());
	// if the main menu is empty, then we should suggest this instead of a new menu ...
	if ( pMainMenu->isEmpty ( ) ) {
	  m_pComboMenu->setCurrentItem  ( 1 );
	  m_pComboMenu->setEditable ( false );
	}
}

void TemplateWizard::initPreview ()
{
	m_pLabelPreview->hide();

	// Here we create the mediaEngine for this dialog.
	MediaInfo *pMediaInfo   = m_pDVDAuthor->getMediaInfo  ();
	void      *pMediaEngine = pMediaInfo->getMediaEngine ();
	m_pMediaInterface = MediaCreator::createPreferredWidget (m_pFramePreview, "TemplateMediaWidget", pMediaEngine);
	connect (m_pMediaInterface, SIGNAL(signalPlaybackFinished()), this, SLOT(slotPlaybackFinished()));
	
	QGridLayout *pVideoLayout = new QGridLayout (m_pFramePreview, 1, 1, 2, 2, "MediaMainLayout");
	pVideoLayout->addWidget (m_pMediaInterface->getWidget(), 0, 0);
	// This is taken care of in the polish () function for Xine and not necessary for MPlayer ...
	m_pMediaInterface->initMediaEngine();
}

void TemplateWizard::initDragList ()
{
	// This function will initialize the ListBox to the left on the second page.
	// It will take the images straight from SourceFileInfo objcts
	uint t, i;
	SourceFileEntry *pEntry;
	SourceFileInfo  *pInfo;
	int iWidth = 125;
	if ( ! m_pDVDAuthor )
		return;
	m_listSourceFileDescriptions.clear ();
	m_pListBoxSources->clear ();
	for (t=0;(int)t<m_pDVDAuthor->sourceFileCount ();t++)	{
		pEntry = m_pDVDAuthor->sourceFileEntry(t);
		if ( ! pEntry )
			continue;
		if (pEntry->bSoundSource)
			continue;
		for (i=0;i<pEntry->listFileInfos.count (); i++)	{
			pInfo = pEntry->listFileInfos[i];
			if ( ( ! pInfo ) || ( ! pInfo->pPreview ) )
				continue;
			QImage tempImage ( *pInfo->pPreview );
			m_pListBoxSources->insertItem (tempImage.smoothScale (iWidth, iWidth, QImage::ScaleMin), pInfo->qsFileName);
			m_listSourceFileDescriptions.append (QString ("%1 : %2").arg(pInfo->qsFileName).arg(pInfo->qsSize));
		}
	}
}

void TemplateWizard::initTab (QString qsWhichTab, QIconView *pIconView)
{
  uint t,  i, iTemplatePath;
  bool        bContinue;
  QStringList listTemplates;
  QString     qsPrefixDir, qsPixmap, qsXMLFile, qsBackgroundFile, qsHomeDir, qsTemplateName;
  QFileInfo   fileInfo;
  QPixmap     thePixmap;
  QDir        theTemplates; 
  QStringList listOfTemplates; // used to keep count of templates
  QSize grid (50, 50);
  qsHomeDir = QDir::homeDirPath ( );

  pIconView->clear ( );
  qsPrefixDir = QString ( "%1/.qdvdauthor/%2" ).arg ( qsHomeDir ).arg ( qsWhichTab );
  for ( iTemplatePath=0;iTemplatePath<2;iTemplatePath++ ) {
    
    if ( ! theTemplates.exists (qsPrefixDir) ) {
      if ( iTemplatePath == 0 )
	continue;
      if ( listOfTemplates.count () < 1 )
	new QIconViewItem (pIconView, tr ("No %1 templates found.").arg (qsWhichTab));
      return;
    }
    
    pIconView->arrangeItemsInGrid ( grid, TRUE );
    
    theTemplates.cd ( qsPrefixDir, TRUE );
    listTemplates = theTemplates.entryList ( QDir::Dirs, QDir::Name );
    if (listTemplates.count ( ) < 3)	{ // 3 = this dir / parent dir / background file
      if ( iTemplatePath == 0 )
	continue;
      if ( listOfTemplates.count ( ) < 1 )
	new QIconViewItem (pIconView, tr ("No %1 Backgrounds in dir :\n%2").arg(qsWhichTab).arg(qsPrefixDir));
      return;
    }
    for (t=0;t<listTemplates.count ();t++)	{
      // Here we go through all directories and check if the preview is present.
      // if so, then we snap the preview.jpg and create a ListItem
      qsTemplateName = listTemplates[t];
      if ( ( qsTemplateName == ".") || ( qsTemplateName == "..") )
	continue;
      // next we check if the Local Templates already defined this one
      bContinue = false;
      for (i=0;i<listOfTemplates.count();i++) {
	if ( listOfTemplates[i] == qsTemplateName ) {
	  bContinue = true;
	}
      }
      if ( bContinue )
	continue;

      qsPixmap = QString ("%1/%2/%3").arg(qsPrefixDir).arg(qsTemplateName).arg("thumbnail.png");
      fileInfo.setFile (qsPixmap);
      if ( ! fileInfo.exists() )
	continue;
      qsXMLFile = QString ("%1/%2/%3").arg(qsPrefixDir).arg( qsTemplateName ).arg("template.xml");
      fileInfo.setFile (qsXMLFile);
      if ( ! fileInfo.exists() )
	continue;
      qsBackgroundFile = QString ("%1/%2/background/background00000.jpg").arg(qsPrefixDir).arg( qsTemplateName);
      fileInfo.setFile (qsBackgroundFile);
      if ( ! fileInfo.exists() )
	continue;
      listOfTemplates.append ( qsTemplateName );
      thePixmap = QPixmap (qsPixmap);
      new QIconViewItem (pIconView, qsTemplateName, thePixmap);
    }
    // for the second run we'll get the system wide installed Templates.
    // Note: lcally installed Templates overrule System wide installed Templates.
    qsPrefixDir = QString ("%1/share/qdvdauthor/%2").arg(PREFIX_DIRECTORY).arg(qsWhichTab);
  }
}
/*
void TemplateWizard::initTab (QString qsWhichTab, QIconView *pIconView)
{
	uint t;
	QStringList listTemplates;
	QIconViewItem *pItem;
	QString qsPrefixDir, qsPixmap, qsXMLFile, qsBackgroundFile;
	QFileInfo fileInfo;
	QPixmap thePixmap;
	QDir theTemplates; 
	QSize grid (50, 50);
	qsPrefixDir = QString ("%1/share/qdvdauthor/%2").arg(PREFIX_DIRECTORY).arg(qsWhichTab);

	pIconView->clear ( );
	if ( ! theTemplates.exists (qsPrefixDir) )	{
	  new QIconViewItem (pIconView, tr ("Warning no dir :\n%1").arg (qsPrefixDir));
	  return;
	}

	pIconView->arrangeItemsInGrid (grid, TRUE);
	
	theTemplates.cd   (qsPrefixDir, TRUE);
	listTemplates = theTemplates.entryList (QDir::Dirs, QDir::Name);
	if (listTemplates.count () < 3)	{
	  new QIconViewItem (pIconView, tr ("No %1 Backgrounds in dir :\n%2").arg(qsWhichTab).arg(qsPrefixDir));
	  return;
	}
	for (t=0;t<listTemplates.count ();t++)	{
		// Here we go through all directories and check if the preview is present.
		// if so, then we snap the preview.jpg and create a ListItem
		if ( (listTemplates[t] == ".") || (listTemplates[t] == ".") )
			continue;
		qsPixmap = QString ("%1/%2/%3").arg(qsPrefixDir).arg(listTemplates[t]).arg("thumbnail.png");
		fileInfo.setFile (qsPixmap);
		if ( ! fileInfo.exists() )
			continue;
		qsXMLFile = QString ("%1/%2/%3").arg(qsPrefixDir).arg(listTemplates[t]).arg("template.xml");
		fileInfo.setFile (qsXMLFile);
		if ( ! fileInfo.exists() )
			continue;
		qsBackgroundFile = QString ("%1/%2/background/background00000.jpg").arg(qsPrefixDir).arg(listTemplates[t]);
		fileInfo.setFile (qsBackgroundFile);
		if ( ! fileInfo.exists() )
			continue;
		thePixmap = QPixmap (qsPixmap);
		new QIconViewItem (pIconView, listTemplates[t], thePixmap);
	}
	connect (pIconView, SIGNAL(clicked (QIconViewItem *)), this, SLOT(slotIconViewClicked (QIconViewItem *)));
}
*/
void TemplateWizard::slotIconViewClicked (QIconViewItem *pIconViewItem)
{
  // The user clicked one of the Icons, 
  // so we should get the information, and read in the description from template.xml
  if ( ! pIconViewItem )
    return;
  QString qsDescription, qsFileName, qsType;
  QPixmap thumbnail;
  QFile   theFile;
  QDir    theDir;
  
  // First we determine where the click came from
  m_bDontRestart = true;
  m_pMediaInterface->stop ();
  qsType = "static";
  if (m_pIconViewAnimated->index (pIconViewItem) != -1)
    qsType = "animated";
  if (m_pIconViewTransition->index (pIconViewItem) != -1)
    qsType = "transition";
  m_qsPathName =  QString ("%1/.qdvdauthor/%2/%3/").arg( QDir::homeDirPath () ).arg( qsType ).arg(pIconViewItem->text());
  m_bLocalTemplate = true;
  
  // check if this is a local template or a system wide installed template.
  if ( ! theDir.exists ( m_qsPathName ) ) {
    m_bLocalTemplate = false;
    m_qsPathName = QString ("%1/share/qdvdauthor/%2/%3/").arg(PREFIX_DIRECTORY).arg( qsType ).arg(pIconViewItem->text());
  }
  
  QFileInfo fileInfo ( m_qsPathName + QString ( "thumbnail.mpg" ) );
  if ( fileInfo.exists ( ) ) {
    m_pLabelPreview->hide();
    m_pFramePreview->show();
    // first we get the right frame size ...
    thumbnail = QPixmap( m_qsPathName+QString ( "thumbnail.png" ) );
    fileInfo.setFile   ( m_qsPathName+QString ( "thumbnail.png" ) );
    if ( fileInfo.exists ( ) )
      m_pFramePreview->setFixedSize ( thumbnail.size ( ) );
    else
      m_pFramePreview->setFixedSize ( 200, 150 );
      
    theFile.setName ( m_qsPathName+QString ( "thumbnail.mpg" ) );
    m_pMediaInterface->playMRL ( m_qsPathName + QString ( "thumbnail.mpg" ) );
    m_bDontRestart = false;
  }
  else { 
    thumbnail = QPixmap(m_qsPathName+QString ("thumbnail.png"));
    m_pLabelPreview->show ( );
    m_pFramePreview->hide ( );
    m_pLabelPreview->setPixmap    ( thumbnail );
    m_pLabelPreview->setFixedSize ( thumbnail.size ( ) );
  }

  qsFileName = m_qsPathName + QString ("template.xml");
  qsDescription = readProjectFile (qsFileName, true);
  m_pLabelTemplateDescription->setText (qsDescription);
  refreshComboMenu ();
  m_pComboMenu->setEditable ( true );
  setNextEnabled ( page (0), true );
}

void TemplateWizard::slotTemplateDetails ( )
{
  QString qsInfo;

  qsInfo  = QString ( "Template Name : <B>%1</B><P>" ).arg ( m_qsCurrentTemplate );
  qsInfo += QString ( "Author        : <B>%1</B><BR>").arg ( m_qsTemplateAuthor  );
  qsInfo += QString ( "Contact       : <B>%1</B><BR>").arg ( m_qsTemplateContact );
  qsInfo += QString ( "Version       : <B>%1</B><P>" ).arg ( m_qsTemplateVersion );
  qsInfo += QString ( "Description   : <B>%1</B><P>" ).arg ( m_qsTemplateDescription );
  qsInfo += QString ( "Comment       : <B>%1</B><P>" ).arg ( m_qsTemplateComment );

  MessageBox::html ( this, tr ( "Details for template." ), qsInfo );  
}

void TemplateWizard::slotListBoxClicked (QListBoxItem *pItem)
{
	int iIndex;
	iIndex = m_pListBoxSources->index (pItem);
	if (iIndex < 0 || iIndex > (int)m_listSourceFileDescriptions.count () - 1)
		return;
	m_pLabelInfo->setText (m_listSourceFileDescriptions[iIndex]);
	// Last we create a dragObject ...
	QDragObject *d = new QTextDrag( m_listSourceFileDescriptions[iIndex], this );
	d->setPixmap (QPixmap (*pItem->pixmap ()));
	d->dragCopy();
}

void TemplateWizard::droppedSomething (QDropEvent *pDropEvent)
{
  uint t, i, iHeight;
  QImage  theImage;
  QString theText;
  QPoint  thePos;
  DropZone *pDropZone = NULL;
  SourceFileEntry *pEntry = NULL;
  SourceFileInfo  *pInfo  = NULL;

  if ( ! QTextDrag::decode(pDropEvent, theText) )
    return;
  
  // The first step is to verify that it was dropped over a DropZone.
  thePos.setX ((int)(pDropEvent->pos().x () / m_fScale));
  thePos.setY ((int)(pDropEvent->pos().y () / m_fScale));
  
  for (t=0;t<m_listDropZones.count();t++)	{
    if (m_listDropZones[t]->rect.contains (thePos))	{
      pDropZone = m_listDropZones[t];
      break;
    }
  }
  if ( ! pDropZone )
    return;
  
  // Get the previewImage ...
  if (m_pDVDAuthor)	{
    for (t=0;(int)t<m_pDVDAuthor->sourceFileCount(); t++)	{
      pEntry = m_pDVDAuthor->sourceFileEntry ( t );
      for (i=0;i<pEntry->listFileInfos.count();i++)	{
	if ( (pEntry)  &&  (theText.contains (pEntry->listFileInfos[i]->qsFileName) > 0 ) )	{
	  pDropZone->qsFileName   = pEntry->listFileInfos[i]->qsFileName;
	  pInfo = pEntry->listFileInfos[i];
	  // Exit both loops ...
	  t = m_pDVDAuthor->sourceFileCount();
	  i = pEntry->listFileInfos.count  ();
	}
      }
    }
  }
  pDropZone->bMovie = true;

  if ( ( pDropZone->iType != DropZone::TextObject ) && ( pDropZone->iType != DropZone::FrameObject ) )  {
    if (pInfo && pInfo->pPreview) {
      float fRatio = (float)pInfo->pPreview->height ( ) / pInfo->pPreview->width ( );
      // for the templates we want to use the width as our ruler (I.e. adjust the height of the image according to the ratio
      iHeight = (int)(fRatio * pDropZone->rect.width ( ) );
      theImage = pInfo->pPreview->smoothScale ((int)(m_fScale*pDropZone->rect.width ( ) ),(int)(m_fScale * iHeight), QImage::ScaleMin);
      //theImage = pInfo->pPreview->smoothScale ((int)(m_fScale*pDropZone->rect.width()), (int)(m_fScale * pDropZone->rect.height()), QImage::ScaleMin);
    }
    else	{
      theImage = QImage().fromMimeSource( "error.jpg" );
      theImage = theImage.smoothScale ((int)(m_fScale*pDropZone->rect.width()), (int)(m_fScale * pDropZone->rect.height()), QImage::ScaleFree );
    }
    // Set the DropZoneValues ...
    // Note: theText is "$FileName : $size" so that does not work.
    // pDropZone->qsFileName = theText;
    if (pDropZone->pPixmap)
      delete pDropZone->pPixmap;
    pDropZone->pPixmap = new QPixmap;
    pDropZone->pPixmap->convertFromImage (theImage);
  }
  refreshBackground ();
}

void TemplateWizard::slotTargetMenuChanged (const QString &qsMenuName)
{
	// Here we check if we have a new or an existing menu.
	bool bEditable = true;

	if ( m_pDVDAuthor )	{
		if (m_pDVDAuthor->getSubMenuByName (qsMenuName))
			bEditable = false;
	}
	m_pComboMenu->setEditable ( bEditable );
}

void TemplateWizard::slotTemplateClicked (QMouseEvent *pMouseEvent)
{
  uint t;
  QPoint mousePos;
  QString qsFileName, qsFilter, qsExtensions;
  DropZone *pDropZone = NULL;
  
  mousePos.setX ((int)( pMouseEvent->pos ().x() / m_fScale ));
  mousePos.setY ((int)( pMouseEvent->pos ().y() / m_fScale ));
  
  for (t=0;t<m_listDropZones.count();t++)	{
    if (m_listDropZones[t]->rect.contains (mousePos))	{
      pDropZone = m_listDropZones[t];
      break;
    }
  }
  if ( ! pDropZone )
    return;
  
  qsFilter   = m_pDVDAuthor->getImageFilter ();
  qsFilter  += " " + m_pDVDAuthor->getMovieFilter ();
  qsFileName = FilePreviewDialog::getOpenFileName ( NULL, Global::qsCurrentPath, tr ("Images/Movies (") + qsFilter + QString (")"));
  if (qsFileName.isNull())
    return;

  QImage theImage;
  Utils  theUtil;

  QFileInfo backgroundInfo (qsFileName);
  MediaInfo *pMediaInfo = m_pDVDAuthor->getMediaInfo ();

  Global::qsCurrentPath = backgroundInfo.absFilePath();
  
  pDropZone->qsFileName = qsFileName;
  qsExtensions = pMediaInfo->getExtensions (true);
  if (qsExtensions.find ("."+backgroundInfo.extension(FALSE), 0, FALSE) > -1)	{
    pDropZone->bMovie = true;
    if ( ( pDropZone->iType == DropZone::TextObject ) || ( pDropZone->iType == DropZone::FrameObject ) ) {
      refreshBackground ( );
      return;
    }
    // Okay let us get the first frame of the game as a screenshot ...
    pMediaInfo->setFileName(qsFileName);
    theImage = pMediaInfo->getScreenshot(0);
    // The we save the screenshot in the temp dir
    qsFileName = theUtil.getTempFile(backgroundInfo.baseName())+QString (".png");
    theImage.save (qsFileName, "PNG");
  }
  else	// Not a movie file, then we should reset this ...
    theImage = QImage(qsFileName);
  
  if ( ( pDropZone->iType != DropZone::TextObject ) && ( pDropZone->iType != DropZone::FrameObject ) ) {
    theImage = theImage.smoothScale ((int)(m_fScale*pDropZone->rect.width()), (int)(m_fScale * pDropZone->rect.height()), QImage::ScaleMin);
    
    if (pDropZone->pPixmap)
      delete pDropZone->pPixmap;
    pDropZone->pPixmap = new QPixmap;
    pDropZone->pPixmap->convertFromImage (theImage);
  }
  refreshBackground ();
}

QString TemplateWizard::readProjectFile (QString qsFileName, bool bHeaderOnly)
{
	QDomDocument xmlDoc( TEMPLATE_DOCTYPE );
	QDomElement  docElem;
	QDomNode     xmlNode;
	int          iX, iY, iWidth, iHeight, iDropZoneNumber;
	uint         t;
	QString      text, qsDropZoneType;
	QRect        rectDropZone;
	// First we take care of the QDVDAuthor variables ...
	QString  qsTemplateName;
	QDomAttr attribute;

	QFile templateFile (qsFileName);
	if ( ! templateFile.open(IO_ReadWrite))
		return qsTemplateName;
	
	if (!xmlDoc.setContent (&templateFile))	{
		// Error handling ...
		templateFile.close();
		MessageBox::warning ( this, tr ("xml template file seems to be defective."),
			tr ("Please try another template file."),
			QMessageBox::Ok, QMessageBox::NoButton);
		return qsTemplateName;
	}

	m_qsTemplateVersion     = "";
	m_qsTemplateAuthor      = "";
	m_qsTemplateContact     = "";
	m_qsTemplateHeader      = "";
	m_qsTemplateDescription = "";
	m_qsTemplateComment     = "";	

	for (t=0;t<m_listDropZones.count ();t++)
		delete m_listDropZones[t];
	m_listDropZones.clear ();

	// Here is the main loop to extract the info ...
	docElem = xmlDoc.documentElement();
	xmlNode = docElem.firstChild();

	attribute = docElem.attributeNode ( TEMPLATE_NAME );
	if (!attribute.isNull())	{
		qsTemplateName = attribute.value();
		m_qsCurrentTemplate = qsTemplateName;
	}
	attribute = docElem.attributeNode ( TEMPLATE_VERSION );
	if (!attribute.isNull())	{
		QString qsTemplateVersion = attribute.value();
		if ( qsTemplateVersion.toFloat ( ) > TEMPLATE_VERSION_NUMBER+0.09 ) {
		  QMessageBox::information ( NULL, tr ("Template too new"), 
		      tr ("The template was created with an newer version of QDVDAuthor.\nNot all features might work properly.\nPlease consider upgrading to the latest QDVDAuthor version.\n"), 
		      QMessageBox::Ok,  QMessageBox::NoButton);
		}
	}

	while( !xmlNode.isNull() ) {
		QDomElement searchXMLTree = xmlNode.toElement();
		// Okay, here we retain the stored data from the xml file.
		QString tagName  = searchXMLTree.tagName();
		QString nodeText = searchXMLTree.text ();
		// Okay, this is ugly but after all it is the simplest of all xml file structure.
		// No need to get fancy ...
		if ( TEMPLATE_VERSION == tagName )
			m_qsTemplateVersion = nodeText;
		else if ( TEMPLATE_AUTHOR == tagName )
			m_qsTemplateAuthor = nodeText;
		else if ( TEMPLATE_CONTACT == tagName )
			m_qsTemplateContact = nodeText;
		else if ( TEMPLATE_HEADER == tagName )
			m_qsTemplateHeader = nodeText;
		else if ( TEMPLATE_DESCRIPTION == tagName )
			m_qsTemplateDescription = nodeText;
		else if ( TEMPLATE_COMMENT == tagName )
			m_qsTemplateComment = nodeText;
		else if ( ( TEMPLATE_DROPZONE == tagName ) && (!bHeaderOnly) )	{
			attribute = searchXMLTree.attributeNode ( TEMPLATE_DROPZONE_TYPE);
			qsDropZoneType = attribute.value( );
			attribute = searchXMLTree.attributeNode ( TEMPLATE_DROPZONE_NUMBER);
			iDropZoneNumber = attribute.value().toInt();
			attribute = searchXMLTree.attributeNode ( TEMPLATE_DROPZONE_X);
			iX = attribute.value().toInt();
			attribute = searchXMLTree.attributeNode ( TEMPLATE_DROPZONE_Y);
			iY = attribute.value().toInt();
			attribute = searchXMLTree.attributeNode ( TEMPLATE_DROPZONE_WIDTH);
			iWidth = attribute.value().toInt();
			attribute = searchXMLTree.attributeNode ( TEMPLATE_DROPZONE_HEIGHT);
			iHeight = attribute.value().toInt();
			rectDropZone = QRect(iX, iY, iWidth, iHeight);
			DropZone *pDropZone = new DropZone ( iDropZoneNumber, text, rectDropZone, qsDropZoneType );
			m_listDropZones.append (pDropZone);
		}
		else if ( (TEMPLATE_DATA == tagName ) && (!bHeaderOnly) )	{
			m_qsXMLDVDMenu = searchXMLTree.text();
		}
		// So lets get the next sibling ... until we hit hte end of DVDMenu ...
		xmlNode = xmlNode.nextSibling();
	}
	templateFile.close();

	// Okay, once something has been selected means we keep this and enable the next button
	nextButton()->setEnabled (true);
	
	return m_qsTemplateDescription;;
}

/**
 * This function is called when the user clicks on the next button.
 */
void TemplateWizard::next ()
{
	QString qsFileName;
	// The user clicked the next button.
	if (m_qsPathName.isEmpty ())
		return;
	if ( ! m_pComboMenu->editable() )	{
		DVDMenu *pDVDMenu = m_pDVDAuthor->getSubMenuByName(m_pComboMenu->currentText());
		if ( ( pDVDMenu) && ( ! pDVDMenu->isEmpty () ) )	{
			if (QMessageBox::information (NULL, tr ("Override Menu"), tr ("Warning the menu %1 will be replaced.\nAre you sure ?").arg (m_pComboMenu->currentText()), QMessageBox::Yes,  QMessageBox::No) == QMessageBox::No)
			return;
		}
	}

	QWizard::next ();
	// At this point we should be on the other side ...
	// So first we read in the whole project file.
	qsFileName = m_qsPathName + QString ("template.xml");
	readProjectFile (qsFileName, false);
	// Then we build a simple GUI for the user to provide the neccesary files
	refreshBackground ();
}

void TemplateWizard::refreshBackground ()
{
  uint      t;
  int       iTemp, iX, iY;
  QPixmap   thePixmap;
  QImage    theImage;
  QString   qsFileName;
  QRect     tempRect;
  DropZone *pDropZone;

  theImage = QImage (m_qsPathName + QString ("preview.png"));
  theImage = theImage.smoothScale (m_pFrameProperties->width(), m_pFrameProperties->height(), QImage::ScaleMin);
  thePixmap.convertFromImage(theImage);
  // Next we draw the black DropZones ...
  m_fScale = (float)thePixmap.width() / 720.0;
  QPainter painter( &thePixmap );
  for (t=0;t<m_listDropZones.count();t++)	{
    pDropZone = m_listDropZones[t];
    //    if (m_listDropZones[t]->pPixmap == NULL)	{
    if ( pDropZone->qsFileName.isNull ( ) )	{
      tempRect.setX      ( (int)( m_fScale *  pDropZone->rect.x ( ) ) );
      tempRect.setY      ( (int)( m_fScale *  pDropZone->rect.y ( ) ) );
      tempRect.setWidth  ( (int)( m_fScale * (pDropZone->rect.width ( )+2 ) ) );
      tempRect.setHeight ( (int)( m_fScale * (pDropZone->rect.height( )+2 ) ) );
      painter.setBrush   ( Qt::black  );
      painter.setPen     ( Qt::yellow );
      painter.drawRect ( tempRect ); // nothing dropped in it yet
      painter.drawText ( tempRect, Qt::AlignCenter|Qt::DontClip, QString ( "%1" ).arg ( pDropZone->iNumber + 1 ) );
    }
    else	{
      if ( ( pDropZone->iType != DropZone::TextObject  ) && 
	   ( pDropZone->iType != DropZone::FrameObject )  ) {
	iTemp = (int)( m_fScale * pDropZone->rect.width  ( ) ) - pDropZone->pPixmap->width ( );
	iX    = (int)( m_fScale * pDropZone->rect.x ( ) + (int)(iTemp/2.0));
	iTemp = (int)( m_fScale * pDropZone->rect.height ( ) ) - pDropZone->pPixmap->height ( );
	iY    = (int)( m_fScale * pDropZone->rect.y ( ) + (int)(iTemp/2.0 ) );
	painter.drawPixmap ( iX, iY, *( pDropZone->pPixmap ) );
      }
    }
  }
  m_pFrameProperties->setFixedWidth  ( thePixmap.width  ( ) );
  m_pFrameProperties->setFixedHeight ( thePixmap.height ( ) );
  m_pFrameProperties->setBackgroundPixmap  ( thePixmap );
}

DVDMenu *TemplateWizard::getMenu ()
{
	return m_pDVDMenu;
}

QString TemplateWizard::getSourceEntryName (QString qsFileName)
{
  // This function will check if the file is already part of a SourceFileEntry.
  uint t, i;
  QString qsEntryName;
  SourceFileEntry *pEntry;
  
  if ( m_pDVDAuthor ) {

    for (t=0;(int)t<m_pDVDAuthor->sourceFileCount ();t++)	{
      pEntry = m_pDVDAuthor->sourceFileEntry(t);
      for (i=0;i<pEntry->listFileInfos.count();i++)	{
	if (pEntry->listFileInfos[i]->qsFileName == qsFileName)	{
	  qsEntryName = pEntry->qsDisplayName;
	  return qsEntryName;
	}
      }
    }
  }
  return qsEntryName;
}
  
void TemplateWizard::slotHelp ()
{
  QString qsHeader, qsHtml;
  qsHeader = tr ("Wizard for templstes.");

  qsHtml  = tr ( "Select <B>One</B> of the templates you like to use and click on [<B>Next ></B>]<P>" );
  qsHtml += tr ( "Don't forget to define if you want to add a new menu or if you wnt to replace an existing menu. This can be done by the ComboBox on the right.<P>" );

  qsHtml += tr ( "In the second stage you have to assign the objects to the DropZones.");
  qsHtml += tr ( "You can do this by dragging the movie from the left side or by clicking into the DropZone itself.<P>" );

  MessageBox::html ( NULL, qsHeader, qsHtml );
}

void TemplateWizard::reject ()
{
	if (m_pDVDMenu)
		delete m_pDVDMenu;
	m_pDVDMenu = NULL;
	QWizard::reject();
}

void TemplateWizard::accept ()
{
	// First we are going to replace the DropZone placeholder and then create a DVDMenu.
	uint t;
	int i, iFreeSlot, iX, iY, iWidth, iHeight;
	QString qsAction, qsEntryName, qsEntry, qsPrefixDir, qsMenuName, qsGeometry, qsCurrentPath, qsType;
	QFileInfo fileInfo;
	QStringList listAddMovies;
 
	QCursor myCursor (QCursor::WaitCursor);
	setCursor(myCursor);
	qsCurrentPath = Global::qsCurrentPath;
	iFreeSlot = m_pDVDAuthor->getFreeSourceSlot ();
	qsEntryName.sprintf ("[%02d] - source", iFreeSlot);
	
	qsPrefixDir = QString ("%1/.qdvdauthor/").arg( QDir::homeDirPath () );
	if ( ! m_bLocalTemplate ) 
	  qsPrefixDir = QString ("%1/share/qdvdauthor/").arg( PREFIX_DIRECTORY );

	m_qsXMLDVDMenu.replace (QString ("+PREFIX_DIRECTORY+"), qsPrefixDir);
	for (t=0;t<m_listDropZones.count();t++)	{
		i = m_listDropZones[t]->iNumber;
		if (m_listDropZones[t]->qsFileName.isEmpty())	{
			m_qsXMLDVDMenu.replace (QString ("+DROP_ZONE_%1_OBJECT_TYPE+").arg(i), QString ("IgnoreObject"));
			m_qsXMLDVDMenu.replace (QString ("+DROP_ZONE_%1_BUTTON+").arg(i), QString ("IgnoreObject"));
			m_qsXMLDVDMenu.replace (QString ("+DROP_ZONE_%1_FILE_NAME+").arg(i), QString ());
			m_qsXMLDVDMenu.replace (QString ("+DROP_ZONE_%1_BASE_NAME+").arg(i), QString ());
			m_qsXMLDVDMenu.replace (QString ("+DROP_ZONE_%1_GEOMETRY+").arg(i), QString ());
			m_qsXMLDVDMenu.replace (QString ("+DROP_ZONE_%1_MOVIE_SIZE+").arg(i), QString ());
			m_qsXMLDVDMenu.replace (QString ("+DROP_ZONE_%1_ACTION+").arg(i), QString ());
			continue;
		}
		
		{ // Next we check this ButtonObject for SourceEntry and set it accordingly
		  QString qsButtonXml, qsPattern, qsSourceEntry;
		  QRegExp rx;
		  // Determine the EntryName by parsing through the currently existng SourceFileEntries and trying to find the defined file.
		  qsSourceEntry = getSourceEntryName ( m_listDropZones[t]->qsFileName );
		  if ( qsSourceEntry.isEmpty ( ) ) // If this movie is not yet in a SourceFileEntry, then use he newly created one.
		       qsSourceEntry = qsEntryName;
		  rx.setMinimal ( true );
		  qsPattern = QString ( "DROP_ZONE_%1_BUTTON[^>]*>.*</.DROP_ZONE_%2_BUTTON.>" ).arg ( i ).arg ( i );		  
		  rx.setPattern ( qsPattern );
		  
		  if ( m_qsXMLDVDMenu.find ( rx ) > -1 ) {
		    qsButtonXml = rx.cap ( 0 );
		    if ( qsButtonXml.find ( "+DROP_ZONE_SOURCE_ENTRY+" ) > -1 )
		      qsButtonXml.replace ( "+DROP_ZONE_SOURCE_ENTRY+", qsSourceEntry );
		    else // Could not find in template ... create on the spot.
		      qsButtonXml.replace ( "Action=", "SourceEntry=\"" + qsSourceEntry + "\" Action=" );
		  }
		  // TODO: fix this function ...
		  adjustPixmapHeight ( m_listDropZones[t]->pPixmap, qsButtonXml );

		  m_qsXMLDVDMenu.replace ( rx, qsButtonXml );
		} // end of replacing this buttonObjects DROP_ZONE_SOURCE_ENTRY ...

		fileInfo.setFile ( m_listDropZones[t]->qsFileName );
		// Next we take care of the geometry
		iWidth = iHeight = 0;
		// the pixmap should have the real extensions of the Object
		if ( m_listDropZones[t]->pPixmap ) {
		  iWidth  = (int) ( m_listDropZones[t]->pPixmap->width ( ) / m_fScale + 0.5 );
		  iHeight = (int) ( m_listDropZones[t]->pPixmap->height( ) / m_fScale + 0.5 );
		}
		if ( iWidth  < 2 )
		     iWidth  = m_listDropZones[t]->rect.width ( );
		if ( iHeight < 2 )
		     iHeight = m_listDropZones[t]->rect.height( );
		iX = (int)((m_listDropZones[t]->rect.width () - iWidth )/2.0 + m_listDropZones[t]->rect.x());
		iY = (int)((m_listDropZones[t]->rect.height() - iHeight)/2.0 + m_listDropZones[t]->rect.y());
		qsGeometry = QString (" X=\"%1\" Y=\"%2\" Width=\"%3\" Height=\"%4\" ").arg(iX).arg(iY).arg(iWidth).arg(iHeight);

		m_qsXMLDVDMenu.replace (QString ("+DROP_ZONE_%1_FILE_NAME+").arg(i), fileInfo.absFilePath());
		m_qsXMLDVDMenu.replace (QString ("+DROP_ZONE_%1_BASE_NAME+").arg(i), fileInfo.baseName());
//		m_qsXMLDVDMenu.replace (QString ("+DROP_ZONE_%1_BASE_NAME+").arg(i), fileInfo.fileName());
		m_qsXMLDVDMenu.replace (QString ("+DROP_ZONE_%1_BUTTON+").arg(i), QString ("ButtonObject"));
		m_qsXMLDVDMenu.replace (QString ("+DROP_ZONE_%1_GEOMETRY+").arg(i), qsGeometry);
		qsType = "ImageObject"; // default
		if ( m_listDropZones[t]->bMovie)
		  qsType = "MovieObject";
		// Note we do not want to change Frames or text ...
		if ( m_listDropZones[t]->iType == DropZone::TextObject )
		  qsType = "TextObject";
		else if ( m_listDropZones[t]->iType == DropZone::FrameObject )
		  qsType = "FrameObject";

		if (m_listDropZones[t]->bMovie)	{
			// Note: if we find the file already in a SourceFileEntry, then we do not need to add it again.
			qsEntry = getSourceEntryName (m_listDropZones[t]->qsFileName);
			if (qsEntry.isEmpty())	{ // If nothing has been found in the current SourceFileEntry list
				qsEntry = qsEntryName;
				listAddMovies.append (m_listDropZones[t]->qsFileName);
			}
			qsEntry.replace ("<", "&lt;");
			qsEntry.replace (">", "&gt;");
			qsAction = QString ( "jump+-+%1+-+%2+-+00:00:00.000").arg(qsEntry).arg(fileInfo.fileName ( ) );
			m_qsXMLDVDMenu.replace ( QString ( "+DROP_ZONE_%1_OBJECT_TYPE+").arg( i ),  qsType  );
			m_qsXMLDVDMenu.replace ( QString ( "+DROP_ZONE_%1_MOVIE_SIZE+" ).arg( i ),  QString ( "720x480" ) );
		}
		else	{	// The image button should jump to the MainMenu  jump+-+vmgm+-+
			qsAction = QString ("jump+-+vmgm+-+");
			m_qsXMLDVDMenu.replace (QString ("+DROP_ZONE_%1_OBJECT_TYPE+").arg(i), qsType );
		}
		m_qsXMLDVDMenu.replace (QString ("+DROP_ZONE_%1_ACTION+").arg(i), qsAction);
	}
	// In case we missed one ...
	m_qsXMLDVDMenu.replace (QString ("+DROP_ZONE_SOURCE_ENTRY+"), qsEntryName);

	if (listAddMovies.count())
		m_pDVDAuthor->addMovieList (listAddMovies, &qsEntryName);

	// Lastly we replace <MenuSound> with a real deal 
	handleMenuAudio ( );

	QDomDocument domDoc;
	int iRow, iCol;
	QString qsError;

	iRow = iCol = 0;
	domDoc.setContent (m_qsXMLDVDMenu, true, &qsError, &iRow, &iCol);
	//printf ("\n\n%s\n\n", (const char *)m_qsXMLDVDMenu);
	QDomElement  menuElement = domDoc.documentElement();
	if (m_pDVDMenu)
		delete m_pDVDMenu;

	// if the menu exist we take this one over
	m_pDVDMenu = m_pDVDAuthor->getSubMenuByName(m_pComboMenu->currentText());
	if ( m_pDVDMenu )	{
		qsMenuName = m_pComboMenu->currentText();
		m_pDVDMenu->clear ();
		m_pDVDMenu->readProjectFile(menuElement);
		m_pDVDMenu->getInterface()->qsMenuName = qsMenuName;
		m_pDVDMenu->setTabLabel (qsMenuName);
		m_pDVDMenu->updateDVDMenu();
	}
	else	{ // Otherwise we will create a new menu.
		m_pDVDMenu = new DVDMenu(m_pDVDAuthor);
		qsMenuName = m_pDVDAuthor->getUniqueMenuTitle (m_pComboMenu->currentText(), 0);
		m_pDVDMenu->readProjectFile(menuElement);
		m_pDVDMenu->getInterface()->qsMenuName = qsMenuName;
		m_pDVDMenu->setTabLabel (qsMenuName);
		m_pDVDMenu->updateDVDMenu();
		m_pDVDAuthor->addDVDMenu(m_pDVDMenu);
	}
	Global::qsCurrentPath = qsCurrentPath;

	m_pDVDAuthor->slotAutosave ();
	m_pDVDAuthor->slotUpdateStructure ();
	// Here we have to create the SoourceFileEntry for the DVDAuthorObject
	// Note, the SourceFileEntry holds N SourceFileInfo's
	refreshMovieButtons ( );
	QWizard::accept();
	QTimer::singleShot (10, m_pDVDAuthor, SLOT(slotDeleteTemplateWizard()));
	myCursor = QCursor(QCursor::ArrowCursor);
	setCursor(myCursor);
}

void TemplateWizard::refreshMovieButtons ( )
{
  // This function will get the right screenshot for thos buttons that were 
  // created from the Media pool (Left side) and have a thumbnail which is
  // NOT the first frame.

  uint t, i;
  MenuObject     *pMenuObject     = NULL;
  MovieObject    *pMovieObject    = NULL;
  ButtonObject   *pButtonObject   = NULL;
  SourceFileInfo *pSourceFileInfo = NULL;
  QValueList<ButtonObject *> listOfButtons;
  if ( m_pDVDMenu ) {
    listOfButtons = m_pDVDMenu->getButtons ( );
    for ( t=0; t<listOfButtons.count ( ); t++ ) {
      pButtonObject = listOfButtons[t];
      pSourceFileInfo = pButtonObject->sourceFileInfo ( );
      if ( pSourceFileInfo && pSourceFileInfo->iMSecPreview > 0 ) {
	for ( i=0; i<pButtonObject->getNormalCount ( ); i++ ) {
	  pMenuObject = pButtonObject->getNormal ( i );
	  if ( pMenuObject && pMenuObject->objectType ( ) == QString ( MOVIE_OBJECT ) ) {
	    pMovieObject = (MovieObject *)pMenuObject;
	    if ( pMovieObject->msecPreview   ( ) != pSourceFileInfo->iMSecPreview ) {
	      pMovieObject->setMSecPreview   ( pSourceFileInfo->iMSecPreview );
	      MediaCreator::unregisterFromMediaScanner ( pMovieObject );
	      MediaCreator::registerWithMediaScanner   ( pMovieObject, pMovieObject->fileName ( ), pMovieObject->previewImage ( ), pSourceFileInfo->iMSecPreview );
	    }
	  }
	}
      }
    }
  }
}

void TemplateWizard::adjustPixmapHeight ( QPixmap *pPixmap, QString &qsButtonXml )
{
  if ( ( ! pPixmap ) || ( qsButtonXml.length ( ) < 1 ) )
    return;
  // This function will filter the MenuObject Height attribute out of the ButtonXml
  // and replace it with the properly calculated Height for the dropped in Image/Movie.
  QRegExp rx, rx1;
  QString qsPattern,  qsMenuObjectXml, qsHeight;
  int iPos, iHeight = (int)((float)pPixmap->height ( ) / m_fScale + 0.5 );
  if ( iHeight < 1 )
    return;
  
  //printf ( "\n\n%s\n----------------\n", qsButtonXml.ascii ( ) );
  qsHeight = QString ( "Height=\"%1\"" ).arg ( iHeight );

  qsPattern = QString ( "MenuObject[^>]*>.*</MenuObject>" );
  rx.setPattern  ( qsPattern );
  rx1.setPattern ( "Height=\".*\"" );
  // A button usually has three objects
  if ( rx.search ( qsButtonXml ) > -1 ) {
    rx.setMinimal  ( true );
    rx1.setMinimal ( true );
    iPos = 0;
    while ( iPos >= 0 ) {
      iPos = rx.search ( qsButtonXml, iPos );
      if ( iPos > -1 ) {
	qsMenuObjectXml = rx.cap ( 0 );
	//printf ( "--------------------------\n%s\n\n", qsMenuObjectXml.ascii ( ) );
	qsMenuObjectXml.replace ( rx1, qsHeight );
	iPos += rx.matchedLength ( );
	qsButtonXml.replace ( rx.cap ( 0 ), qsMenuObjectXml );
      }
    }
  }
  //printf ( "--------------------------\n%s\n\n", qsButtonXml.ascii ( ) );
}

void TemplateWizard::handleMenuAudio ( )
{
  int iPos;
  QRegExp rx;
  QString qsMenuSound, qsSoundFile;
  QStringList listSoundFiles;

  rx.setPattern ( "<MenuSound>.*</MenuSound>" );
  if ( rx.search ( m_qsXMLDVDMenu ) > -1 ) {
    rx.setMinimal ( true );

    iPos = 0;
    while ( iPos >= 0 ) {
      iPos = rx.search ( m_qsXMLDVDMenu, iPos );
      if ( iPos > -1 ) {
	qsSoundFile = rx.cap ( 0 );  // get the full ImageObject - Tag 
	qsSoundFile = qsSoundFile.remove  (  "<MenuSound>" );
	qsSoundFile = qsSoundFile.remove  ( "</MenuSound>" );
	listSoundFiles.append ( qsSoundFile );
	iPos += rx.matchedLength ( );
      }
    }
    
    if ( listSoundFiles.count () > 0 ) {
      // Okay, we add the sound source
      m_pDVDAuthor->checkForNewProject ( );
      m_pDVDAuthor->addSound ( listSoundFiles );
      // And the created SourceFileEntry will be the last in the list.
      SourceFileEntry *pEntry = m_pDVDAuthor->sourceFileEntry ( m_pDVDAuthor->sourceFileCount ( ) - 1 );
      if ( pEntry && pEntry->bSoundSource ) {
	QString qsEntryName = pEntry->qsDisplayName;
	qsEntryName = qsEntryName.replace ( "<", "&lt;" );
	qsEntryName = qsEntryName.replace ( ">", "&gt;" );
	qsMenuSound = "   <MenuSound>" + qsEntryName + "</MenuSound>";
      }
    }
  }
  rx.setMinimal ( false );
  // Finally, we replace the entry with one that the DVDMenu can chew on.
  m_qsXMLDVDMenu.replace ( rx, qsMenuSound );
}
