/****************************************************************************
** ButtonObject class
**
** Created: Tue Feb 02 22:06:51 2004
**      by: Varol Okan using Kate
**
** This class is the encapsulation of the ButtonObject. 
** 
** A ButtonObject is the object in a menu which was created by
** either dragging a SourceFileEntry over to the  DVD menu or
** by choosing "define as button" from the context menu of an 
** MenuObject.
**
****************************************************************************/

#include <qtimer.h>
#include <qobject.h>
#include <qfileinfo.h>
#include <qlistview.h>
#include <qpopupmenu.h>

#include "global.h"
#include "xml_dvd.h"
#include "menupreview.h"
#include "dialogbutton.h"
#include "menuobject.h"
#include "frameobject.h"
#include "buttonobject.h"
#include "qdvdauthor.h"
#include "imageobject.h"
#include "sourcefileentry.h"
#include "structuretoolbar.h"

ButtonObject::ButtonObject (QWidget *pParent) //, const char *pName, WFlags flags)
	: MenuObject (pParent)
{
	m_qsObjectType = QString (BUTTON_OBJECT);
	m_iButtonState = STATE_NORMAL;
	m_pSourceFileEntry = NULL;
	m_bMoveable = true;
}

ButtonObject::~ButtonObject ()
{
	// Please note that the m_listNormalState etc objects are not destroyed here
	// As this is merely a holding place for the Objects.
	// Creation and destruction is done in the Parent (MenuPreview / ButtonPreview etc.)
}

MenuObject *ButtonObject::clone ( QWidget *pParent )
{
  if ( ! pParent )
    pParent = MenuObject::parent ( );
  uint t;
  ButtonObject *pNewObject = new ButtonObject ( pParent );
  for (t=0;t<m_listNormalState.count();t++)
    pNewObject->appendNormal (m_listNormalState[t]->clone ( pParent ) );
  for (t=0;t<m_listSelectedState.count();t++)
    pNewObject->appendSelected (m_listSelectedState[t]->clone ( pParent ) );
  for (t=0;t<m_listHighlightedState.count();t++)
    pNewObject->appendHighlighted (m_listHighlightedState[t]->clone ( pParent ) );
  
  pNewObject->setSourceFileEntry(sourceFileEntry());
  pNewObject->setAction   ( action    ( ) );
  pNewObject->setPreAction( preAction ( ) );
  pNewObject->setName     ( name      ( ) );
  pNewObject->setNext     ( NEXT_BUTTON_UP,    m_qsUp    );
  pNewObject->setNext     ( NEXT_BUTTON_DOWN,  m_qsDown  );
  pNewObject->setNext     ( NEXT_BUTTON_RIGHT, m_qsRight );
  pNewObject->setNext     ( NEXT_BUTTON_LEFT,  m_qsLeft  );
  
  return pNewObject;
}

ButtonObject &ButtonObject::operator = (ButtonObject &theOther)
{
	uint t;
	clear ();
	setSourceFileEntry(theOther.sourceFileEntry());
	m_qsAction    = theOther.action();
	m_qsPreAction = theOther.preAction();
	m_qsName      = theOther.name();
	m_qsUp        = theOther.next(NEXT_BUTTON_UP);
	m_qsDown      = theOther.next(NEXT_BUTTON_DOWN);
	m_qsRight     = theOther.next(NEXT_BUTTON_RIGHT);
	m_qsLeft      = theOther.next(NEXT_BUTTON_LEFT);
	// The following lists hold the information for the different button states.
	for (t=0;t<theOther.getNormalCount();t++)
		appendNormal(theOther.getNormal(t));
	for (t=0;t<theOther.getSelectedCount();t++)
		appendSelected(theOther.getSelected(t));
	for (t=0;t<theOther.getHighlightedCount();t++)
		appendHighlighted(theOther.getHighlighted(t));
	return *this;
}

void ButtonObject::clear ()
{
	uint t;

	m_iButtonState = STATE_NORMAL;
	m_qsAction     = QString ("");
	m_qsPreAction  = QString ("");
	m_qsUp         = QString ("");
	m_qsDown       = QString ("");
	m_qsRight      = QString ("");
	m_qsLeft       = QString ("");
	m_pSourceFileEntry = NULL;

	for (t=0;t<m_listNormalState.count();t++)
		delete m_listNormalState[t];
	for (t=0;t<m_listSelectedState.count();t++)
		delete m_listSelectedState[t];
	for (t=0;t<m_listHighlightedState.count();t++)
		delete m_listHighlightedState[t];
	m_listNormalState.clear();
	m_listSelectedState.clear();
	m_listHighlightedState.clear();
}

void ButtonObject::drawContents (QPainter *pPainter)
{
	drawContents(pPainter, BACKGROUND_IMG);
//	m_listNormalState[0]->drawContents(pPainter);
//	m_boundingRect = m_listNormalState[0]->boundingRect();
//	m_rect = m_listNormalState[0]->rect();
}

void ButtonObject::drawContents (QPainter *pPainter, uint iWhichState)
{
	switch (iWhichState)	{
	case BACKGROUND_IMG:
		if (m_listNormalState[0])	{
			m_listNormalState[0]->drawContents(pPainter);
			m_boundingRect = m_listNormalState[0]->boundingRect();
			m_rect = m_listNormalState[0]->rect();
		}
	break;
	case HIGHLIGHTED_MASK:
		if (m_listHighlightedState[0])
			m_listHighlightedState[0]->drawContents(pPainter);
	break;
	case SELECTED_MASK:
		if (m_listSelectedState[0])
			m_listSelectedState[0]->drawContents(pPainter);
	break;
	}
}

void ButtonObject::drawContents (QPainter *pPainter, int iRenderFrameNumber, int iTotalFrames)
{
	if (m_listNormalState[0])	{
		m_listNormalState[0]->drawContents(pPainter, iRenderFrameNumber, iTotalFrames);
		m_boundingRect = m_listNormalState[0]->boundingRect();
		m_rect = m_listNormalState[0]->rect();
	}
}

bool ButtonObject::mouseMoveEvent (QMouseEvent *pEvent)
{
  if (m_bMoveable)	{
    switch ( m_objectState )  {	
    case MenuObject::StateScaleTLXY:
    case MenuObject::StateScaleTRXY:
    case MenuObject::StateScaleBLXY:
    case MenuObject::StateScaleBRXY:
    case MenuObject::StateScaleLeftX:
    case MenuObject::StateScaleRightX:
    case MenuObject::StateScaleTopY:
    case MenuObject::StateScaleBottomY:
    case MenuObject::StateRotate: {
      uint t;
      Modifiers *pModifiers, *pObjectModifiers;
      MenuObject::mouseMoveEvent ( pEvent );
      pModifiers = modifiers ();
      for (t=0;t<m_listNormalState.count();t++) {
	pObjectModifiers = m_listNormalState[t]->modifiers ();
	*pObjectModifiers = *pModifiers;
      }
      for (t=0;t<m_listSelectedState.count();t++) {
	pObjectModifiers = m_listSelectedState[t]->modifiers ();
	*pObjectModifiers = *pModifiers;
      }
      for (t=0;t<m_listHighlightedState.count();t++) {
	pObjectModifiers = m_listHighlightedState[t]->modifiers ();
	*pObjectModifiers = *pModifiers;
      }
    }
      break;
    case MenuObject::StateMoveObject:
    default: {
      // This will move the ButtonObject and all associated objects around and around and around we go ...
      uint t;
      QRect theRect = rect();
      int iX, iY, iWidth, iHeight;
      iWidth  = rect().width ();
      iHeight = rect().height();
      iX = rect().x() - (m_currentMousePos.x() - pEvent->pos().x());
      iY = rect().y() - (m_currentMousePos.y() - pEvent->pos().y());
      theRect.setX(iX);
      theRect.setY(iY);
      theRect.setWidth(iWidth);
      theRect.setHeight(iHeight);
      
      setRect(theRect);
      for (t=0;t<m_listNormalState.count();t++)
	m_listNormalState[t]->setRect (theRect);
      for (t=0;t<m_listSelectedState.count();t++)
	m_listSelectedState[t]->setRect (theRect);
      for (t=0;t<m_listHighlightedState.count();t++)
	m_listHighlightedState[t]->setRect (theRect);
      }
    }
  }
  m_currentMousePos = pEvent->pos();
  return false;
}

bool ButtonObject::mousePressEvent (QMouseEvent *pEvent)
{
	m_currentMousePos = pEvent->pos ( );
	if (pEvent->button() == Qt::RightButton)	{
		QPoint globalPos = pEvent->globalPos();
		return createContextMenu ( globalPos );
	}
	else // Here I only want to activate the drawing of the frame rather then the full thing.
	  if ( m_listNormalState[0] )
	       m_listNormalState[0]->mousePressEvent (pEvent);
	m_bDrawRect = true;
	return false;
}

bool ButtonObject::mouseReleaseEvent (QMouseEvent *pEvent)
{
	m_bDrawRect = false;
	if ( m_listNormalState[0] )
	     m_listNormalState[0]->mouseReleaseEvent (pEvent);
	emit (signalUpdatePixmap());
	emit (signalUpdateStructure());
	return false;
}

bool ButtonObject::mouseDoubleClickEvent(QMouseEvent *)
{
  // Call MenuPreview::slotCreateButtonDialog ()
  emit (signalCreateButtonDialog (this));
  return false;
}

MenuObject *ButtonObject::shadow ( )
{
  MenuObject *pNormal = getNormal ( 0 );
  if ( pNormal )
    return pNormal->shadow ( );
  return NULL;
}

void ButtonObject::updateShadow ( )
{
  MenuObject *pNormal = getNormal ( 0 );
  if ( pNormal )
       pNormal->updateShadow ( );
}

void ButtonObject::setShadow ( MenuObject *pShadow )
{
  MenuObject *pNormal = getNormal ( 0 );
  if ( pNormal )
       pNormal->setShadow ( pShadow );
}

void ButtonObject::appendNormal (MenuObject *pObject)
{
	m_listNormalState.append (pObject);
}

void ButtonObject::appendSelected (MenuObject *pObject)
{
	m_listSelectedState.append (pObject);
}

void ButtonObject::appendHighlighted (MenuObject *pObject)
{
	m_listHighlightedState.append (pObject);
}

uint ButtonObject::getNormalCount ()
{
	return m_listNormalState.count();
}

MenuObject *ButtonObject::getNormal (int iNr)
{
	if (iNr > (int)m_listNormalState.count())
		return NULL;
	return m_listNormalState[iNr];
}

uint ButtonObject::getSelectedCount ()
{
	return m_listSelectedState.count();
}

MenuObject *ButtonObject::getSelected (int iNr)
{
	if (iNr > (int)m_listSelectedState.count())
		return NULL;
	return m_listSelectedState[iNr];
}

uint ButtonObject::getHighlightedCount ()
{
	return m_listHighlightedState.count();
}

MenuObject *ButtonObject::getHighlighted (int iNr)
{
	if (iNr > (int)m_listHighlightedState.count())
		return NULL;
	return m_listHighlightedState[iNr];
}

void ButtonObject::deleteMasks()
{
	// This function handles only the case of the cancelation of the Button creation
	// From the DialogButton - class.
	// 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.
	uint t;
	// we can leave the m_listNormalState - objects as they reflect the original Objects.
	// However the m_listSelected / Highlighted should be deleted ...
	for (t=0;t<m_listSelectedState.count();t++)
		delete m_listSelectedState[t];
	for (t=0;t<m_listHighlightedState.count();t++)
		delete m_listHighlightedState[t];
	m_listSelectedState.clear();
	m_listHighlightedState.clear();
}

bool ButtonObject::readProjectFile  (QDomNode &theNode)
{
	// Okay, here we retain the stored data from the xml file.
	QDomElement theElement = theNode.toElement();
	QDomAttr attribute;

	attribute = theElement.attributeNode ( BUTTON_OBJECT_NAME );
	if (!attribute.isNull())
		m_qsName = attribute.value();

	attribute = theElement.attributeNode ( BUTTON_OBJECT_ACTION );
	if (!attribute.isNull())
		m_qsAction = attribute.value();

	attribute = theElement.attributeNode ( BUTTON_OBJECT_PRE_ACTION );
	if ( ! attribute.isNull ( ) )
		m_qsPreAction = attribute.value ( );

	attribute = theElement.attributeNode ( BUTTON_OBJECT_UP );
	if (!attribute.isNull())
		m_qsUp = attribute.value();
	else
		m_qsUp = QString ("-- default --");
	
	attribute = theElement.attributeNode ( BUTTON_OBJECT_DOWN );
	if (!attribute.isNull())
		m_qsDown = attribute.value();
	else
		m_qsDown = QString ("-- default --");

	attribute = theElement.attributeNode ( BUTTON_OBJECT_LEFT );
	if (!attribute.isNull())
		m_qsLeft = attribute.value();
	else
		m_qsLeft = QString ("-- default --");

	attribute = theElement.attributeNode ( BUTTON_OBJECT_RIGHT );
	if (!attribute.isNull())
		m_qsRight = attribute.value();
	else
		m_qsRight = QString ("-- default --");

	attribute = theElement.attributeNode ( BUTTON_OBJECT_MOVEABLE );
	m_bMoveable = true;
	if (!attribute.isNull())	{
		if (attribute.value () == QString ("false"))
			m_bMoveable = false;
	}

	attribute = theElement.attributeNode ( BUTTON_OBJECT_SOURCE_ENTRY);
	if (!attribute.isNull())
		m_qsSourceDisplayName = attribute.value();
	// Please note that the nortmal / selected / highlighted objects are read
	// in by ButtonObject::readObjects(...);
	return true;
}

bool ButtonObject::readObjects (QDomNode &theNode, MenuPreview *pPreview)
{
	QDomElement buttonElement;
	QDomNode buttonNode = theNode.firstChild();
	QDomNode childNode;
	MenuObject *pNewObject = NULL;
	while (!buttonNode.isNull())	{
		buttonElement   = buttonNode.toElement();
		QString tagName = buttonElement.tagName();
		childNode = buttonNode.firstChild();
		// Next we should create the new Object but if we see the
		// MenoObject tag it means it is the MenuObject vars of the button
		// itself, thus we don't want to create anything. (It would put out a warning).
		if (tagName != MENU_OBJECT)
			pNewObject = pPreview->readObject ( childNode );
		if (tagName == BUTTON_OBJECT_NORMAL)
			m_listNormalState.append ( pNewObject );

		else if (tagName == BUTTON_OBJECT_SELECTED)
			m_listSelectedState.append( pNewObject );

		else if (tagName == BUTTON_OBJECT_HIGHLIGHTED)
			m_listHighlightedState.append ( pNewObject );

		else if (tagName == MENU_OBJECT)
			MenuObject::readProjectFile( theNode );

		else
			printf ("Warning : ButtonObject::readObjects -=> wrong XML Node <%s>\nContinuing ...\n", (const char *)tagName);
		buttonNode = buttonNode.nextSibling ();
	}
	return true;
}

bool ButtonObject::writeProjectFile (QDomElement &theElement)
{
	uint t;
	QDomDocument xmlDoc = theElement.ownerDocument();
	QDomElement buttonNode = xmlDoc.createElement( BUTTON_OBJECT );	// <FrameObject>
	// Here we set the attributes of the <dvdauthor> tag
	if (!m_qsName.isNull())
		buttonNode.setAttribute( BUTTON_OBJECT_NAME,   m_qsName );
	if (!m_qsAction.isNull())
		buttonNode.setAttribute( BUTTON_OBJECT_ACTION, m_qsAction );
	if ( ! m_qsPreAction.isNull ( ) )
		buttonNode.setAttribute( BUTTON_OBJECT_PRE_ACTION, m_qsPreAction );
	if ( (!m_qsUp.isNull()) || ( m_qsUp != QString ("-- default --")) )
		buttonNode.setAttribute( BUTTON_OBJECT_UP,     m_qsUp );
	if ( (!m_qsDown.isNull()) || ( m_qsDown != QString ("-- default --")) )
		buttonNode.setAttribute( BUTTON_OBJECT_DOWN,   m_qsDown );
	if ( (!m_qsLeft.isNull()) || ( m_qsLeft != QString ("-- default --")) )
		buttonNode.setAttribute( BUTTON_OBJECT_LEFT,   m_qsLeft );
	if ( (!m_qsRight.isNull()) || ( m_qsRight != QString ("-- default --")) )
		buttonNode.setAttribute( BUTTON_OBJECT_RIGHT,  m_qsRight );
	if (!m_bMoveable)
		buttonNode.setAttribute( BUTTON_OBJECT_MOVEABLE, QString ("false") );

	if (m_pSourceFileEntry)
		buttonNode.setAttribute( BUTTON_OBJECT_SOURCE_ENTRY,  m_pSourceFileEntry->qsDisplayName );
//printf ("ButtonObject::writeProjectFile <%s> - <%s> \n", (const char *)m_pSourceFileEntry->qsDisplayName, (const char *)m_qsAction );

	// And here we store the ButtonObjects children ...
	QDomElement normalNode = xmlDoc.createElement( BUTTON_OBJECT_NORMAL );
	for (t=0;t<m_listNormalState.count();t++)
		m_listNormalState[t]->writeProjectFile ( normalNode );

	QDomElement selectedNode = xmlDoc.createElement( BUTTON_OBJECT_SELECTED );
	for (t=0;t<m_listSelectedState.count();t++)
		m_listSelectedState[t]->writeProjectFile ( selectedNode );

	QDomElement highlightedNode = xmlDoc.createElement( BUTTON_OBJECT_HIGHLIGHTED );
	for (t=0;t<m_listHighlightedState.count();t++)
		m_listHighlightedState[t]->writeProjectFile ( highlightedNode );

	buttonNode.appendChild( normalNode );
	buttonNode.appendChild( selectedNode );
	buttonNode.appendChild( highlightedNode );
	
	theElement.appendChild( buttonNode );
	// And here we write the base class ...
	return MenuObject::writeProjectFile( buttonNode );
}

bool ButtonObject::createContextMenu (QPoint globalPos)
{
	int     iID = -1;
	bool    bHasPropertyDialog;
	QString qsObject, qsEditObject;
        QPoint  globalPos2 = globalPos;
	QPopupMenu *pStackMenu = new QPopupMenu(m_pParent);
	pStackMenu->insertItem ( tr ("Cut") , this, SLOT ( slotCut  ( ) ) );
	pStackMenu->insertItem ( tr ("Copy"), this, SLOT ( slotCopy ( ) ) );
	pStackMenu->insertSeparator ( );
	pStackMenu->insertItem ( tr ("To Front")  , this, SLOT(slotToFront()));
	pStackMenu->insertItem ( tr ("To Back")   , this, SLOT(slotToBack()));
	globalPos.setY ( globalPos.y ( ) - 25 );
	globalPos.setX ( globalPos.x ( ) - pStackMenu->sizeHint().width()); // -100);
	pStackMenu->popup(globalPos, 1);

	bHasPropertyDialog = false;
	qsEditObject = tr ( "Edit Object ..." );
	if ( m_listNormalState[0] ) {
	  if ( m_listNormalState[0]->objectType ( ) == QString ( IMAGE_OBJECT ) ) {
	    qsEditObject = tr ( "Edit Image ..." );
	    qsObject     = tr ( "Image Properties ..." );
	    bHasPropertyDialog = true;
	  }
	  else if ( m_listNormalState[0]->objectType ( ) == QString ( MOVIE_OBJECT ) ) {
	    qsEditObject = tr ( "Edit Movie ..." );
	    qsObject     = tr ( "Movie Properties ..." );
	    bHasPropertyDialog = true;
	  }
	}

	if ( m_pContextMenu )
	     delete m_pContextMenu;
	m_pContextMenu = new QPopupMenu(m_pParent);
	m_pContextMenu->setCheckable (true);
	if ( bHasPropertyDialog )
	     m_pContextMenu->insertItem ( qsObject,          (QObject *)this, SLOT(slotObjectProperties ( ) ) );
	m_pContextMenu->insertItem (       qsEditObject,     (QObject *)this, SLOT(slotEditObject ( ) ) );
	m_pContextMenu->insertSeparator();
	m_pContextMenu->insertItem ( tr ("Edit Button ..."), (QObject *)this, SLOT(slotEdit       ( ) ) );
	m_pContextMenu->insertItem ( tr ("Unbutton"),        (QObject *)this, SLOT(slotUnbutton   ( ) ) );
	m_pContextMenu->insertItem ( tr ("Delete"),          (QObject *)this, SLOT(slotDelete     ( ) ) );
	iID = m_pContextMenu->insertItem ( tr ("Moveable"),  (QObject *)this, SLOT(slotMoveable   ( ) ) );
	m_pContextMenu->insertSeparator();
	m_pContextMenu->insertItem ( tr ("Add Frame"),       (QObject *)this, SLOT(slotAddFrame   ( ) ) );
	m_pContextMenu->insertItem ( tr ("Add Image"),       (QObject *)this, SLOT(slotAddImage   ( ) ) );
	m_pContextMenu->insertItem ( tr ("Add Movie"),       (QObject *)this, SLOT(slotAddMovie   ( ) ) );
	m_pContextMenu->setItemChecked (iID, m_bMoveable);

	m_pContextMenu->exec(globalPos2, 5);

	delete pStackMenu;
	if (m_pContextMenu)
		delete m_pContextMenu;
	m_pContextMenu = NULL;

	// Here we mark that the user called a menu item thus we don't want the
	// base classes to continue with the mouse event
//	if (iReturn != -1)
		return true;
}

void ButtonObject::createStructure (QListViewItem *pParentItem)
{
  // Creating teh ListView structure of this Button.
  StructureItem *pButtonItem;
  StructureItem *pStateItem;

  QString qsAction;
  QStringList actionList;
  if (!m_qsAction.isEmpty())	{	// For new buttons this might be empty ...
    actionList = QStringList::split (QString (STRING_SEPARATOR), m_qsAction);
    if (actionList.count() == 1)	
      qsAction = m_qsAction;
    else	{
      qsAction = actionList[0] + QString (" ") +actionList[1] + QString (" ") +actionList[2];
      if (actionList.count() == 4)
	qsAction += QString (" ") +actionList[3];
    }
  }
  pButtonItem = new StructureItem(this, pParentItem, m_qsName, qsAction);
  pButtonItem->setExpandable (TRUE);
  
  uint t;
  for (t=0;t<m_listHighlightedState.count();t++)	{
    pStateItem = new StructureItem(this, pButtonItem, QString ("Highlighted"), QString (""));
    pStateItem->setExpandable (TRUE);
    m_listHighlightedState[t]->createStructure ( pStateItem );
  }
  for (t=0;t<m_listSelectedState.count();t++)	{
    pStateItem = new StructureItem(this, pButtonItem, QString ("Selected"), QString (""));
    pStateItem->setExpandable (TRUE);
    m_listSelectedState[t]->createStructure ( pStateItem );
  }
  for (t=0;t<m_listNormalState.count();t++)	{
    m_listNormalState[t]->createStructure ( pButtonItem );
  }
}

void ButtonObject::replaceColor (QColor theColor, QColor oldColor)
{
	// We handle the actual color as a unique index. Thus we allow 
	// the user to utilise any of the 4 available colors for any purpose.
	uint t;
	
	// Does this make sense ??? I don't know yet ...
//	for (t=0;t<m_listNormalState.count();t++)	{
//		m_listNormalState[t]->replaceColor (theColor);
//	}
	for (t=0;t<m_listSelectedState.count();t++)	{
		m_listSelectedState[t]->replaceColor (theColor, oldColor);
	}
	for (t=0;t<m_listHighlightedState.count();t++)	{
		m_listHighlightedState[t]->replaceColor (theColor, oldColor);
	}
}

QRect &ButtonObject::boundingRect()
{
  // Here we have a little special handling for frames to include the frame width
  // for button objects.
  static QRect rect;
  FrameObject  tempFrameObject, *pFrame;
  int iHalf;
  rect = m_boundingRect;

  if ( m_listHighlightedState.count () < 1 )
    return rect;

  if ( m_listHighlightedState[0]->objectType () == tempFrameObject.objectType() ) {
    pFrame = (FrameObject *)m_listHighlightedState[0];
    iHalf  = (int)((float)pFrame->width() / 2.0);
    rect = QRect (m_boundingRect.x()-iHalf, m_boundingRect.y()-iHalf, m_boundingRect.width()+2*iHalf,  m_boundingRect.height()+2*iHalf);
  }

  return rect;
}

void ButtonObject::setAction(QString &qsAction)
{
	m_qsAction = qsAction;
}

QString &ButtonObject::action()
{
	return m_qsAction;
}

void ButtonObject::setPreAction(QString &qsPreAction)
{
  m_qsPreAction = qsPreAction;
}

QString &ButtonObject::preAction()
{
  return m_qsPreAction;
}

void ButtonObject::setSourceFileEntry(SourceFileEntry *pEntry)
{
	m_pSourceFileEntry = pEntry;
	if (pEntry)
		m_qsSourceDisplayName = pEntry->qsDisplayName;
	else
		m_qsSourceDisplayName = QString ();
}

QString &ButtonObject::sourceDisplayName ()
{
	return m_qsSourceDisplayName;
}

SourceFileEntry *ButtonObject::sourceFileEntry()
{
	return m_pSourceFileEntry;
}

SourceFileInfo *ButtonObject::sourceFileInfo()
{
  uint            t;
  QString         qsName;
  QFileInfo       fileInfo;
  QStringList     actionList;
  SourceFileInfo *pInfo = NULL;

  if ( ! m_pSourceFileEntry )
    return pInfo;

  // default to the first info 
  pInfo = m_pSourceFileEntry->listFileInfos[0];

  if ( ! m_qsAction.isEmpty() )  {  // For new buttons this might be empty ...
    actionList = QStringList::split (QString (STRING_SEPARATOR), m_qsAction);
    if (actionList.count() == 4)
      qsName = actionList[actionList.count() - 2];
    else if (actionList.count() > 1)
      qsName = actionList[1];
  }
  // find the right sourceFileInfo from the action - string
  for ( t=0;t<m_pSourceFileEntry->listFileInfos.count();t++ ) {
    fileInfo.setFile ( m_pSourceFileEntry->listFileInfos[t]->qsFileName );
    if ( qsName == fileInfo.fileName () )
      return m_pSourceFileEntry->listFileInfos[t];
  }

  return pInfo;
}

int ButtonObject::chapter ( bool bAllEntries )
{
  uint t, iTemp;
  int iChapterNumber = 1;
  SourceFileEntry *pEntry = sourceFileEntry ();
  SourceFileInfo  *pInfo  = sourceFileInfo  ();
  if ( ( ! pEntry ) || ( ! pInfo ) )
    return 0;  // No Info present ... Error
  QStringList     actionList;

  if ( ! m_qsAction.isEmpty() )  // For new buttons this might be empty ...
    actionList = QStringList::split (QString (STRING_SEPARATOR), m_qsAction);
  if ( actionList.count() < 1 )
    return iChapterNumber;
  
  // To get the total chapter number you have to add up the SourceFileInfos
  // chapters in the SourceFileEntry that come before the actual SourceFIleInfo
  // on which the button points.
  iChapterNumber = 1;
  if ( bAllEntries ) {
    for (t=0;t<pEntry->listFileInfos.count();t++) {
      if ( pEntry->listFileInfos[t] == pInfo )
	break; // break out of the loop
      iTemp = pEntry->listFileInfos[t]->listChapters.count();
      //iTemp = (iTemp < 1) ? 1: iTemp; // removed 20060920. No chapter, no -pit-stop-, no count increase.
      iChapterNumber += iTemp;
    }
  }

  if ( pInfo->listChapters.count () > 0 ) {
    for ( t=0;t<pInfo->listChapters.count ();t++ ) {
      if (pInfo->listChapters[t] == actionList[actionList.count()-1])	// the chapter
	iChapterNumber += t;
    }
  }
  else // In order to reach this VOB it needs to have at least one chapter to get to. Remember pInfo is associated with this button.
    pInfo->listChapters.append ( "00:00:00.000" ); 

  return iChapterNumber;  // Info present but no chapter info...
}

void ButtonObject::setNext(uint iNext, QString &qsNext)
{
	switch (iNext)	{
	case NEXT_BUTTON_UP:
		m_qsUp = qsNext;
	break;
	case NEXT_BUTTON_DOWN:
		m_qsDown = qsNext;
	break;
	case NEXT_BUTTON_RIGHT:
		m_qsRight = qsNext;
	break;
	case NEXT_BUTTON_LEFT:
		m_qsLeft = qsNext;
	break;
	};
}

QString &ButtonObject::next(uint iNext)
{
	switch (iNext)	{
	case NEXT_BUTTON_UP:
		return m_qsUp;
	break;
	case NEXT_BUTTON_DOWN:
		return m_qsDown;
	break;
	case NEXT_BUTTON_RIGHT:
		return m_qsRight;
	break;
	case NEXT_BUTTON_LEFT:
		return m_qsLeft;
	break;
	};
	return m_qsUp;
}

void ButtonObject::slotEdit ( )
{
	mouseDoubleClickEvent ( NULL );
}

void ButtonObject::slotEditObject ( )
{
  if ( m_listNormalState[0] )
       m_listNormalState[0]->mouseDoubleClickEvent ( NULL );
}

void ButtonObject::slotObjectProperties ( )
{
  if ( m_listNormalState[0] ) {
    MenuObject *pObject = m_listNormalState[0];
    if ( ( pObject->objectType ( ) == QString ( IMAGE_OBJECT ) ) || 
	 ( pObject->objectType ( ) == QString ( MOVIE_OBJECT ) ) ) {
      ImageObject *pImage = (ImageObject *)pObject;
      pImage->slotProperties ( );
    }
  }
}

void ButtonObject::slotUnbutton ( )
{
  // get a slight delay to allow the ContextMenu to be destroyed ...
  QTimer::singleShot ( 10, this, SLOT ( slotEmitUnbuttonMe ( ) ) );
}

void ButtonObject::slotEmitUnbuttonMe ( )
{
  // Here we are going to split the Button object into its three distinkt 
  // objects and add them to the Preview (MenuPreview that is).
  emit ( signalUnbuttonMe ( this ) );
  // The work is done in MenuPreview::slotUnbutton()
}

void ButtonObject::slotMoveable()
{
	// if iot is not moveable the the Button is locked in.
	m_bMoveable = !m_bMoveable;
}

void ButtonObject::slotAddFrame()
{

}

void ButtonObject::slotAddImage()
{

}

void ButtonObject::setRect ( QRect &theRect )
{
  uint t;
  for ( t=0; t<m_listHighlightedState.count ( ); t++ )
    m_listHighlightedState[t]->setRect ( theRect );
  for ( t=0; t<m_listSelectedState.count ( ); t++ )
    m_listSelectedState[t]->setRect ( theRect );
  for ( t=0; t<m_listNormalState.count ( ); t++ )
    m_listNormalState[t]->setRect ( theRect );
  MenuObject::setRect ( theRect );
}

QRect &ButtonObject::rect ( )
{
  if ( m_listHighlightedState.count ( ) > 0 )
    return m_listHighlightedState[ 0 ]->rect ( );

  return m_rect;
}

void ButtonObject::slotAddMovie() // movie object for the Menu that is ...
{

}

AnimationAttribute *ButtonObject::getSpecificAttributes (long, QString)
{
	return NULL;
}

