/****************************************************************************
** ObjectCollection class 
**
**   Created : Tue Feb 02 22:06:51 2004
**        by : Varol Okan using Kate
** Copyright : (c) Varol Okan
**   License : GPL v 2.0
**
** This class is the encapsulation of the ObjectCollection.
**
** The ObjectCollection is not yet finished. It is intended to hold a list
** of MenuObject's which are linked to each other. Meaning if you move 
** the collection each member of it will move the same extend.
**
** Another use is to create a template which will fit the images/movies
** into a fixed scheme.
**
****************************************************************************/
#include <qpopupmenu.h>
#include <qpainter.h>
#include <qwmatrix.h>
#include <qpixmap.h>

#include "xml_dvd.h"
#include "menupreview.h"
#include "menuobject.h"
#include "buttonobject.h"
#include "objectcollection.h"
#include "structuretoolbar.h"

ObjectCollection::Collection::Collection ( MenuObject *pTheObject, bool bDelete )
{
  pObject = pTheObject;
  bDeleteMe = bDelete;
}

ObjectCollection::Collection::~Collection ( )
{
  if ( bDeleteMe )
    delete pObject;
  pObject = NULL;
}

ObjectCollection::ObjectCollection ( QWidget *pParent )
  : MenuObject ( pParent )
{
  m_qsObjectType = QString ( OBJECT_COLLECTION );
}

ObjectCollection::~ObjectCollection ( )
{
  clear ( );
}

void ObjectCollection::clear ( )
{
  uint t;
  for (t=0;t<m_listObjectCollection.count();t++)
    delete m_listObjectCollection[t];

  m_listObjectCollection.clear ( );
}

int ObjectCollection::getCount ( )
{
  return m_listObjectCollection.count ( );
}

MenuObject *ObjectCollection::getObject (int iObjectNumber)
{
  if (iObjectNumber > (int)m_listObjectCollection.count())
    return NULL;
  return m_listObjectCollection[iObjectNumber]->pObject;
}

void ObjectCollection::append ( MenuObject *pNewObject, bool bDeleteThisObject )
{
  if ( pNewObject )
    m_listObjectCollection.append ( new Collection ( pNewObject, bDeleteThisObject ) );
}

void ObjectCollection::setObjects ( QValueList<MenuObject *> &list, bool bDeleteThem )
{
  clear ( );
  QValueList<MenuObject *>::iterator it = list.begin ( );
  while ( it != list.end ( ) )
    append ( *it++, bDeleteThem );
}

bool ObjectCollection::contains ( MenuObject *pObject )
{
  uint t;
  for ( t=0;t<m_listObjectCollection.count ();t++) {
    if ( m_listObjectCollection[t]->pObject == pObject )
      return true;
  }
  return false;
}

MenuObject *ObjectCollection::clone ( QWidget *pParent, MenuObject * )
{
  if ( ! pParent )
    pParent = MenuObject::parent ( );

  ObjectCollection *pNewObject = new ObjectCollection ( pParent );
  MenuObject       *pObject;
  uint t;
  for ( t=0; t<m_listObjectCollection.count (); t++) {
    pObject = m_listObjectCollection[t]->pObject->clone ( pParent, pNewObject );
    pNewObject->append ( pObject );
  }

  return pNewObject;
}

void ObjectCollection::drawContents (QPainter *pPainter)
{
  // Here we simply pass the painter to the attached objects. No magic here !!!
  uint t;
  for (t=0;t<m_listObjectCollection.count();t++)
    m_listObjectCollection[t]->pObject->drawContents(pPainter);
}

void ObjectCollection::drawContents (QPainter *pPainter, int iFrameNumber, int iTotalNumberOfFrames)
{
  // Here we simply pass the painter to the attached objects. No magic here !!!
  uint t;
  for (t=0;t<m_listObjectCollection.count();t++)
    m_listObjectCollection[t]->pObject->drawContents(pPainter, iFrameNumber, iTotalNumberOfFrames);
}

bool ObjectCollection::mousePressEvent ( QMouseEvent *pEvent )
{
  m_currentMousePos = pEvent->pos ( );
  if ( pEvent->button ( ) == Qt::RightButton )  {
    QPoint globalPos = pEvent->globalPos ( );
    return createContextMenu ( globalPos );
  }
  else
    m_bDrawRect = true;
  return false;
}

bool ObjectCollection::mouseMoveEvent ( QMouseEvent *pEvent )
{
  // Here we simply pass the painter to the attached objects. No magic here !!!
  uint t;
  for ( t=0; t<m_listObjectCollection.count ( ); t++ )
    m_listObjectCollection[t]->pObject->mouseMoveEvent ( pEvent );

/*
  int iX, iY, iWidth, iHeight;
  QRect theRect;
  iX = rect().x() - (m_currentMousePos.x() - pEvent->pos().x());
  iY = rect().y() - (m_currentMousePos.y() - pEvent->pos().y());
  iWidth  = rect( ).width  ( );
  iHeight = rect( ).height ( );
  theRect.setX  ( iX );
  theRect.setY  ( iY );
  theRect.setWidth  ( iWidth  );
  theRect.setHeight ( iHeight );
  m_pData->m_rect = theRect;;
*/
  m_currentMousePos = pEvent->pos ( );
  return true;
}

bool ObjectCollection::mouseReleaseEvent ( QMouseEvent * )
{
  m_bDrawRect = false;
  return false;
}

void ObjectCollection::setShadow ( MenuObject *pShadow ) 
{
  // In this function we'll create a new shadow object for each object in the list.
  // and then take control of the ObjectCollections shadow object itself
  uint t;
  MenuObject *pNewShadow = NULL;

  for (t=0;t<m_listObjectCollection.count();t++) {
    if ( pShadow )
         pNewShadow = pShadow->clone ( );
    //printf ( "%s::%s::%d  Shadow<%p> for object<%p\n", __FILE__, __FUNCTION__, __LINE__, pNewShadow, m_listObjectCollection[t]->pObject );
    m_listObjectCollection[t]->pObject->setShadow ( pNewShadow );
  }
  MenuObject::setShadow ( pShadow );
}

void ObjectCollection::slotToFront ()
{
  // Send it all the way to the front
  uint t;
  for (t=0;t<m_listObjectCollection.count ( );t++) {
    emit ( signalMoveOnStack ( m_listObjectCollection[t]->pObject, 1000 ) );
  }
  if (m_pContextMenu)
    delete m_pContextMenu;
  m_pContextMenu = NULL;
}

void ObjectCollection::slotToBack ()
{
  // Send it all the way to the back
  uint t;
  for (t=0;t<m_listObjectCollection.count ( );t++) {
    emit ( signalMoveOnStack ( m_listObjectCollection[t]->pObject, -1000 ) );
  }
  if (m_pContextMenu)
    delete m_pContextMenu;
  m_pContextMenu = NULL;
}

bool ObjectCollection::mouseDoubleClickEvent (QMouseEvent *)
{
  return false;
}

bool ObjectCollection::readProjectFile  (QDomNode &)
{
  return false;
}

bool ObjectCollection::writeProjectFile (QDomElement &)
{
  return false;
}

bool ObjectCollection::createContextMenu (QPoint globalPos)
{
  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);
  
  if (m_pContextMenu)
    delete m_pContextMenu;
  m_pContextMenu = new QPopupMenu(m_pParent);
  m_pContextMenu->insertItem ( tr ("Modify ..."), this, SLOT(slotEdit      ( ) ) );
  m_pContextMenu->insertItem ( tr ("Delete")    , this, SLOT(slotDelete    ( ) ) );
  m_pContextMenu->insertSeparator();
  m_pContextMenu->insertItem ( tr ("Add Shadow"), this, SLOT(slotAddShadow ( ) ) );
  m_pContextMenu->insertItem ( tr ("Add Frame") , this, SLOT(slotAddFrame  ( ) ) );
  m_pContextMenu->insertItem ( tr ("Add Text")  , this, SLOT(slotAddImage  ( ) ) );
  m_pContextMenu->insertItem ( tr ("Add Image") , this, SLOT(slotAddImage  ( ) ) );
  m_pContextMenu->insertItem ( tr ("Add Movie") , this, SLOT(slotAddImage  ( ) ) );
  m_pContextMenu->insertSeparator();
  m_pContextMenu->insertItem ( tr ("Define as Button") , this, SLOT(slotDefineAsButton()));
  m_pContextMenu->exec(globalPos2, 4);
  
  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;
}

StructureItem *ObjectCollection::createStructure ( StructureItem *pParentItem )
{
  // Creating teh ListView structure of this Button.
  QString qsCollection = tr("Collection of %1").arg(m_listObjectCollection.count ( ) );

  if ( pParentItem )  {
    if ( ! m_pStructureItem )  {
      m_pStructureItem = new StructureItem ( this, StructureItem::Unknown, pParentItem, name ( ), qsCollection );
      m_pStructureItem->setExpandable (TRUE);
    }
    else
      m_pStructureItem->setText ( name ( ), qsCollection );
  }
  else
    m_pStructureItem = NULL;

  uint t;
  for ( t=0; t<m_listObjectCollection.count ( ); t++ )
    m_listObjectCollection[t]->pObject->createStructure ( m_pStructureItem );

  return m_pStructureItem;
}

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

void ObjectCollection::slotDelete()
{
	emit (signalDeleteMe(this));
}

void ObjectCollection::slotAddFrame()
{
}

void ObjectCollection::slotAddText()
{

}

void ObjectCollection::slotAddImage()
{

}

void ObjectCollection::slotAddMovie()
{

}

void ObjectCollection::slotDefineAsButton()
{
	emit (signalDefineAsButton(this));
}

bool ObjectCollection::readObjects (QDomNode &theNode, MenuPreview *pPreview)
{
	QDomElement collectionElement;
	QDomNode collectionNode = theNode.firstChild();
	QDomNode childNode;
	MenuObject *pNewObject;
	childNode = collectionNode.firstChild();
	while (!childNode.isNull())	{
		pNewObject = NULL;
		collectionElement   = collectionNode.toElement();
		QString tagName = collectionElement.tagName();
		// 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 == FRAME_OBJECT)
			pNewObject = pPreview->createFrameObject (false);
		else if (tagName == TEXT_OBJECT)
			pNewObject = pPreview->createTextObject (false);
		else if (tagName == IMAGE_OBJECT)
			pNewObject = pPreview->createImageObject (false);
		else if (tagName == MOVIE_OBJECT)
			pNewObject = pPreview->createMovieObject (false);
		else if (tagName == BUTTON_OBJECT)	{
			pNewObject = pPreview->createButtonObject (false);
			// A small special handling for the Buttons ...
			// Funky, since the above function itself calls this function here ...
			((ButtonObject *)pNewObject)->readObjects(childNode, pPreview);
		}
		else if (tagName == OBJECT_COLLECTION)	{
			pNewObject = pPreview->createObjectCollection (false);
			// A small special handling for the Buttons ...
			// Funky, since the above function itself calls this function here ...
			((ObjectCollection *)pNewObject)->readObjects(childNode, pPreview);
		}
		else
			printf ("Warning: MenuPreview::readObject -=> wrong XML Node <%s>\nContinuing ...\n",
					(const char *)tagName);

		append (pNewObject);
		childNode = childNode.nextSibling ();
	}
	return true;
}

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

