/****************************************************************************
** This is the CommandQueueDialog
**
**   Created : Wed Mar 31 07:53:05 2004
**        by : Varol Okan using Kate
** Copyright : (c) Varol Okan
**   License : GPL v 2.0
**
****************************************************************************/
#include <sys/stat.h>

#include <qvariant.h>
#include <qpushbutton.h>
#include <qtabwidget.h>
#include <qwidget.h>
#include <qframe.h>
#include <qgroupbox.h>
#include <qcheckbox.h>
#include <qlabel.h>
#include <qfiledialog.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qcombobox.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qscrollview.h>
#include <qwhatsthis.h>
#include <qregexp.h>
#include <qtimer.h>

#include "win32.h"
#include "execute.h"
#include "dialogexecute.h"
#include "dialogman.h"
#include "qdvdauthorinit.h"
#include "dialogcommandeditor.h"
#include "messagebox.h"


DialogExecute::GuiBlock::GuiBlock ( )
{
  pLabelComment          = NULL;
  pComboTranscode        = NULL;
  pComboCommands         = NULL;
  pButtonMan             = NULL;
  pButtonEdit            = NULL;
  pButtonSetAsDefault    = NULL;
  iBlockID               = -1;
  iBlockExecuteInterface = -1;
}

DialogExecute::DialogExecute(QValueList<ExecuteInterface *> listExecuteBlocks, bool bShowDialog )
    : QDialog( )
{
	uint t;
	
	// Init member variables.
	QStringList commandList;
	m_pInitObject      = NULL;
	m_pTranscodeParent = NULL;
	m_pTranscodeLayout = NULL;
	m_iTranscodeOffset = 0;
	m_pSubtitlesParent = NULL;
	m_pSubtitlesLayout = NULL;
	m_pSlideshowParent = NULL;
	m_pSlideshowLayout = NULL;
	m_iSubtitlesOffset = 0;

	// Here we concat all commands together ...
	for (t=0;t<listExecuteBlocks.count();t++)	// Lets get the default commands ...
		commandList += listExecuteBlocks[t]->listCommandList[0];
//	for (t=0;t<listExecuteBlocks.count();t++)	// Lets get the default commands ...
//		for (i=0;i<listExecuteBlocks[t]->listCommandList.count();i++)	// Lets get the default commands ...
//			commandList.append(listExecuteBlocks[t]->listCommandList[i][listExecuteBlocks[t]->listDefaults[t]]);
/* debugging the output.
for (t=0;t<listExecuteBlocks.count();t++)  {
for (int i=0;i<listExecuteBlocks[t]->listCommandList.count ();i++)  {
QStringList qsCommandList = listExecuteBlocks[t]->listCommandList[i];
for (int j=0;j<qsCommandList.count();j++)  {
printf ( "DialogExecute::DialogExecute <%d><%d><%d> = <%s>\n", t, i, j, qsCommandList[j].ascii() );
}
}
}
printf ("\n\n");
*/

	// In case the user does not want to display a execute Dialog but instead prefers the default settings.
	if ( ! bShowDialog )
		m_doSomething.system ( commandList );

	createMainForm       ( );
	createPreprocessing  ( );
	createDVDAuthorTab   ( listExecuteBlocks );
	QTimer::singleShot ( 50, this, SLOT ( slotResize ( ) ) );
}

DialogExecute::~DialogExecute()
{
  // Destroys the object and frees any allocated resources
  // no need to delete child widgets, Qt does it all for us
  int t;
  for ( t=0; t<(int)m_listGui.count(); t++ )
    delete m_listGui[t];
  m_listGui.clear ( );

  delete m_pInitObject;
}

void DialogExecute::slotResize ( )
{
  // Delayed initialization to have the dialog on screen for resize.
  createPostprocessing ( );
  languageChange ( );
  resize ( QSize ( 877, 662 ).expandedTo ( minimumSizeHint ( ) ) );
  slotCheckBlock ( true );
}

void DialogExecute::setInit ( QDVDAuthorInit *pInit )
{
	m_pInitObject = pInit;
	// Here we save over the ToolsPaths. This list will be removed from the InitObject ...
	m_listToolsPaths = pInit->getToolsPaths ( );
}

void DialogExecute::createMainForm ( )
{
	setName( "DialogExecute" );
	setSizeGripEnabled( TRUE );
	DialogExecuteLayout = new QGridLayout( this, 1, 1, 11, 6, "DialogExecuteLayout");

	Layout1 = new QHBoxLayout( 0, 0, 6, "Layout1");

	buttonHelp = new QPushButton( this, "buttonHelp" );
	buttonHelp->setAutoDefault( TRUE );
	Layout1->addWidget( buttonHelp );
	QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
	Layout1->addItem( spacer );

	buttonExport = new QPushButton( this, "buttonExport" );
	buttonExport->setAutoDefault( TRUE );
	Layout1->addWidget( buttonExport );

	buttonOk = new QPushButton( this, "buttonOk" );
	buttonOk->setAutoDefault( TRUE );
	buttonOk->setDefault( TRUE );
	Layout1->addWidget( buttonOk );

	buttonCancel = new QPushButton( this, "buttonCancel" );
	buttonCancel->setAutoDefault( TRUE );
	Layout1->addWidget( buttonCancel );

	DialogExecuteLayout->addLayout( Layout1, 1, 0 );

	m_pTabWidget = new QTabWidget( this, "m_pTabWidget" );
	m_pTabWidget->setEnabled( TRUE );

	// signals and slots connections
	connect ( buttonOk     , SIGNAL ( clicked() ), this, SLOT( slotOkay  ( ) ) );
	connect ( buttonCancel , SIGNAL ( clicked() ), this, SLOT( reject    ( ) ) );
	connect ( buttonExport , SIGNAL ( clicked() ), this, SLOT( slotExport( ) ) );
	connect ( buttonHelp ,   SIGNAL ( clicked() ), this, SLOT( slotHelp  ( ) ) );
	connect ( m_pTabWidget , SIGNAL ( currentChanged   ( QWidget * ) ), this, SLOT ( slotTabChanged ( QWidget * ) ) );
	connect (&m_doSomething, SIGNAL ( signalRenderMenu ( QString   ) ), this, SLOT ( slotRenderMenu ( QString   ) ) );
}

void DialogExecute::createPreprocessing ()
{
//	m_pTabPreparing = new QWidget( m_pTabWidget, "m_pTabPreparing" );
//	m_pTabWidget->insertTab( m_pTabPreparing, QString("Preparing") );
}

QGridLayout *DialogExecute::createBlockFrame(QWidget *pParent, QGridLayout *pParentLayout, ExecuteInterface *pInterface, int t, int iOffset)
{
	QGridLayout *pGroupBoxLayout;
	QCheckBox   *pCheckBox, *pCheckBox2;
	QGroupBox   *pGroupBox;

	pGroupBox = new QGroupBox( pParent, QString ("pGroupBox_%1").arg(t) );
	pGroupBox->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)1, 0, 0, pGroupBox->sizePolicy().hasHeightForWidth() ) );
	pGroupBox->setPaletteBackgroundColor(pInterface->backgroundColor);
	pGroupBox->setColumnLayout(0, Qt::Vertical );
	pGroupBox->layout()->setSpacing( 6 );
	pGroupBox->layout()->setMargin( 11 );
	m_listGroupBox.append (pGroupBox);

	pGroupBoxLayout = new QGridLayout( pGroupBox->layout() );
	pGroupBoxLayout->setAlignment( Qt::AlignTop );

	pCheckBox = new QCheckBox (pGroupBox, QString ("pCheckBox_%1").arg(t));
	pCheckBox->setChecked (pInterface->bShowBlock);
	pCheckBox->setMaximumWidth (25);
	pCheckBox->move (15, 0);
	connect( pCheckBox, SIGNAL( toggled(bool) ), this, SLOT( slotCheckBlock(bool) ) );
	m_listCheckBox.append(pCheckBox);

	if (iOffset == -1)	{
		pGroupBox->setTitle( QString ("           ") + pInterface->qsBlockName );
		pCheckBox2 = new QCheckBox (tr ("        Don't execute ") + 
			pInterface->qsBlockName, pParent, QString ("pCheckBox2_%1").arg(t));
	}
	else	{ // this will get the fileBaseName (as spec in the ini after the two possible conv tools)
		pGroupBox->setTitle (QString ("           Convert : ") + pInterface->listCommandList[0][pInterface->listSplitAt.count()] );
		pCheckBox2 = new QCheckBox (tr ("        Don't convert ") + 
			pInterface->listCommandList[0][pInterface->listSplitAt.count()], 
			pParent, QString ("pCheckBox2_%1").arg(t));
	}
	pCheckBox2->setPaletteBackgroundColor(pInterface->backgroundColor);
	connect( pCheckBox2, SIGNAL( toggled(bool) ), this, SLOT( slotCheckBlock(bool) ) );
	pCheckBox2->hide ();
	m_listCheckBox2.append(pCheckBox2);

	pParentLayout->addWidget( pCheckBox2, 2*t+1, 0 );
	pParentLayout->addWidget( pGroupBox, 2*t+2, 0 );

	return pGroupBoxLayout;
}

void DialogExecute::createCommandBlock (QWidget *pParent, QGridLayout *pParentLayout, ExecuteInterface *pInterface, int t, int i)
{
        int iYPos, iDefaultComment;
	QLabel		*pComment;
	QComboBox	*pCommand;
	QPushButton	*pButton, *pButtonEdit, *pButtonDefault;

	// Add another Layout with d/e - buttons oriented Vertically and in between the man button and the Combo box
	QVBoxLayout *pEDButtons;
	// setting : m_listCheckBox/m_listCheckBox2/m_listGroupBox
	iYPos = 2*i;
	pEDButtons   = new QVBoxLayout( 2, QString ("buttonbox_%1-%2t").arg(t).arg(i));
	pComment     = new QLabel( pParent,   QString ("comment_%1-%2t").arg(t).arg(i));
	pCommand     = new QComboBox( FALSE, pParent, QString ("command_%1-%2t").arg(t).arg(i));
	pButton      = new QPushButton( pParent, QString ("button_%1-%2t" ).arg(t).arg(i));
	pButton->setText( tr( "man" ) );
	pButtonEdit  = new QPushButton( pParent, QString ("button_%1-%2t" ).arg(t).arg(i));
	pButtonEdit->setMaximumSize ( 25, 25 );
	pButtonEdit->setText( tr( "e" ) );
	// If this is the internal render then we don't want to allow the user to change the command.
	pButtonDefault  = new QPushButton( pParent, QString ("button_%1-%2t" ).arg(t).arg(i));
	pButtonDefault->setMaximumSize ( 25, 25 );
	pButtonDefault->setText( tr( "d" ) );
	if (pInterface->listCommandList[i][0].find (QString (RENDER_MENU)) > -1)	{
		pCommand->setEditable(FALSE);
		pButtonEdit->setEnabled (false);
	}
	else
		pCommand->setEditable(TRUE);
	iDefaultComment = pInterface->listDefaults[i];
	if ( iDefaultComment >= (int)pInterface->listCommentList[i].count ( ) )
	     iDefaultComment = 0;

	//for (int x=0; x<pInterface->listCommentList.count ( ); x++ ) {
	//  for (int y=0;y<pInterface->listCommentList[x].count ( ); y++ ) {
	//    printf ( "Norm  [%d][%d]=<%s>\n", x, y, pInterface->listCommentList[x][y].ascii () );
	//  }
	//}

	pCommand->insertStringList ( pInterface->listCommandList[i] );
	pComment->setText          ( pInterface->listCommentList[i][iDefaultComment] );
	pCommand->setCurrentItem   ( pInterface->listDefaults   [i] );

	pEDButtons->addWidget( pButtonEdit );
	pEDButtons->addWidget( pButtonDefault );
	pParentLayout->addMultiCellWidget( pComment, iYPos, iYPos, 0, 2 );
	pParentLayout->addWidget( pCommand,   1+iYPos, 0 );
	pParentLayout->addLayout( pEDButtons, 1+iYPos, 1 );
	pParentLayout->addWidget( pButton,    1+iYPos, 2 );
	
	GuiBlock *pGuiBlock               = new GuiBlock;
	pGuiBlock->listComments           = pInterface->listCommentList[i];
	pGuiBlock->pComboCommands         = pCommand;
	pGuiBlock->pLabelComment          = pComment;
	pGuiBlock->pButtonMan             = pButton;
	pGuiBlock->pButtonEdit            = pButtonEdit;
	pGuiBlock->pButtonSetAsDefault    = pButtonDefault;
	pGuiBlock->iBlockID               = pInterface->listBlockIDs[i];
	pGuiBlock->iBlockExecuteInterface = t;// this connects the ExecuteInterface with the generated Block
	m_listGui.append ( pGuiBlock );

	connect (pCommand,       SIGNAL(activated (int)), this, SLOT(slotNormalSelectionChanged(int)));
	connect (pButton,        SIGNAL(clicked ()), this, SLOT(slotManButtonClicked()));
	connect (pButtonEdit,    SIGNAL(clicked ()), this, SLOT(slotEditButtonClicked()));
	connect (pButtonDefault, SIGNAL(clicked ()), this, SLOT(slotDefaultButtonClicked()));
}

void DialogExecute::createStandardBlock (QWidget *pParent, QGridLayout *pParentLayout, ExecuteInterface *pInterface, int t)
{
	int i;
	QGridLayout	*pGroupBoxLayout;
	// setting : m_listCheckBox/m_listCheckBox2/m_listGroupBox
	pGroupBoxLayout = createBlockFrame (pParent, pParentLayout, pInterface, t); 

	for (i=0;i<(int)pInterface->listCommandList.count();i++)
		createCommandBlock (m_listGroupBox.last(), pGroupBoxLayout, pInterface, t, i);
}

void DialogExecute::createTranscodeBlock (ExecuteInterface *pInterface, int t)
{
        int i, j, iYPos, iDefaultComment;
	QLabel		*pComment;
	QComboBox	*pCommand;
	QPushButton	*pButtonDefault;
	QGridLayout *pGroupBoxLayout = NULL;

	// m_listCheckBox/m_listCheckBox2/m_listGroupBox
	if  ( ! m_pTranscodeLayout )	{
		m_pTranscodeLayout = createBlockFrame (m_pScrollFrame, m_pScrollFrameLayout, pInterface, t); 
		m_pTranscodeParent = m_listGroupBox.last();
	}
	iYPos = 2*m_iTranscodeOffset++;

	pGroupBoxLayout = createBlockFrame (m_pTranscodeParent, m_pTranscodeLayout, pInterface, t, m_iTranscodeOffset);
	pComment = new QLabel( m_listGroupBox.last(),   QString ("comment_%1-0").arg(t));
	pCommand = new QComboBox( FALSE, m_listGroupBox.last(), QString ("command_%1-0").arg(t));
	// If this is the internal render then we don't want to allow the user to change the command.
	pButtonDefault  = new QPushButton( m_listGroupBox.last(), QString ("button_%1-0" ).arg(t));
	pButtonDefault->setMaximumSize ( 25, 25 );
	pButtonDefault->setText( tr( "d" ) );
	pCommand->setEditable(FALSE);
	iDefaultComment = pInterface->listDefaults[0];
	if ( iDefaultComment >= (int)pInterface->listCommentList[0].count ( ) )
	     iDefaultComment = 0;
	for (i=0;i<(int)pInterface->listSplitAt.count ();i++)
		pCommand->insertItem ( pInterface->listCommandList[0][i] );
	pComment->setText            ( pInterface->listCommentList[0][iDefaultComment] );
	pCommand->setCurrentItem     ( pInterface->listDefaults   [0] );

	pGroupBoxLayout->addMultiCellWidget ( pComment, iYPos, iYPos, 0, 1 );
	iYPos ++;
	pGroupBoxLayout->addMultiCellWidget ( pCommand, iYPos, iYPos, 0, 1 );
	pGroupBoxLayout->addWidget ( pButtonDefault, iYPos, 2 );
	iYPos ++;

	//////////////////////////////////////////////////////////////////////////////////////////////////////
	//for (int x=0; x<pInterface->listCommandList.count ( ); x++ ) {
	//  for (int y=0;y<pInterface->listCommandList[x].count ( ); y++ ) {
	//    printf ( "Trans Command [%d][%d]=<%s>\n", x, y, pInterface->listCommandList[x][y].ascii ( ) );
	//  }
	//}
	//for (int x=0; x<pInterface->listCommentList.count ( ); x++ ) {
	//  for (int y=0;y<pInterface->listCommentList[x].count ( ); y++ ) {
	//    printf ( "Trans Comment [%d][%d]=<%s>\n", x, y, pInterface->listCommentList[x][y].ascii ( ) );
	//  }
	//}
	//////////////////////////////////////////////////////////////////////////////////////////////////////

	GuiBlock *pGuiBlock               = new GuiBlock;
	pGuiBlock->listComments           = pInterface->listCommentList[0];
	pGuiBlock->pComboTranscode        = pCommand;
	pGuiBlock->pComboCommands         = pCommand;
	pGuiBlock->pLabelComment          = pComment;
	pGuiBlock->pButtonMan             = NULL;
	pGuiBlock->pButtonEdit            = NULL;
	pGuiBlock->pButtonSetAsDefault    = pButtonDefault;
	pGuiBlock->iBlockID               = pInterface->listBlockIDs[0];
	pGuiBlock->iBlockExecuteInterface = t;// this connects the ExecuteInterface with the generated Block
	m_listGui.append ( pGuiBlock );

	connect (pCommand,       SIGNAL(activated (int)), this, SLOT(slotTranscodeSelectionChanged(int)));
	connect (pButtonDefault, SIGNAL(clicked ()), this, SLOT(slotDefaultButtonClicked()));

	QGridLayout *pGroupBoxLayout2;
	QGroupBox   *pGroupBox;
	int iSplitAtStart, iSplitAtEnd;

	for (i=0;i<(int)pInterface->listSplitAt.count ();i++)	{
		iSplitAtStart = pInterface->listSplitAt[i] + 1;
		if (i+1 < (int)pInterface->listSplitAt.count ())
			iSplitAtEnd = pInterface->listSplitAt[i+1] + 1;
		else
			iSplitAtEnd = pInterface->listCommandList.count ();
//printf ("DialogExecute::createTranscodeBlock i<%d> count<%d> count<%d> <%d>\n", i, pInterface->listDefaults.count (), pInterface->listCommandList.count (),  pInterface->listDefaults[i]);
		pGroupBox = new QGroupBox( m_listGroupBox.last(), QString ("pGroupBox_%1").arg(t) );
		pGroupBox->setPaletteBackgroundColor(pInterface->backgroundColor);
		pGroupBox->setColumnLayout(0, Qt::Vertical );

		pGroupBoxLayout2 = new QGridLayout( pGroupBox->layout() );
		pGroupBoxLayout2->setAlignment( Qt::AlignTop );

		pGroupBoxLayout->addMultiCellWidget ( pGroupBox, iYPos, iYPos, 0, 2 );
//		pGroupBoxLayout->addWidget ( pGroupBox, iYPos, 0 );
		iYPos ++;
		for (j=iSplitAtStart;j<iSplitAtEnd;j++)
			createCommandBlock (pGroupBox, pGroupBoxLayout2, pInterface, t, j);
		// Hide everything but the default selection.
		if (pInterface->listDefaults[0] != i)
			pGroupBox->hide ();
		pGuiBlock->listTranscodeFrames.append ( pGroupBox );
		//		m_listTranscodeFrames.append ( pGroupBox );
	}
}

void DialogExecute::createSubtitlesBlock ( ExecuteInterface *pInterface, int t )
{
  if  ( ! m_pSubtitlesLayout )	{
    QString qsBlockName     = pInterface->qsBlockName;
    pInterface->qsBlockName = tr ( "Subtitles Block" );
    m_pSubtitlesLayout      = createBlockFrame    ( m_pScrollFrame, m_pScrollFrameLayout, pInterface, t ); 
    m_pSubtitlesParent      = m_listGroupBox.last ( );
    pInterface->qsBlockName = qsBlockName;
  }
  createStandardBlock ( m_pSubtitlesParent, m_pSubtitlesLayout, pInterface, t );
}

void DialogExecute::createSlideshowBlock ( ExecuteInterface *pInterface, int t )
{
  if  ( ! m_pSlideshowLayout )	{
    QString qsBlockName     = pInterface->qsBlockName;
    pInterface->qsBlockName = tr ( "Slideshow Block" );
    m_pSlideshowLayout      = createBlockFrame    ( m_pScrollFrame, m_pScrollFrameLayout, pInterface, t ); 
    m_pSlideshowParent      = m_listGroupBox.last ( );
    pInterface->qsBlockName = qsBlockName;
  }
  createStandardBlock ( m_pSlideshowParent, m_pSlideshowLayout, pInterface, t );
}

void DialogExecute::createDVDAuthorTab   (QValueList<ExecuteInterface *> listExecuteBlocks)
{
	uint t;
	m_listExecuteInterface = listExecuteBlocks;
	ExecuteInterface *pExecute = NULL;

	// Here we create the ScrollView and Layouts ...
	m_pTabExpert   = new QWidget( m_pTabWidget, "m_pTabExpert" );
	tabLayout      = new QGridLayout( m_pTabExpert, 1, 1, 11, 6, "tabLayout");
	m_pScrollView  = new QScrollView (m_pTabExpert, "ScrollView");
	m_pScrollFrame = new QFrame( m_pScrollView, "m_pScrollFrame" );
	m_pScrollFrame->setPaletteBackgroundColor( QColor( 238, 230, 234 ) );
	m_pScrollFrame->setFrameShape( QFrame::StyledPanel );
	m_pScrollFrame->setFrameShadow( QFrame::Raised );
	m_pScrollFrameLayout = new QGridLayout( m_pScrollFrame, 1, 1, 11, 6, "m_pScrollFrameLayout");

	for ( t=0; t<listExecuteBlocks.count ( ); t++ )  {
	  pExecute = listExecuteBlocks[t];
	  // Check if this is a transcoding block ...
	  //if ( pExecute->enType == ExecuteInterface::TYPE_TRANSCODING )//( pExecute->listSplitAt.count ( ) > 0 )
	  if ( pExecute->listSplitAt.count ( ) > 0 )
	    createTranscodeBlock ( pExecute, t );
	  else if ( pExecute->enType == ExecuteInterface::TYPE_SLIDESHOW )
	    //createStandardBlock  ( m_pScrollFrame, m_pScrollFrameLayout, pExecute, t );
	    createSlideshowBlock ( pExecute, t );
	  else if ( pExecute->enType == ExecuteInterface::TYPE_SUBTITLES )
	    //createStandardBlock  ( m_pScrollFrame, m_pScrollFrameLayout, pExecute, t );
	    createSubtitlesBlock ( pExecute, t );
	  else // TYPE_DEFAULT
	    createStandardBlock  ( m_pScrollFrame, m_pScrollFrameLayout, pExecute, t );
	}

	m_pScrollView->addChild  ( m_pScrollFrame );

	m_pFrameExplain = new QFrame( m_pScrollFrame, "m_pFrameExplain" );
	m_pFrameExplain->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)1, 0, 0, m_pFrameExplain->sizePolicy().hasHeightForWidth() ) );
	m_pFrameExplain->setPaletteBackgroundColor( QColor( 177, 211, 238 ) );
	m_pFrameExplain->setFrameShape( QFrame::GroupBoxPanel );
	m_pFrameExplain->setFrameShadow( QFrame::Sunken );
	m_pFrameExplain->setMaximumHeight(150);
	m_pFrameExplainLayout = new QGridLayout( m_pFrameExplain, 1, 1, 11, 6, "m_pFrameExplainLayout");

	m_pLabelExplain = new QLabel( m_pFrameExplain, "m_pLabelExplain" );
	m_pLabelExplain->setPaletteBackgroundColor( QColor( 177, 211, 238 ) );

	m_pFrameExplainLayout->addWidget( m_pLabelExplain, 0, 0 );

	m_pScrollFrameLayout->addWidget( m_pFrameExplain, 0, 0 );

	tabLayout->addWidget( m_pScrollView, 0, 0 );
	m_pTabWidget->insertTab( m_pTabExpert, QString("") );

	DialogExecuteLayout->addWidget( m_pTabWidget, 0, 0 );
}

void DialogExecute::createPostprocessing ()
{
//	m_pTabPostprocessing = new QWidget( m_pTabWidget, "m_pTabPostprocessing" );
//	m_pTabWidget->insertTab( m_pTabPostprocessing, QString("Cleaning") );
}

void DialogExecute::resizeEvent (QResizeEvent *p)
{
	// Here we keep the width of the inner Frame in sync with the resized Dialog ...
	QDialog::resizeEvent(p);
	slotTabChanged (m_pTabExpert);
}

void DialogExecute::slotNormalSelectionChanged (int iNewSelection)
{
  uint t;
  GuiBlock *pGuiBlock;
  // Called when the user changes from e.g Transcode, to MEncoder ...
  for ( t=0; t<m_listGui.count ( ); t++ )  {
    pGuiBlock = m_listGui[t];
    if ( ( ! pGuiBlock ) || ( ! pGuiBlock->pComboCommands ) )
      continue;
    if ( pGuiBlock->pComboCommands->hasFocus ( ) )	{
      if ( iNewSelection >= (int)pGuiBlock->listComments.count ( ) )
	   iNewSelection = 0;
      pGuiBlock->pLabelComment->setText ( pGuiBlock->listComments[iNewSelection] );
      slotTabChanged (m_pTabExpert);
      return;
    }
  }
}

void DialogExecute::slotTranscodeSelectionChanged (int iNewSelection)
{
  uint t, i, iComboCount;
  QWidget *pFrame = NULL;
  QComboBox *pCombo;
  GuiBlock *pGuiBlock;
  // Called when the user changes from e.g Transcode, to MEncoder ...
  for ( t=0; t<m_listGui.count ( ); t++ )  {
    pGuiBlock = m_listGui[t];
    if ( ( ! pGuiBlock ) || ( ! pGuiBlock->pComboTranscode ) )
      continue;
    if ( pGuiBlock->pComboTranscode->hasFocus ( ) )	{
      pCombo = pGuiBlock->pComboTranscode;
      // Okay every transcode block has the same amount of options 
      // (currently only transcode and mencoder)
      iComboCount = pCombo->count ( );
      for (i=0;i<iComboCount;i++)	{
	if ( i < pGuiBlock->listTranscodeFrames.count ( ) ) {
	  pFrame = pGuiBlock->listTranscodeFrames[i];
	  if ( pFrame ) {
	    if (iNewSelection == (int)i )
	      pFrame->show ( );
	    else
	      pFrame->hide ( );
	  }
	}
      }
      if ( iNewSelection >= (int)pGuiBlock->listComments.count ( ) )
	   iNewSelection = 0;
      pGuiBlock->pLabelComment->setText ( pGuiBlock->listComments[iNewSelection] );
      slotTabChanged (m_pTabExpert);
      return;
    }
  }
}
/*
void DialogExecute::slotTranscodeSelectionChanged (int iNewSelection)
{
  uint t, i, iComboCount;
  QWidget *pFrame = NULL;
  // Called when the user changes from e.g Transcode, to MEncoder ...
  for (t=0;t<m_listTranscodeCombos.count();t++)	{
    if (m_listTranscodeCombos[t]->hasFocus ())	{
      // Okay every transcode block has the same amount of options 
      // (currently only transcode and mencoder)
      iComboCount = m_listTranscodeCombos[t]->count ();
      for (i=0;i<iComboCount;i++)	{
	if ( ( t*iComboCount+i ) < m_listTranscodeFrames.count () ) {
	  pFrame = m_listTranscodeFrames[t*iComboCount+i];
	  if ( pFrame ) {
	    if (iNewSelection == (int)i )
	      pFrame->show ( );
	    else
	      pFrame->hide ( );
	  }
	}
      }
      slotTabChanged (m_pTabExpert);
      return;
    }
  }
}
*/
void DialogExecute::slotTabChanged(QWidget *pTab)
{
  int iWidth, iViewWidth, iOffset;
  uint t;
  QPoint pos, globPos;
  GuiBlock *pGuiBlock;
 
  if (pTab == m_pTabExpert)	{
    m_pScrollFrame->adjustSize();
    iViewWidth = m_pScrollView->visibleWidth();
    if (iViewWidth < 100)
      iViewWidth = 200;
    for ( t=0; t<m_listGui.count(); t++ )	{
      pGuiBlock = m_listGui[t];
      iOffset = 0;
      pos = pGuiBlock->pComboCommands->pos();
      globPos = pGuiBlock->pComboCommands->mapTo ( m_pScrollFrame, pos );
      // If the this is not a SubSubFrame, then we can extend it by 11 (Layout margin)
      if ( pGuiBlock->pComboCommands->parentWidget ( )->parent ( ) == m_pScrollFrame )
	iOffset = 11;
      iWidth = iViewWidth - 139 + iOffset - globPos.x();
      if (iWidth < 100)
	iWidth = 200;
      pGuiBlock->pComboCommands->setFixedWidth(iWidth);
    }
  }
}

void DialogExecute::slotCheckBlock(bool)
{
	static bool bWorking = false;
	// This function activates/deactivates all command lines in the checked // unchecked command block
	uint t;
	bool bShowCommandBlock;
	// This check will prevent the setChecked function calls in this function to mess up the logic.
	if (bWorking)
		return;
	bWorking = true;
	for (t=0;t<m_listGroupBox.count();t++)	{
		bShowCommandBlock = true;
		// First we need t figure out the logic ...
		// We are only interested in the negatives (I.e. when the block is NOT to be shown)
		// since the default is to show the command block.
		if ( (m_listGroupBox[t]->isVisible () ) && (!m_listCheckBox[t]->isChecked()) )
			bShowCommandBlock = false;
		if ( (!m_listGroupBox[t]->isVisible ()) && (!m_listCheckBox2[t]->isChecked()) )
			bShowCommandBlock = false;

		if (bShowCommandBlock)	{
			m_listCheckBox2[t]->hide();
			m_listGroupBox[t]->show ();
			m_listCheckBox[t]->setChecked (true);
		}
		else	{
			m_listGroupBox[t]->hide ();
			m_listCheckBox2[t]->show();
			m_listCheckBox2[t]->setChecked (false);
		}
	}
	bWorking = false;
}

// Sets the strings of the subwidgets using the current language.
void DialogExecute::languageChange()
{
    setCaption( tr( "Command Queue Dialog" ) );
    buttonHelp->setText( tr( "&Help" ) );
    buttonHelp->setAccel( QKeySequence( tr( "F1" ) ) );
    buttonOk->setText( tr( "&OK" ) );
    buttonOk->setAccel( QKeySequence( QString::null ) );
    buttonCancel->setText( tr( "&Cancel" ) );
    buttonCancel->setAccel( QKeySequence( QString::null ) );
    buttonExport->setText( tr( "&Export" ) );
    buttonExport->setAccel( QKeySequence( QString::null ) );
//    m_pTabWidget->changeTab( tab, tr( "Simple" ) );
    m_pLabelExplain->setText( tr( "<p align=\"center\"><b><h2>Here is the list of commands which will be executed. You can modify each single Command or accept the default settings.</h2></b></p>" ) );
    m_pTabWidget->changeTab( m_pTabExpert, tr( "Authoring" ) );
}

void DialogExecute::slotHelp ()
{
  MessageBox::warning (NULL, tr ("Help"), 
    tr ("In this dialog you see all commands that are going to get executed to create the DVD.\n\n"
	"[Export] Allows you to export all those commands to a script and execute one it fomr the command line.\n"
	"         Note: You can execute one command at a time. E.g. script.sh 1; script.sh 2 etc.\n"
	"[Help]   Displays this message.\n"
	"[e]      Opens the CommandEditorDialog. Using this button allows you to modify (and store) the command.\n"
	"[d]      Will set the current selected choice in the combo box as the default command.\n"
	"[man]    Will open a new dialog, which displays the man pages of all toools used in this command line.\n"
	"         Note: You can easily search for text through this dialog.\n"
	"[X]      (checkbox) this will enable / disable the commands for the whole selected command block.\n"
     ), QMessageBox::Ok , QMessageBox::NoButton );
  raise ();
}

void DialogExecute::slotManButtonClicked ( )
{
  QStringList listOfCommandsUsed;
  QWidget    *pFromList;
  QWidget    *pButton = childAt ( mapFromGlobal ( QCursor::pos ( ) ) );
  GuiBlock *pGuiBlock;

  if (!pButton)
    return;
  WId buttonID = pButton->winId();
  for ( uint t=0; t<m_listGui.count ( ); t++ ) {
    pGuiBlock = m_listGui[t];
    pFromList = pGuiBlock->pButtonMan;
    if ( ! pFromList )
      continue;
    if ( pGuiBlock->pButtonMan->winId ( ) == buttonID )	{
      // Here we create the list of the commands in this commandString.
      QString qsCommand = pGuiBlock->pComboCommands->currentText ( );
      QStringList partialCommandList = QStringList::split (";", qsCommand);
      for (uint i=0;i<partialCommandList.count();i++)	{
	QStringList partialCommandList2 = QStringList::split ("|", partialCommandList[i]);
	for (uint j=0;j<partialCommandList2.count();j++)	{
	  QStringList argumentList =  QStringList::split (" ", partialCommandList2[j]);
	  // the first argument is always the command.
	  // but we don't want the cd command.
	  if (argumentList[0] != "cd")
	    listOfCommandsUsed.append(argumentList[0]);
	}
      }
      createManPages (listOfCommandsUsed);
      return;
    }
  }
}

void DialogExecute::slotEditButtonClicked()
{
  uint t, i;
  QStringList listOfCommandsUsed;
  QWidget *pFromList;
  int iWhichKeyset = Keyword::Keys;
  GuiBlock *pGuiBlock;
  // In order to get the button we clicked we use the Cursor position ...
  QWidget *pButton = childAt ( mapFromGlobal ( QCursor::pos ( ) ) );
  if ( ! pButton )
    return;
  
  WId buttonID = pButton->winId ( );
  for ( t=0; t<m_listGui.count  ( ); t++ )  {
    pGuiBlock = m_listGui[t];
    pFromList = pGuiBlock->pButtonEdit;
    if (!pFromList)
      continue;
    if (pFromList->winId() == buttonID)	{
      // Here we open the CommandEditDialog ...
      if (m_pInitObject)	{
	QDVDAuthorInit::MenuBlock::Block *pBlock = m_pInitObject->getBlock (pGuiBlock->iBlockID, &iWhichKeyset );
	if (pBlock)	{
	  // Here we get the index to the appropriate ExecuteInterface for the given Block
	  int iInterface = pGuiBlock->iBlockExecuteInterface;
	  Keyword *pKeyword = m_pInitObject->getKeyword ( );
	  DialogCommandEditor *pEditor = new DialogCommandEditor (this);
	  pEditor->initMe (pBlock, pGuiBlock->pComboCommands->currentItem ( ), pKeyword->getKeys ( iWhichKeyset ), m_listExecuteInterface[iInterface]->listKeywords.count ( ) );
	  if ( pEditor->exec ( ) != QDialog::Rejected ) {
	    // Here we set the command line to the modified strings. 
	    // and then we set the keywords for the found ExecuteInterface - object.
	    pKeyword->setKeywords( iWhichKeyset, m_listExecuteInterface[iInterface]->listKeywords );
	    // and finally we generate the command / header with the correct keywords ...
	    pGuiBlock->pComboCommands->clear ( );
	    for ( i=0; i<pBlock->listCommands.count ( ); i++ )
		  pGuiBlock->pComboCommands->insertItem( pKeyword->resolvString( iWhichKeyset, pBlock->listCommands[i] ) );
	    pGuiBlock->pLabelComment->setText ( pKeyword->resolvString( iWhichKeyset, pBlock->listComments[0] ) );
	    m_pInitObject->setToolsPaths ( m_listToolsPaths );
	    m_pInitObject->saveIniFile   ( );
	    // this is to re-set the ToolsPaths information (keep it in here)
	    m_pInitObject->getToolsPaths ( );
	  }
	  delete pEditor;
	}
      }
      return;
    }
  }
}

void DialogExecute::slotDefaultButtonClicked()
{
  QWidget *pButton = childAt (mapFromGlobal(QCursor::pos()));
  GuiBlock *pGuiBlock;
  if (!pButton)
    return;
  WId buttonID = pButton->winId();
  for ( uint t=0; t<m_listGui.count ( ); t++ )  {
    pGuiBlock = m_listGui[t];
    if ( pGuiBlock->pButtonSetAsDefault->winId() == buttonID)	{
      if (m_pInitObject)	{
	m_pInitObject->setDefault ( pGuiBlock->iBlockID, pGuiBlock->pComboCommands->currentItem ( ) );
	m_pInitObject->setToolsPaths ( m_listToolsPaths );
	m_pInitObject->saveIniFile();
	// this is to re-set the ToolsPaths information (keep it in here)
	m_pInitObject->getToolsPaths ( );
      }
      return;
    }
  }
}

void DialogExecute::slotRenderMenu (QString qsMenuName)
{
	// Only here to forward the signal from the Execute - object (m_doSomething) to QDVDAuthor ...
	emit (signalRenderMenu(qsMenuName));
}

void DialogExecute::returnFromRenderMenu    ()
{
	// here we continue where we had a short break while rendering the menu.
	m_doSomething.raise();
	m_doSomething.startCommand ();
}

void DialogExecute::createManPages(QStringList &listOfCommandsUsed)
{
	// Create a modeless dialog, so we can work with DialogExecute and the DialogMan at the same time.
	DialogMan *pManDialog = new DialogMan(listOfCommandsUsed, this);
	pManDialog->show();
}

void DialogExecute::slotExport ( )
{
  uint t, iCounter = 0;
  int  i;
  // This function creates a script which the user can then execute ...
  QString fileName = QFileDialog::getSaveFileName("./", tr("Shell file (*.sh)"), this,tr( "Save file dialog"),tr( "Save File As ..."));
  GuiBlock *pGuiBlock;
  if (fileName.isNull ())
    return;

  QFileInfo fileInfo(fileName);
  if (fileInfo.extension(FALSE).isEmpty())
    fileName += QString (".sh");

  QFile shellFile(fileName);
  QString qsComment;
  if ( shellFile.open( IO_WriteOnly ) ) {
    QTextStream stream( &shellFile );
    stream << Global::qsBashString;
    stream << "run=0\n";
    stream << "if [ $# -eq 0 ];\n";
    stream << "then\n";
    stream << "        run=1\n";
    stream << "fi;\n\n";
    stream << "while [ $# -gt 0 ] || [ $run -eq 1 ]\n";
    stream << "do\n\n";

    for (t=0;t<m_listGui.count();t++)	{
      pGuiBlock = m_listGui[t];
      // First we check if the user wants this command to get executed after all ...
      if ( pGuiBlock->pComboCommands->isVisible ( ) )  {
	stream << "if [ 1 -eq $run ] || [ " << ++iCounter << " -eq $1 ];\n";
	stream << "then\n";
	// Okay to also output the comments ...
	qsComment = stripTags( pGuiBlock->pLabelComment->text());
	stream << "# " << qsComment + "\n";
	stream << "#############################################################################\n";
	// we should offer all options as comments and the current one as the real deal ...
	for (i=0;i< pGuiBlock->pComboCommands->count ( );i++)	{
	  if (i != pGuiBlock->pComboCommands->currentItem ( ) )	{
	    stream << "# Option " << i << " : \n";
	    stream << "# " <<  getToolsPath( pGuiBlock->pComboCommands->text ( i ) ) + "\n";
	  }
	}
	// And here we write the current selected Option ...
	if ( pGuiBlock->pComboCommands->currentText ( ).find ( "#=-" ) == 0 )  // we should add this to avoid an error message for this script.
	  stream << "echo \"" << pGuiBlock->pComboCommands->currentText ( ) << "\"\n";
	else
	  stream << getToolsPath( pGuiBlock->pComboCommands->currentText ( ) ) + "\n";
	stream << "fi;\n\n";
      }
    }

    if ( Global::iRegionalZone > 0 )  {
      stream << "if [ 1 -eq $run ] || [ " << ++iCounter << " -eq $1 ];\n";
      stream << "then\n";
      stream << "# Here we write the Regional Zone code to the final DVD.\n";
      stream << "#############################################################################\n";

      QString qsRegionalZone = QString ( "%1" ).arg ( Global::iRegionalZone );
      QString qsQRender = "qrender --zone " + qsRegionalZone + " --path " + Global::qsProjectPath + "\n";
      qsQRender = getToolsPath ( qsQRender );
      stream << qsQRender;
      stream << "fi;\n\n";
    }


    stream << "shift\n";
    stream << "run=0\n";
    stream << "done\n\n";

    shellFile.close ( );
    chmod ((const char *)fileName, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
    emit (signalGenerateMasks ());
  }
}

QString DialogExecute::stripTags(QString qsInput)
{
	// This function will strip off all HTML TAGs (Or anything between < and >
	QString qsOutput = qsInput;
	QRegExp rx ("<[^>]*>");

	qsOutput.remove(rx);
	qsOutput.remove("\n");
	return qsOutput;
}

void DialogExecute::slotOkay()
{
  uint t;
  QStringList listCommands;
  GuiBlock *pGuiBlock;
  // first let us create the masks ...
  emit ( signalGenerateMasks   ( ) );
  for ( t=0; t<m_listGui.count ( ); t++ )	{
    pGuiBlock = m_listGui[t];
    if ( pGuiBlock->pComboCommands->isVisible())
      listCommands.append ( getToolsPath ( pGuiBlock->pComboCommands->currentText ( ) ) );
  }
  m_doSomething.system ( listCommands );

  hide ();

  // for a blocking execution one has to start a timer, which checks m_doSomthing.isRunning()
  // And calls accept () only after all commands have been executed.
  // Also one needs to tak care of the user closing the execution-output-dialog.
  //	accept();
}

QString DialogExecute::getToolsPath(QString qsCommandLine)
{
	// This function will take the command line as an input and add the full path to each of the tools used in this cmmand line.
	// E.g. 
	// jpeg2yuv -n 50 -j "/tmp/Main Menu VMGMbackground.jpg" | mpeg2enc -n p -o "/tmp//Main Menu VMGM.m2v"
	// will be converted into 
	// /usr/bin/jpeg2yuv -n 50 -j "/tmp/Main Menu VMGMbackground.jpg" | /usr/local/bin/mpeg2enc -n p -o "/tmp//Main Menu VMGM.m2v"
	/////////////////////////////////////////////////////////////////////

	uint t;
	QString qsReturn;
	QString qsCommand;
	QRegExp regExp;
	qsReturn = qsCommandLine;

	for (t=0;t<m_listToolsPaths.count ();t++)	{
		if (m_listToolsPaths[t]->bPresent)	{
 			// The first regExp takes care of all occurances of the tool which do NOT start with a '/'
			regExp = QRegExp ("(^|\\s(?!/+))"+m_listToolsPaths[t]->qsExecutableName+" ");
			qsReturn.replace (regExp, m_listToolsPaths[t]->qsFullPath+" ");
			// The second regExp takes care of the case where the user does not leave a blank between the pipe symbol '|' and the tool.
 			regExp = QRegExp ("\\|"+m_listToolsPaths[t]->qsExecutableName+" ");
			qsReturn.replace (regExp, "| "+m_listToolsPaths[t]->qsFullPath+" ");
		}
//		else
//			printf ("WARNING, %s not present in system.\n", (const char *) m_listToolsPaths[t]->qsExecutableName);
	}
	return qsReturn;
}
