/****************************************************************************
** Form implementation generated from reading ui file 'dialogundostack.ui'
**
** Created: Tue Dec 21 09:13:25 2004
**      by: The User Interface Compiler ($Id: dialogundostack.cpp,v 1.66 2006/01/13 05:04:19 qdvdauthor Exp $)
**
** WARNING! All changes made in this file will be lost!
****************************************************************************/

#include <qvariant.h>
#include <qpushbutton.h>
#include <qheader.h>
#include <qlistview.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qwhatsthis.h>
#include <qimage.h>
#include <qpixmap.h>

#include "messagebox.h"
#include "dialogundostack.h"
#include "dvdmenuundoobject.h"
#include "menuobject.h"

DialogUndoStack::DialogUndoStack( UndoBuffer *pUndoBuffer, DVDMenu *pDVDMenu, QWidget* parent, const char* name, bool, WFlags fl)
    : QDialog( parent, name, FALSE, fl )
{
	m_pUndoBuffer = pUndoBuffer;
	m_pDVDMenu    = pDVDMenu;
	m_pBaseItem   = NULL;
    if ( !name )
		setName( "DialogUndoStack" );
    setSizeGripEnabled( TRUE );
    DialogUndoStackLayout = new QGridLayout( this, 1, 1, 11, 6, "DialogUndoStackLayout"); 

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

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

    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 );

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

	m_pListViewUndo = new QListView( this, "m_pListViewUndo" );
	m_pListViewUndo->setSorting( -1);
	m_pListViewUndo->addColumn ( tr( "Object" ) );
	m_pListViewUndo->addColumn ( tr( "Nr" ) );
	m_pListViewUndo->addColumn ( tr( "Type" ) );

    DialogUndoStackLayout->addWidget( m_pListViewUndo, 0, 0 );
    languageChange();
    resize( QSize(200, 350).expandedTo(minimumSizeHint()) );
    clearWState ( Qt::WState_Polished );
//    clearWState ( Qt::WStyle_StaysOnTop );
    // signals and slots connections
	connect( m_pListViewUndo, SIGNAL( clicked ( QListViewItem *, const QPoint &, int )), this, SLOT (slotClickedOnList(QListViewItem *, const QPoint &, int)) );
    connect( buttonOk, SIGNAL( clicked() ), this, SLOT( accept() ) );
    connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) );
}

/*
 *  Destroys the object and frees any allocated resources
 */
DialogUndoStack::~DialogUndoStack()
{
    // no need to delete child widgets, Qt does it all for us
}

/*
 *  Sets the strings of the subwidgets using the current
 *  language.
 */
void DialogUndoStack::languageChange()
{
    setCaption( tr( "Undo Stack" ) );
    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 ) );
    m_pListViewUndo->clear();
}

void DialogUndoStack::buildUndoTree ()
{
	m_pListViewUndo->clear();
	if ( (m_pUndoBuffer->count() < 1) && (m_pUndoBuffer->countRedo() < 1) )
		return;
	int  t, iCounter, iMaxUndoSize, iMaxRedoSize;
	UndoObject *pUndoObject, *pNextUndoObject;

	// Here we ensure that only the specified depth is shown
	iMaxUndoSize = MAX_TREE_SIZE - m_pUndoBuffer->countRedo();
	if (iMaxUndoSize < 0)
		iMaxUndoSize = 0;
	else if (iMaxUndoSize > (int)m_pUndoBuffer->count())
		iMaxUndoSize = m_pUndoBuffer->count();

	// Since the ListView adds reverted, we have to start with the redo - steps.
	if (iMaxUndoSize == 0)
		iMaxRedoSize = MAX_TREE_SIZE;
	else
		iMaxRedoSize = m_pUndoBuffer->countRedo();

	iCounter = -iMaxRedoSize;
	m_pBaseItem = NULL;
	for (t=0;(int)t<iMaxRedoSize;t++)	{
		pNextUndoObject = NULL;
		pUndoObject = m_pUndoBuffer->atRedo(t);
		if (t < iMaxRedoSize - 1)
			pNextUndoObject = m_pUndoBuffer->atRedo(t+1);
		appendUndoStep (pUndoObject, pNextUndoObject, iCounter++);
	}

	new QListViewItem( m_pListViewUndo, tr("Current"), "0", tr("Status") );

	iCounter = 1;
	m_pBaseItem = NULL;
	for (t=iMaxUndoSize-1; t>=0; t--)	{
		pNextUndoObject = NULL;
		pUndoObject = m_pUndoBuffer->at(t);
		if (t > 0)
			pNextUndoObject = m_pUndoBuffer->at(t-1);
		appendUndoStep (pUndoObject, pNextUndoObject, iCounter++);
	}
}

void DialogUndoStack::appendUndoStep (UndoObject *pUndoObject, UndoObject *pNextUndoObject, int iCounter)
{
	QString qsUndoType, qsName;
	MenuObject *pMenuObject, *pNextMenuObject;
	
	pMenuObject     = NULL;
	pNextMenuObject = NULL;
	qsName          = QString ();
	qsUndoType      = tr("Undefined");
	if (pUndoObject)	{	// Here we check if have gotten MenuObject
		qsUndoType = pUndoObject->getTypeString ();
		pMenuObject = ((DVDMenuUndoObject *)pUndoObject)->getMenuObject();
		if (pMenuObject)	// All's fine, lets set the name ...
			qsName = pMenuObject->name();
	}

	// Next step is to look forward to be able to determine if we should group things together ...
	if (pNextUndoObject)
		pNextMenuObject = ((DVDMenuUndoObject *)pNextUndoObject)->getMenuObject();

	// The next step is to figure out if the current MenuObject is the same as the previous
	// in which case we want to group them together
	
	// First let us see if we have the BaseItem set, meaning we previously found curr and prev belong together
	if (m_pBaseItem)
		new QListViewItem( m_pBaseItem, QString (), QString ("%1").arg(iCounter), qsUndoType );
	else if (pMenuObject == pNextMenuObject)	{
		// Otherwise, if no masterItem set and the ext is the same as this, let us create one masterItem
		if (!m_pBaseItem)	{
			 m_pBaseItem = new QListViewItem( m_pListViewUndo, qsName, QString (), QString () );
			 m_pBaseItem->setOpen (true);
		}
		new QListViewItem( m_pBaseItem, QString (), QString ("%1").arg(iCounter), qsUndoType );
	}
	// In case the next item is different we still want to attach the current item to the MasterItem
	if (pMenuObject != pNextMenuObject)	{
		if (!m_pBaseItem)	// This one is only generated if we not already added it in the first if - case
			new QListViewItem( m_pListViewUndo, qsName, QString ("%1").arg(iCounter), qsUndoType );
		m_pBaseItem = NULL;
	}
}

void DialogUndoStack::slotClickedOnList(QListViewItem *, const QPoint &, int)
{
	MessageBox::warning(NULL, QString ("Warning"), QString ("No functionality implemented yet."), QMessageBox::Ok, QMessageBox::NoButton);
}
