/****************************************************************************
** DialogButton class
**
** Created: Wed Feb 26 22:48:00 2004
**      by: Varol Okan using Kate
**
** This class handles the ButtonDialog.
** With this dialog you are able to set all properties of the button,
** including the different states (normal, highlighted, and selected).
**
** Once the Button object has been created, it is displayed in the MenuPreview
** window and handles the Highlight state, when the mouse is over it, and the
** selected state when the mouse is 'left-clicked' on it.
**
****************************************************************************/
#include <qlineedit.h>
#include <qstringlist.h>
#include <qpushbutton.h>
#include <qtabwidget.h>
#include <qcombobox.h>
#include <qgroupbox.h>
#include <qpainter.h>
#include <qlayout.h>
#include <qframe.h>
#include <qfileinfo.h>
#include <qtimer.h>
#include <qregexp.h>

#include "global.h"
#include "dialogbutton.h"
#include "menupreview.h"
#include "menuobject.h"
#include "messagebox.h"
#include "buttonobject.h"
#include "buttonpreview.h"
#include "sourcefileentry.h"

#define BUTTON_BASIC    "<<< Basic"
#define BUTTON_ADVANCED "Advanced >>>"
#define MANUAL_CHANGE   255, 180, 60

DialogButton::DialogButton(QWidget * parent, const char * name, WFlags f)
	: uiDialogButton (parent, name, f)
{
	// Standard is set to false. This indicates that we create a button as
	// opposed to modify an existing one.
	m_bButtonCreation = false;
	m_bAutomatic = false;
}

DialogButton::~DialogButton()
{
}

void DialogButton::initMe ( ButtonObject *pButton, MenuPreview *pView )
{
	QPixmap image = QPixmap::fromMimeSource (QString ("checkered.png"));

	// Here we hide the advanced features and wait for the user to ask for them.
	m_pGroupGoto->hide ( );
	m_pEditAction->hide ( );
	m_pGroupGeometry->hide ( );
	m_pButtonHelpAction->hide ( );
	m_pGroupSystemRegister->hide ( );
	m_pButtonAdvanced->setText ( BUTTON_ADVANCED );

	m_pFramePreviewNormal = new ButtonPreview( tab, "m_pFramePreviewNormal" );
	m_pFramePreviewNormal->setPaletteBackgroundPixmap( image );
	m_pFramePreviewNormal->setFrameShape( QFrame::GroupBoxPanel );
	m_pFramePreviewNormal->setFrameShadow( QFrame::Raised );
	m_pFramePreviewNormal->setLineWidth( 2 );
	tabLayout->addWidget( m_pFramePreviewNormal, 0, 0 );

	m_pFrameHighlighted = new ButtonPreview( tab_2, "m_pFrameHighlighted" );
	m_pFrameHighlighted->setPaletteBackgroundPixmap( image );
	m_pFrameHighlighted->setFrameShape( QFrame::GroupBoxPanel );
	m_pFrameHighlighted->setFrameShadow( QFrame::Raised );
	m_pFrameHighlighted->setLineWidth( 2 );
	tabLayout_2->addWidget( m_pFrameHighlighted, 0, 0 );

	m_pFrameSelected = new ButtonPreview( TabPage_2, "m_pFrameSelected" );
	m_pFrameSelected->setPaletteBackgroundPixmap( image );
	m_pFrameSelected->setFrameShape( QFrame::GroupBoxPanel );
	m_pFrameSelected->setFrameShadow( QFrame::Raised );
	m_pFrameSelected->setLineWidth( 2 );
	TabPageLayout_2->addWidget( m_pFrameSelected, 0, 0 );

	m_pButtonObject = pButton;
	// Note the cloned Button is where all the action takes place. Unless the User clicks on Ok 
	// Nothing in the original ButtonObject is modified.
	m_pClonedButton = (ButtonObject *)pButton->clone();

	// Okay for the cloned Button but we need to reParent the MenuObjects contained within,
	// otherwise the effect will shoot back ...
	uint t=0;
	MenuObject *pObject;
	for (t=0;t<m_pClonedButton->getNormalCount();t++)	{
		pObject = m_pClonedButton->getNormal(t);
		pObject->setParent(m_pFramePreviewNormal);
	}
	for (t=0;t<m_pClonedButton->getHighlightedCount();t++)	{
		pObject = m_pClonedButton->getHighlighted(t);
		pObject->setParent(m_pFrameHighlighted);
		// In case the user changes the highlighted color of the objects in this dialog ...
		connect (pObject, SIGNAL(signalMaskColorChanged(QColor, QColor)), pView, SIGNAL(signalMaskColorChanged(QColor, QColor)));
	}
	for (t=0;t<m_pClonedButton->getSelectedCount();t++)	{
		pObject = m_pClonedButton->getSelected(t);
		pObject->setParent(m_pFrameSelected);
		// In case the user changes the selected color of the objects in this dialog ...
		connect (pObject, SIGNAL(signalMaskColorChanged(QColor, QColor)), pView, SIGNAL(signalMaskColorChanged(QColor, QColor)));
	}

	m_pFramePreviewNormal->addMenuObject(m_pClonedButton->getNormal(0));
	m_pFrameHighlighted->addMenuObject(m_pClonedButton->getHighlighted(0));
	m_pFrameSelected->addMenuObject(m_pClonedButton->getSelected(0));

	// Now we proceed to initialize the GUI objects (LineEdits, ComboBoxes etc.)
	initNext();
	
	initSystem ( pView, pButton );

	// Here we set the text fields for the bounding rectangle ...
	m_pEditX->setText     ( QString ("%1").arg(pButton->getNormal(0)->boundingRect().x ( ) ) );
	m_pEditY->setText     ( QString ("%1").arg(pButton->getNormal(0)->boundingRect().y ( ) ) );
	m_pEditWidth->setText ( QString ("%1").arg(pButton->getNormal(0)->boundingRect().width  ( ) ) );
	m_pEditHeight->setText( QString ("%1").arg(pButton->getNormal(0)->boundingRect().height ( ) ) );	
	m_pEditName->setText  ( pButton->name());
	
	// And then we should also init the possible Actions to take ...
	initActions ();
	// Last we connect all signal's slots neccesary.	
	connect (m_pComboAction1,     SIGNAL(activated(int)), this, SLOT(slotAction1    (int)));
	connect (m_pComboSourceEntry, SIGNAL(activated(int)), this, SLOT(slotSourceEntry(int)));
	connect (m_pComboSourceFile,  SIGNAL(activated(int)), this, SLOT(slotSourceFile (int)));
	connect (m_pComboChapters,    SIGNAL(activated(int)), this, SLOT(slotChapters   (int)));
	connect (m_pComboChapters2,   SIGNAL(activated(int)), this, SLOT(slotChapters2  (int)));

	connect (m_pComboAudio,       SIGNAL(activated(int)), this, SLOT(slotSystem  (int)));
	connect (m_pComboButton,      SIGNAL(activated(int)), this, SLOT(slotSystem  (int)));
	connect (m_pComboSubtitles,   SIGNAL(activated(int)), this, SLOT(slotSystem  (int)));
	connect (m_pComboAngle,       SIGNAL(activated(int)), this, SLOT(slotSystem  (int)));
	connect (m_pComboRegion,      SIGNAL(activated(int)), this, SLOT(slotSystem  (int)));

	connect (m_pButtonAdvanced,   SIGNAL(clicked()), this, SLOT(slotAdvanced   ( ) ) );
	connect (m_pButtonHelpAction, SIGNAL(clicked()), this, SLOT(slotHelpAction ( ) ) );
	connect (m_pButtonHelpGoto,   SIGNAL(clicked()), this, SLOT(slotHelpGoto   ( ) ) );
	connect (m_pButtonHelp,       SIGNAL(clicked()), this, SLOT(slotHelp       ( ) ) );
	connect (m_pButtonHelpSystem, SIGNAL(clicked()), this, SLOT(slotHelpSystem ( ) ) );
	connect (m_pTabWidget,        SIGNAL(currentChanged(QWidget *)), this, SLOT(slotTabChanged(QWidget *)));
	connect (m_pEditAction,       SIGNAL(textChanged(const QString &)), this, SLOT(slotEditActionChanged(const QString &)));

	connect (m_pButtonOkay,       SIGNAL(clicked()), this, SLOT(slotOkay ()));
	connect (m_pButtonCancel,     SIGNAL(clicked()), this, SLOT(slotCancel()));
	QTimer::singleShot ( 10, this, SLOT ( slotAdjustSize ( ) ) );
}

void DialogButton::slotAdjustSize ( )
{
  resize  ( width ( ), 530 );
}

void DialogButton::initNext()
{
	// Interesting handling here, 
	// first we should check if the choice exists in the ComboBox and if so set the index, OR
	// if it does not exist, we should set it as the currentText.
//	m_pButtonObject->setNext (BUTTON_UP,    m_pComboUp->currentText());
//	m_pButtonObject->setNext (BUTTON_DOWN,  m_pComboDown->currentText());
//	m_pButtonObject->setNext (BUTTON_LEFT,  m_pComboLeft->currentText());
//	m_pButtonObject->setNext (BUTTON_RIGHT, m_pComboRight->currentText());

	// First we build the available choices ...
	QComboBox *comboArray[4];
	int intArray[4];
	comboArray[0] = m_pComboUp;	intArray[0] = NEXT_BUTTON_UP;
	comboArray[1] = m_pComboDown;	intArray[1] = NEXT_BUTTON_DOWN;
	comboArray[2] = m_pComboRight;	intArray[2] = NEXT_BUTTON_RIGHT;
	comboArray[3] = m_pComboLeft;	intArray[3] = NEXT_BUTTON_LEFT;
	uint t, i;
	for (t=0;t<4;t++)	{
		comboArray[t]->clear();
		// The main menu (bien sur)
//		comboArray[t]->insertItem(QString("vmgm"));
		comboArray[t]->insertItem(QString("-- default --"));
		// Next we should include all sub-menus ...
		for (i=0;i<m_listSubMenus.count();i++)
			comboArray[t]->insertItem(m_listSubMenus[i]);
		// and also all available Buttons for the current menu
		for (i=0;i<m_listMenuButtons.count();i++)
			comboArray[t]->insertItem(m_listMenuButtons[i]);
		// After we initialized the combo boxes, we set the current text (from the buttonObject
		if (!m_pClonedButton->next(intArray[t]).isEmpty())
			comboArray[t]->setCurrentText(m_pClonedButton->next(intArray[t]));
	}
}

void DialogButton::initActions()
{
	// Action1 can only be one of these four ...
 	// Note: an empty string indicates that the user manually changed the action along the way.
	m_pComboAction1->insertItem(QString ("jump"));
	m_pComboAction1->insertItem(QString ("call"));
	m_pComboAction1->insertItem(QString ("resume"));
	// The slots will build the rest of the fest ...
	slotAction1(0);
}

void DialogButton::initActionState ()
{
	// Here we initialize the state of the Action Combo boxes according to ButtonObject->action()
	QString qsAction1, qsAction2, qsAction3, qsAction4, qsButtonAction;
	// It could be 2 different possibilities : a) only one file in this entry b) multiple files in this entry
	// a) action1 = Jump / action2 = file / action3 = chapter
	// b) action1 = Jump / action2 = entry / action3 = file / action4 = chapter
	QStringList listActions;

	qsButtonAction = m_pButtonObject->action();
	if (qsButtonAction.isEmpty())
		return;

	listActions = QStringList::split (STRING_SEPARATOR, qsButtonAction);
	qsAction1 = listActions[0];
	if (listActions.count() == 1)	{
		if (m_pComboAction1->count() <= 3)
			m_pComboAction1->insertItem (QString ());
		m_pComboAction1->setCurrentItem (3);
		return;
	}
	qsAction2 = listActions[1];
	qsAction3 = listActions[2];
	if (listActions.count() > 3)
		qsAction4 = listActions[3];

	// At this point we have the correct mix of Actions ... Let's set them ...
	m_pComboAction1->setCurrentText(qsAction1);
	if (qsAction1 == QString ("resume"))
		return;

	if (!qsAction2.isEmpty())
		m_pComboSourceEntry->setCurrentText(qsAction2);

	// Okay here we generate the information in the Combo boxes
	slotSourceEntry(m_pComboSourceEntry->currentItem());

	// and finally we set the value found in the file ...
	if (listActions.count() == 3)	{
		if (!qsAction3.isEmpty())
			m_pComboChapters->setCurrentText(qsAction3);
		slotChapters(0);
	}
	else if (listActions.count() > 3)	{
		if (!qsAction3.isEmpty())
			m_pComboSourceFile->setCurrentText(qsAction3);
		slotSourceFile(0);
		if (!qsAction4.isEmpty())
			m_pComboChapters2->setCurrentText(qsAction4);
		slotChapters2(0);
	}
}

void DialogButton::initSystem ( MenuPreview *pMenuPreview, ButtonObject *pButton )
{
  uint t, iItem;
  bool bOkay;
  MenuObject *pMenuObject = NULL;
  QString     qsTemp, qsPreAction;

  if ( pButton )
    qsPreAction = pButton->preAction ( );
  m_pComboButton->clear ( );
  m_pComboButton->insertItem ( "Button -Def-" );
  if ( pMenuPreview && pButton ) {
    for ( t=0; t<pMenuPreview->objectCount ( );t++ ) {
      pMenuObject = pMenuPreview->menuObject ( t );
      if ( pMenuObject && pMenuObject->objectType ( ) == pButton->objectType ( ) )
	m_pComboButton->insertItem ( pMenuObject->name ( ) );
    }
  }

  // Next we initialize the combo boxes.
  QRegExp rx;
  rx.setMinimal ( true );
  rx.setPattern ( "audio=.*;" );
  if ( rx.search ( qsPreAction ) > - 1 ) {
    qsTemp = rx.cap ( 0 );
    qsTemp.remove ( "audio=" ); qsTemp.remove ( ";" );
    iItem = qsTemp.toInt ( &bOkay );
    if ( bOkay ) 
      m_pComboAudio->setCurrentItem ( ++iItem );
  }
  rx.setPattern ( "subtitle=.*;" );
  if ( rx.search ( qsPreAction ) > - 1 ) {
    qsTemp = rx.cap ( 0 );
    qsTemp.remove ( "subtitle=" ); qsTemp.remove ( ";" );
    iItem = qsTemp.toInt ( &bOkay );
    if ( bOkay ) 
      m_pComboSubtitles->setCurrentItem ( ++iItem );
  }
  rx.setPattern ( "angle=.*;" );
  if ( rx.search ( qsPreAction ) > - 1 ) {
    qsTemp = rx.cap ( 0 );
    qsTemp.remove ( "angle=" ); qsTemp.remove ( ";" );
    iItem = qsTemp.toInt ( &bOkay );
    if ( bOkay ) 
      m_pComboAngle->setCurrentItem ( ++iItem );
  }
  rx.setPattern ( "region=.*;" );
  if ( rx.search ( qsPreAction ) > - 1 ) {
    qsTemp = rx.cap ( 0 );
    qsTemp.remove ( "region=" ); qsTemp.remove ( ";" );
    iItem = qsTemp.toInt ( &bOkay );
    if ( bOkay ) 
      m_pComboRegion->setCurrentItem ( ++iItem );
  }

  qsPreAction.replace ( "\"", "&quot;" ); // this to make sure we catch either way " and &quot; ...
  rx.setPattern ( "button=&quot;.*&quot;" );
  if ( rx.search ( qsPreAction ) > -1 ) {
    QString qsButtonName = rx.cap ( 0 );
    qsButtonName.remove ( "button=" );
    qsButtonName.remove ( "&quot;" );
    for ( t=0; t<pMenuPreview->objectCount ( ); t++ ) {
      pMenuObject = pMenuPreview->menuObject ( t );
      if ( pMenuObject->name ( ) == qsButtonName ) {
	m_pComboButton->setCurrentItem ( t + 1 );
	break; // exit for - loop
      }
    }
  }
  qsPreAction.replace ( "&quot;", "\"" ); // this to make sure we catch either way " and &quot; ...

  m_pEditSystem->setText ( qsPreAction );
}

void DialogButton::slotHelpSystem ()
{
  QSize theSize ( 1000, 600 );
  MessageBox::help ( this, "System Register", "system_register.html", theSize );
}

void DialogButton::slotSystem ( int )
{
  QString qsPreAction = m_pEditSystem->text ( );
  // This function will create the qsPreAction - string.
  // this function is called from all combo boxes.
  removeFromString ( qsPreAction, "^\\s*" ); // remove leading white spaces.
  removeFromString ( qsPreAction, "\\s*$" ); // remove trailing white spaces.
  removeFromString ( qsPreAction, "audio\\s*=.*;" );
  if ( m_pComboAudio->currentItem ( ) > 0 )
    qsPreAction = QString ( "audio=%1; " ).arg ( m_pComboAudio->currentItem ( ) - 1 );
  removeFromString ( qsPreAction, "button\\s*=.*;" );
  if ( m_pComboButton->currentItem ( ) > 0 )
    qsPreAction += QString ( "button=\"%1\"; " ).arg ( m_pComboButton->currentText ( ) );
  removeFromString ( qsPreAction, "subtitle\\s*=.*;" );
  if ( m_pComboSubtitles->currentItem ( ) > 0 )
    qsPreAction += QString ( "subtitle=%1; " ).arg ( m_pComboSubtitles->currentItem ( ) - 1 );
  removeFromString ( qsPreAction, "angle\\s*=.*;" );
  if ( m_pComboAngle->currentItem ( ) > 0 )
    qsPreAction += QString ( "angle=%1; " ).arg ( m_pComboAngle->currentItem ( ) - 1 );
  removeFromString ( qsPreAction, "region\\s*=.*;" );
  if ( m_pComboRegion->currentItem ( ) > 0 )
    qsPreAction += QString ( "region=%1; " ).arg ( m_pComboRegion->currentItem ( ) - 1 );

  m_pEditSystem->setText ( qsPreAction );
}

void DialogButton::removeFromString ( QString &qsInput, QString qsRegExp )
{
  //  printf ( "DialogButton::removeFromString b4<%s> + rx<%s>", qsInput.ascii ( ), qsRegExp.ascii () );
  QRegExp rx;
  rx.setMinimal  ( true );
  rx.setPattern  ( qsRegExp );
  qsInput.remove ( rx );
  //  printf ( "= <%s>\n", qsInput.ascii() );
}

/*
// First incarnation which did remove user input.
void DialogButton::slotSystem ( int )
{
  QString qsPreAction;
  // This function will create the qsPreAction - string.
  // this function is called from all combo boxes.

  if ( m_pComboAudio->currentItem ( ) > 0 )
    qsPreAction = QString ( "audio=%1; " ).arg ( m_pComboAudio->currentItem ( ) - 1 );
  if ( m_pComboButton->currentItem ( ) > 0 )
    qsPreAction += QString ( "button=\"%1\"; " ).arg ( m_pComboButton->currentText ( ) );
  if ( m_pComboSubtitles->currentItem ( ) > 0 )
    qsPreAction += QString ( "subtitle=%1; " ).arg ( m_pComboSubtitles->currentItem ( ) - 1 );
  if ( m_pComboAngle->currentItem ( ) > 0 )
    qsPreAction += QString ( "angle=%1; " ).arg ( m_pComboAngle->currentItem ( ) - 1 );
  if ( m_pComboRegion->currentItem ( ) > 0 )
    qsPreAction += QString ( "region=%1; " ).arg ( m_pComboRegion->currentItem ( ) - 1 );

  m_pEditSystem->setText ( qsPreAction );
}
*/

void DialogButton::slotTabChanged (QWidget *pTab)
{
	int iTab = m_pTabWidget->indexOf(pTab);
	ButtonPreview *pFrame;
	switch (iTab)	{
	case 2:
		pFrame = m_pFrameHighlighted;
	break;
	case 3: 
		pFrame = m_pFrameSelected;
	break;
	default:
		pFrame = m_pFramePreviewNormal;
	break;
	}	
	// This function calculates the viewport extension such that the Object is centered.

	// Every time the tab is pressed we want to update the previews Viewport setting.
	// Note all three ought to have the same extensions ...
	QRect rectViewport = pFrame->rect();
	MenuObject *pNormal = m_pClonedButton->getNormal (0);
	// The bounding rect is the active buttons area.
	QRect rectNormal = pNormal->boundingRect();

	rectViewport.setX ((int)(-rectNormal.x() + (pFrame->rect().width () - rectNormal.width ()) / 2.0));
	rectViewport.setY ((int)(-rectNormal.y() + (pFrame->rect().height() - rectNormal.height()) / 2.0));
	// And finally we re-store the original width and height ...
	rectViewport.setWidth (pFrame->rect().width ());
	rectViewport.setHeight(pFrame->rect().height());

	pFrame->setViewport(rectViewport);
}

void DialogButton::setSourceFiles(QValueList<SourceFileEntry *>listSourceFileEntries)
{
	uint t;
	m_listSourceFileEntries.clear();
	for (t=0;t<listSourceFileEntries.count();t++)	{
		if (!listSourceFileEntries[t]->bSoundSource)
			m_listSourceFileEntries.append(listSourceFileEntries[t]);
	}
	slotAction1(0);
	initActionState ();
}

void DialogButton::setSubMenus (QStringList listSubMenus)
{
	m_listSubMenus = listSubMenus;
	slotAction1(0);
	initActionState ();
}

void DialogButton::setMenuButtons (QStringList listMenuButtons)
{
	m_listMenuButtons = listMenuButtons;
	initNext();
}

SourceFileEntry *DialogButton::getSelectedSourceEntry()
{
	uint t;

	// Since we have also menus in the combo box we need to get the iCurrentEntry, which is the correct index 
	// to the m_listSourceFileEntries - list.
	for (t=0;t<m_listSourceFileEntries.count();t++)	{
		if (m_listSourceFileEntries[t]->qsDisplayName == m_pComboSourceEntry->currentText())
			return m_listSourceFileEntries[t];
	}
	return NULL;
}

SourceFileInfo *DialogButton::getSelectedSourceFile()
{
	uint t;
	QFileInfo fileInfo;
	SourceFileEntry *pEntry = getSelectedSourceEntry();
	// sanity check ...
	if (pEntry)	{
		// First we should see which sourceFile is selected ...
		for (t=0;t<pEntry->listFileInfos.count();t++)	{
			fileInfo.setFile (pEntry->listFileInfos[t]->qsFileName);
			if (fileInfo.fileName() == m_pComboSourceFile->currentText())	{
				return pEntry->listFileInfos[t];
			}
		}
	}
	return NULL;
}

void DialogButton::slotEditActionChanged(const QString &qsText)
{
	// Okay we detected that the user manually changed the text and as such we want to keep this change.
	if (!m_bAutomatic)	{
		m_pEditAction->setPaletteBackgroundColor (QColor(MANUAL_CHANGE));
		if (m_pComboAction1->count() <= 3)	{
			m_pComboAction1->insertItem(QString ());
			m_pComboSourceEntry->clear ();
			m_pComboSourceEntry->insertItem (QString ());

			m_pComboChapters->clear ();
			m_pComboSourceFile->hide();
			m_pComboChapters2->hide();
			m_pComboChapters->show();
		}
		m_pComboAction1->setCurrentItem (3);
		m_pComboSourceEntry->setCurrentText(qsText);
	}
	else	{
		m_pEditAction->setPaletteBackgroundColor (QColor(255, 255, 255));
		if (m_pComboAction1->count() > 3)
			m_pComboAction1->removeItem(3); // remove the last item (0 based)
	}
}

void DialogButton::slotAction1(int)
{
	// Okay, here we prepare the available actions ...
	// if (Action1->text() == jump , then we generate a movie list for Action2, and Action3 has chapters according to the Movie.
	// if (Action1->text() == call , then we generate only a menu list for Action2.
	// if (Action1->text() == resume , then we keep Action2 and Action3 empty.

	// The following is allowed :
	// jump vmgm menu               -> jumps to default menu.
	// jump titleset 2 menu         -> default menu of titleset 2
	// jump vmgm menu 3             -> jumps to menu 3.
	// jump titleset 2 menu 3       -> jumps to menu 3 of titleset 2
	// jump vmgm menu 3 entry 4     -> jumps to menu denoted as the entry 4 for the vmgm.
	// jump titleset 2 menu entry 3 -> jumps to menu denoted as the entry 3 of titleset 2
	//
	// call - resume work together but only from a title t a menu, all other forms are illegal.
	// this is used to allow to return to the point in the title from where the call originated.
	//
	// jump vmgm title 2 [chapter 3] -> jumps to the title or chapter in a title
	//                                  All titles on the disc are accessible in the vmgm domain
	// jump chater 2, jump program 1, cell 4 -> jumps to a chapter, program, or cell in the current title.
	//                                  You cna use this to create looping menus (jump cell 1;)

	uint t;
	m_pComboSourceEntry->clear();
	m_pComboSourceFile->clear();
	if (m_pComboAction1->currentText() == QString ("jump"))	{
		// We can always jump to the main menu ...
		m_pComboSourceEntry->insertItem("vmgm");
		for (t=0;t<m_listSourceFileEntries.count();t++)	{
			if (!m_listSourceFileEntries[t]->bSoundSource)
				m_pComboSourceEntry->insertItem(m_listSourceFileEntries[t]->qsDisplayName);
		}
		for (t=0;t<m_listSubMenus.count();t++)
			m_pComboSourceEntry->insertItem(m_listSubMenus[t]);
	}
	else if (m_pComboAction1->currentText() == QString ("call"))	{
//		for (t=0;t<m_listSourceFiles.count();t++)
//			m_pComboAction2->insertItem(m_listSubMenus[t]);
		m_pComboSourceEntry->insertItem("vmgm");
		for (t=0;t<m_listSubMenus.count();t++)
			m_pComboSourceEntry->insertItem(m_listSubMenus[t]);
	}
//	else	{	// resume ...
//			m_pComboSourceEntry->insertItem(m_pClonedButton->action());
//	}
	slotSourceEntry(0);
}

void DialogButton::slotSourceEntry(int)
{
	uint t;
	bool bHideStatus = true;
	QFileInfo fileInfo;
	SourceFileEntry *pEntry;

	m_pComboChapters->clear();
	// Since we have also menus in the combo box we need to get the iCurrentEntry, which is the correct index 
	// to the m_listSourceFileEntries - list.
	pEntry = getSelectedSourceEntry ();
	if (pEntry)	{
		if (pEntry->listFileInfos.count() > 1)	{
			// Okay we found a movie SourceEntry with multiple source files.
			// So we should dislay m_pComboSourceFile, and m_pComboChapters
			// and we also ought to hide m_pComboChapter
			bHideStatus = false;
			if (m_pComboAction1->currentText() == QString ("jump"))	{
				m_pComboSourceFile->clear ();
				for (t=0;t<pEntry->listFileInfos.count();t++)	{
					fileInfo.setFile(pEntry->listFileInfos[t]->qsFileName);
					m_pComboSourceFile->insertItem(fileInfo.fileName());
				}
				// Here we connect the button object with the SourceFileEntry from the list.
				m_pClonedButton->setSourceFileEntry(pEntry);
			}
			// Lets generate the text for m_pEditAction
			slotSourceFile(0);
		}
		else	{
			// Here we add all chapters possible ...
			if (m_pComboAction1->currentText() == QString ("jump"))	{
				for (t=0;t<pEntry->listFileInfos[0]->listChapters.count();t++)
					m_pComboChapters->insertItem(pEntry->listFileInfos[0]->listChapters[t]);
				if (pEntry->listFileInfos[0]->listChapters.count() < 1)
					m_pComboChapters->insertItem(QString ("00:00:00.000"));
				// Here we connect the button object with the SourceFileEntry from the list.
				m_pClonedButton->setSourceFileEntry(pEntry);
			}
			// Lets generate the text for m_pEditAction
			slotChapters(0);
		}
	}
	else
		slotChapters(0);
	// Finally we shwo or hide the appropriate combo boxes ...
	if (bHideStatus)	{
		m_pComboSourceFile->hide();
		m_pComboChapters2->hide();
		m_pComboChapters->show();
	}
	else	{	// The default is to show only one line of ComboBoxes ...
		m_pComboSourceFile->show();
		m_pComboChapters2->show();
		m_pComboChapters->hide();
	}
}

void DialogButton::slotSourceFile(int)
{
	uint t;
	m_pComboChapters2->clear();
	SourceFileEntry *pEntry = getSelectedSourceEntry ();
	if (pEntry)	{
		// Note: Later on I want to hide the Chapters for Movies which are called from within the VMGM - Main Menu.
		// This is becaus eyou can not jump to chapters, only titles from the VMGM.
		SourceFileInfo *pInfo = getSelectedSourceFile ();
		if (!pInfo)
			pInfo = pEntry->listFileInfos[0];
		// Here we add all chapters possible ...
		if (m_pComboAction1->currentText() == QString ("jump"))	{
			for (t=0;t<pInfo->listChapters.count();t++)
				m_pComboChapters2->insertItem(pInfo->listChapters[t]);
			if (pInfo->listChapters.count() < 1)
				m_pComboChapters2->insertItem(QString ("00:00:00.000"));
		}
	}
	// Okay does currently nothig but ...
	slotChapters2(0);
}

void DialogButton::slotChapters(int)
{
	uint t;
	int  iChapterCounter = 1;
	SourceFileEntry *pEntry = getSelectedSourceEntry ();
	// Okay this here is generating the text for m_pEditAction.
	QString qsAction1 = m_pComboAction1->currentText();
	QString qsAction2 = m_pComboSourceEntry->currentText();
	QString qsAction3 = m_pComboChapters->currentText();
	// Here we get the Chapter number of chapter (e.g. "00:00:01.200")
	if ( (!qsAction3.isEmpty()) && (pEntry) )	{
		for (t=0;t<pEntry->listFileInfos[0]->listChapters.count();t++)	{
			if (pEntry->listFileInfos[0]->listChapters[t] == qsAction3)	{
				iChapterCounter = t + 1;
				break;
			}
		}
		qsAction3 = QString (" chapter %1").arg(iChapterCounter);
	}
	else
		qsAction3 = QString (" menu 1");
	
	QString qsAction = qsAction2;
	// Here we check that the changes are not manually made by the user ...
	if (!qsAction1.isEmpty())	{
		qsAction = QString (" ")  + qsAction1 + QString (" ") + qsAction2 + qsAction3 + QString (" ; ");
		m_bAutomatic = true;
	}
	m_pEditAction->setText(qsAction);
	m_bAutomatic = false;
}

void DialogButton::slotChapters2(int)
{
	uint t;
	int  iChapterCounter = 1;
	QFileInfo fileInfo;
	SourceFileEntry *pEntry = getSelectedSourceEntry();
	SourceFileInfo *pInfo = NULL;
	// Okay this here is generating the text for m_pEditAction.
	QString qsAction1 = m_pComboAction1->currentText();
	QString qsAction2 = m_pComboSourceFile->currentText();
	QString qsAction3 = m_pComboChapters2->currentText();
	// Here we get the Chapter number of chapter (e.g. "00:00:01.200")
	if ( (!qsAction3.isEmpty()) && (pEntry) )	{
		// First we should see which sourceFile is selected ...
		pInfo = getSelectedSourceFile ();
		if (!pInfo)
			pInfo = pEntry->listFileInfos[0];
		for (t=0;t<pInfo->listChapters.count();t++)	{
			if (pInfo->listChapters[t] == qsAction3)	{
				iChapterCounter = t + 1;
				break;
			}
		}
		qsAction3 = QString (" chapter %1").arg(iChapterCounter);
	}
	else
		qsAction3 = QString (" menu 1");
	QString qsAction = QString (" ")  + qsAction1 + QString (" ") + qsAction2 + qsAction3 + QString (" ; ");
	m_bAutomatic = true;
	m_pEditAction->setText(qsAction);
	m_bAutomatic = false;
}

void DialogButton::slotHelpAction()
{
	MessageBox::warning(this, tr("Action - tag"), tr("If you make manual changes here they will be kept.\n"
		"If this is the case then the background color will change to orange.\n"
		"You can reverse these changes by using the drop down boxes above.\n"
		"This is an advanced feature and should be used with care.\n\n"
		"Please note that the syntax in the XML file is different to the one displayed here."), 
		QMessageBox::Ok, QMessageBox::NoButton);
}

void DialogButton::slotHelpGoto()
{
	MessageBox::warning(this, tr("Goto - attributes"), 
		tr("Here you can specify the button to goto when the user pushes\n"
		"the up/down/right/left buttons on the remote control.\n\n"
		"Note: dvdauthor will choose a logical default value for each of those cases."), 
		QMessageBox::Ok, QMessageBox::NoButton);
}

void DialogButton::slotHelp()
{
	MessageBox::warning(this, "ButtonDialog", "Cool you got a button !!!\n", 
		QMessageBox::Ok, QMessageBox::NoButton);
}

void DialogButton::slotAdvanced()
{
	if ( m_pButtonAdvanced->text ( ) == QString ( BUTTON_ADVANCED ) )  {
		m_pGroupGeometry->show       ( );
		m_pGroupGoto->show           ( );
		m_pEditAction->show          ( );
		m_pButtonHelpAction->show    ( );
		m_pGroupSystemRegister->show ( );
		m_pButtonAdvanced->setText   ( BUTTON_BASIC );
	}
	else {
		m_pGroupGeometry->hide       ( );
		m_pGroupGoto->hide           ( );
		m_pEditAction->hide          ( );
		m_pButtonHelpAction->hide    ( );
		m_pGroupSystemRegister->hide ( );
		m_pButtonAdvanced->setText   ( BUTTON_ADVANCED );
	}
}

void DialogButton::setButtonCreation(bool bButtonCreation)
{
	m_bButtonCreation = bButtonCreation;
}

void DialogButton::slotCancel()
{
	// This function handles only the case of the cancelation of the Button creation.
	// I.e. the user just created the Button and decides to cancel out.
	// In case the User cancels the ButtonDialog when the ButtonObject already 
	// existed before, nothing ought to be done here.
	if (m_bButtonCreation)	{
		m_pButtonObject->deleteMasks();
		m_pButtonObject->slotUnbutton();
	}
	reject ();
}

void DialogButton::slotOkay()
{
	// Here we take care of the information we obtained ...
	QString qsPreAction = m_pEditSystem->text();
	QString qsAction    = m_pEditAction->text();
	QString qsName      = m_pEditName->text();
	QString qsUp        = m_pComboUp->currentText();
	QString qsDown      = m_pComboDown->currentText();
	QString qsRight     = m_pComboRight->currentText();
	QString qsLeft      = m_pComboLeft->currentText();

	// if the user has manually changed the action, then we do not want to modify it at all.
	// Power to the user ...
	if (m_pEditAction->paletteBackgroundColor() != QColor(MANUAL_CHANGE) )	{
		// Next let us take care of the action. Remember we showed the user something like :
		// jump my_movie1.mpg chapter 3
		// this needs to convert to something like ...
		// jump titleset 2 chapter 3
		SourceFileEntry *pEntry = getSelectedSourceEntry ();
		if ( (pEntry) && (pEntry->listFileInfos.count() > 1) )
			qsAction = m_pComboAction1->currentText() + QString (STRING_SEPARATOR) +
				m_pComboSourceEntry->currentText() + QString (STRING_SEPARATOR) +
				m_pComboSourceFile->currentText() + QString (STRING_SEPARATOR) +
				m_pComboChapters2->currentText();
		else
			qsAction = m_pComboAction1->currentText() + QString (STRING_SEPARATOR) +
				m_pComboSourceEntry->currentText() + QString (STRING_SEPARATOR) +
				m_pComboChapters->currentText();
	}

	m_pClonedButton->setPreAction ( qsPreAction );
	m_pClonedButton->setAction    ( qsAction    );
	m_pClonedButton->setName      ( qsName      );
	m_pClonedButton->setNext      ( NEXT_BUTTON_UP,    qsUp    );
	m_pClonedButton->setNext      ( NEXT_BUTTON_DOWN,  qsDown  );
	m_pClonedButton->setNext      ( NEXT_BUTTON_LEFT,  qsLeft  );
	m_pClonedButton->setNext      ( NEXT_BUTTON_RIGHT, qsRight );
	uint t;
	// Here we associate the new SourceFileEntry to the Cloned Button ...
	m_pClonedButton->setSourceFileEntry(NULL);
	for (t=0;t<m_listSourceFileEntries.count();t++)
		if (m_listSourceFileEntries[t]->qsDisplayName == m_pComboSourceEntry->currentText())
			m_pClonedButton->setSourceFileEntry(m_listSourceFileEntries[t]);
	
	// We should only topuch the rect if the user has indeed changed something ...	
	QRect rect (m_pEditX->text().toInt(), m_pEditY->text().toInt(), m_pEditWidth->text().toInt(), m_pEditHeight->text().toInt());
	if (rect != m_pButtonObject->getNormal(0)->boundingRect())	{
		m_pClonedButton->setRect(rect);
		for (t=0;t<m_pClonedButton->getNormalCount();t++)
			m_pClonedButton->getNormal(t)->setRect(rect);
		for (t=0;t<m_pClonedButton->getHighlightedCount();t++)
			m_pClonedButton->getHighlighted(t)->setRect(rect);
		for (t=0;t<m_pClonedButton->getSelectedCount();t++)
			m_pClonedButton->getSelected(t)->setRect(rect);
	}

	// And last but not least we equalize the original with the cloned brother ...
	*m_pButtonObject = *m_pClonedButton;
	MenuObject *pObject;
	for (t=0;t<m_pButtonObject->getNormalCount();t++)	{
		pObject = m_pButtonObject->getNormal(t);
		connect (pObject, SIGNAL(signalDeleteMe(MenuObject *)),
			parent(), SLOT(slotDeleteObject(MenuObject *)));
		connect (pObject, SIGNAL(signalDefineAsButton(MenuObject *)),
			parent(), SLOT(slotDefineAsButton(MenuObject *)));
		connect (pObject, SIGNAL(signalShadowMe(MenuObject *)),
			parent(), SLOT(slotAddShadow(MenuObject *)));
		connect (pObject, SIGNAL(signalUpdateStructure()),
			parent(), SLOT(slotUpdateStructure()));
		connect (pObject, SIGNAL(signalUpdatePixmap()),
			parent(), SLOT(slotUpdatePixmap()));
	}
	for (t=0;t<m_pButtonObject->getHighlightedCount();t++)	{
		pObject = m_pButtonObject->getHighlighted(t);
		connect (pObject, SIGNAL(signalDeleteMe(MenuObject *)),
			parent(), SLOT(slotDeleteObject(MenuObject *)));
		connect (pObject, SIGNAL(signalDefineAsButton(MenuObject *)),
			parent(), SLOT(slotDefineAsButton(MenuObject *)));
		connect (pObject, SIGNAL(signalUpdateStructure()),
			parent(), SLOT(slotUpdateStructure()));
		connect (pObject, SIGNAL(signalUpdatePixmap()),
			parent(), SLOT(slotUpdatePixmap()));
	}
	for (t=0;t<m_pButtonObject->getSelectedCount();t++)	{
		pObject = m_pButtonObject->getSelected(t);
		connect (pObject, SIGNAL(signalDeleteMe(MenuObject *)),
			parent(), SLOT(slotDeleteObject(MenuObject *)));
		connect (pObject, SIGNAL(signalDefineAsButton(MenuObject *)),
			parent(), SLOT(slotDefineAsButton(MenuObject *)));
		connect (pObject, SIGNAL(signalUpdateStructure()),
			parent(), SLOT(slotUpdateStructure()));
		connect (pObject, SIGNAL(signalUpdatePixmap()),
			parent(), SLOT(slotUpdatePixmap()));
	}
	delete m_pClonedButton;
	emit (signalUpdateStructure ());
	emit (signalUpdatePixmap ());
	accept();
}


