/****************************************************************************
** DialogChapters class
**
** Created: Fri Jun 18 22:48:00 2004
**      by: Varol Okan using Kate
**
****************************************************************************/

#include <qpushbutton.h>
#include <qmessagebox.h>
#include <qfileinfo.h>
#include <qlineedit.h>
#include <qlistbox.h>
#include <qlayout.h>
#include <qlabel.h>
#include <qimage.h>

#include "dialogchapters.h"
#include "mediacreator.h"
#include "startstopcontrol.h"
#include "../mediainfo.h"
#include "../utils.h"

DialogChapters::DialogChapters(QWidget * parent, const char * name, WFlags f)
	: uiDialogChapters (parent, name, f)
{
	m_iMovieLength = 0;
}

DialogChapters::~DialogChapters ()
{
	delete m_pMediaInterface;
	delete m_pStartStopControl;
}

void DialogChapters::initMe(SourceFileInfo *pInfo, const void *pExistingMediaEngine, int iThumbnailSize)
{
	if (!pInfo)
		return;
	Utils theUtil;
	int iLength = theUtil.getMsFromString(pInfo->qsLength);
	// Check if the default 5 minutes chapter creation is out of range anyways ...
	QString qsReturn = theUtil.getStringFromMs (iLength);
	if (iLength < 5*60*1000)	{
		m_pEditEvery->setText (QString ("%1").arg((int)(iLength/1000)));
		m_pEditAdd->setText (qsReturn);
	}
	m_pEditEnding->setText(qsReturn);
	// Here we copy the infos over ...
	m_sourceFileInfo = *pInfo;
	QFileInfo fileInfo(m_sourceFileInfo.qsFileName);

	// and now on to initializing the dialog. Length : 00:07:23.123 File : Cool Video.mpg
	m_pTextTitle->setText (tr ("Length : <%1> File : %2").arg(qsReturn).arg(fileInfo.fileName()));

	m_pListBoxChapters->clear ();
	if (m_sourceFileInfo.listChapters.count() == 0)
		m_pListBoxChapters->insertItem (QString ("00:00:00.000"));
	m_pListBoxChapters->insertStringList (m_sourceFileInfo.listChapters);
	m_pListBoxChapters->setCurrentItem (0);
	m_pListBoxChapters->setSelected (0, true);
	
	m_pMediaInterface = MediaCreator::createPreferredWidget (m_pMediaPreview, "ChapterXineWidget", (void *)pExistingMediaEngine);

	connect (m_pMediaInterface, SIGNAL(signalNewPosition(int, const QString&)), this, SLOT(slotNewPosition(int, const QString&)));
	QGridLayout *pVideoLayout = new QGridLayout (m_pMediaPreview, 1, 1, 2, 2, "MediaMainLayout");
	pVideoLayout->addWidget (m_pMediaInterface->getWidget(), 0, 0);
	// This is take care of in the polish () function for Xine and not necessary for MPlayer ...
	m_pMediaInterface->initMediaEngine();

	m_pMediaInterface->openMRL (m_sourceFileInfo.qsFileName);
//	m_pMediaInterface->getScreenshot  ();

	// This is the new version, where I have a new WidgetControl.
	QGridLayout *pLayout = new QGridLayout( m_pFrameControl, 1, 1, 2, 2, "pLayout");
	m_pStartStopControl = new StartStopControl ( m_pFrameControl );
	m_pStartStopControl->initMe (m_sourceFileInfo.qsFileName, iThumbnailSize, iLength);
	m_pStartStopControl->showSlider (false);
	m_iMovieLength = iLength;
	pLayout->addWidget( m_pStartStopControl, 0, 0 );
	// And finally here are the callback functions ...
	connect (m_pButtonAdd,       SIGNAL(clicked ()), this, SLOT (slotAddChapter()));
	connect (m_pButtonDel,       SIGNAL(clicked ()), this, SLOT (slotDelChapters()));
	connect (m_pButtonAuto,      SIGNAL(clicked ()), this, SLOT (slotAutoChapters()));
	connect (m_pButtonPreview,   SIGNAL(clicked ()), this, SLOT (slotPreview()));
	connect (m_pListBoxChapters, SIGNAL(currentChanged (QListBoxItem *)), this, SLOT (slotCurrentChanged(QListBoxItem *)));
}

void DialogChapters::initMe(SourceFileEntry *pSourceFileEntry, const void *pExistingMediaEngine, int iThumbnailSize)
{
	// For now we cheat ... Later more
	SourceFileInfo *pInfo = pSourceFileEntry->listFileInfos[0];
	m_sourceFileEntry = *pSourceFileEntry;
	initMe (pInfo, pExistingMediaEngine, iThumbnailSize);
}

SourceFileInfo *DialogChapters::getSourceFileInfo ()
{
	return &m_sourceFileInfo;
}

SourceFileEntry *DialogChapters::getSourceFileEntry ()
{
	return &m_sourceFileEntry;
}

void DialogChapters::slotAutoChapters ()
{
	uint t, i, iDeltaStep, iStarting, iEnding, iChapter, iPreviousChapter;
	int iTotalLength, iNumberOfNewChapters;
	QString qsTimeString;
	Utils theUtil;
	// Here we read in the list of currently generated chapters
	// then we convert them into milliseconds, and store them in an array
	// And finally we generate the chapters, sort the array and put it back into the
	// m_pListBoxChapters, and m_sourceFileInfo - structures.
	uint *pArrayExistingChapters = new uint[m_pListBoxChapters->count()];
	for (t=0;t<m_pListBoxChapters->count(); t++)	{
		qsTimeString = m_pListBoxChapters->text(t);
		pArrayExistingChapters[t] = theUtil.getMsFromString (qsTimeString);
	}
	iStarting  = theUtil.getMsFromString (m_pEditStarting->text());
	iEnding    = theUtil.getMsFromString (m_pEditEnding->text());
	iDeltaStep = theUtil.getMsFromString (m_pEditEvery->text());
	iTotalLength = (int)(iEnding - iStarting);
	// a DeltaStep of 0 woudl generate infinite number of chapters
	if (iDeltaStep < 1)
		return;
	if (iDeltaStep > (uint) iTotalLength)
		iDeltaStep = iTotalLength;
	iNumberOfNewChapters = (int)((float)iTotalLength / (float)iDeltaStep) + 1;

	QValueList<int> listAllChapters;
	// Okay this is the worst sort algo around but we would'nt sort thousands of chapters, now would we ???
	i = 0;
	for (t=0;t<(uint)iNumberOfNewChapters;t++)	{
		iChapter = t*iDeltaStep;
		for (i=0;i<m_pListBoxChapters->count();i++)	{
			// If we find an entry which is the same as a calculated chapter we should skip it ...
			if (pArrayExistingChapters[i] == iChapter)
				pArrayExistingChapters[i] = 0;
			// If we find an entry which is smaller but not 0, then we should include them ...
			else if ( (pArrayExistingChapters[i] < iChapter) && (pArrayExistingChapters[i] > 0) )	{
				listAllChapters.append (pArrayExistingChapters[i]);
				// Here we ensure the next time this entry is higher
				pArrayExistingChapters[i] = 0;
			}
		}
		listAllChapters.append (iChapter);
	}

	m_pListBoxChapters->clear ();
	iChapter = iPreviousChapter = 0;
	for (t=0;t<listAllChapters.count();t++)	{
		iChapter = listAllChapters[t];
		if (iChapter >= iPreviousChapter)
			m_pListBoxChapters->insertItem(theUtil.getStringFromMs (iChapter));
		iPreviousChapter = iChapter;
	}

	delete []pArrayExistingChapters;
}

void DialogChapters::slotAddChapter ()
{
	// Here we add a chapter in the right space,
	// but only if this chapter does not already exists ...
	int iChapter, iAddChapter;
	uint t;
	iChapter = 0;
	Utils theUtil;
	iAddChapter = theUtil.getMsFromString (m_pEditAdd->text());
	for (t=0;t<m_pListBoxChapters->count();t++)	{
		iChapter = theUtil.getMsFromString (m_pListBoxChapters->text(t));
		if (iAddChapter == iChapter)
			break;
		else if (iAddChapter < iChapter)	{
			m_pListBoxChapters->insertItem (theUtil.getStringFromMs (iAddChapter), t);
			break;
		}
	}
	// and in case the Chpater is to be added at the end ...
	if (iAddChapter > iChapter)
		m_pListBoxChapters->insertItem (theUtil.getStringFromMs (iAddChapter));
}

void DialogChapters::slotDelChapters ()
{
	// This function will remove all chapters which are currently selected in m_pListBoxChapters
	uint t;
	QValueList<QListBoxItem *> listItems;
	for (t=0;t<m_pListBoxChapters->count();t++)	{
		if (m_pListBoxChapters->isSelected (t))
			listItems.append (m_pListBoxChapters->item(t));
	}
	for (t=0;t<listItems.count();t++)
			delete listItems[t];
}

void DialogChapters::slotCurrentChanged (QListBoxItem *pItem)
{
	uint t, iCount;
	iCount = 0;
	// we first count the number of selected chapters
	for (t=0;t<m_pListBoxChapters->count();t++)	{
		if (m_pListBoxChapters->isSelected (t))
			iCount ++;
	}
	if ( (iCount > 1) || (iCount == 0) )
		m_pButtonPreview->setEnabled (false);
	else
		m_pButtonPreview->setEnabled (true);
	if (iCount != 1)
		return;
	// Last we jump to the position
	if (m_pListBoxChapters->isSelected (pItem))	{
		int iChapter = 0;
		QTime chapterTime, zeroTime;
		QString qsChapter = m_pListBoxChapters->currentText ();
	
		chapterTime = QTime::fromString (qsChapter);
		iChapter = zeroTime.secsTo (chapterTime);
		m_pMediaInterface->setPositionByTime (iChapter);

//		if (!m_pMediaInterface->isPaused   ())
//			m_pMediaInterface->pause   ();
	}
}

void DialogChapters::slotPreview ()
{
	if (m_pButtonPreview->text() == tr ("Preview"))
		preview ();
	else if (m_pButtonPreview->text() == tr ("Play"))
		play ();
	else if (m_pButtonPreview->text() == tr ("Pause"))
		pause ();
}

void DialogChapters::preview ()
{
	// Here we will preview the chapter but only if
	// a)	there is only one chapter selected and
	// b)	the stream is seekable
	uint t, iCount;
	iCount = 0;
	for (t=0;t<m_pListBoxChapters->count();t++)	{
		if (m_pListBoxChapters->isSelected (t))
			iCount ++;
	}
	if (iCount == 0)	{
		QMessageBox::information (this, tr("Error."), tr ("Please select at one chapter to preview."), QMessageBox::Ok);
		return;
	}
	else if (iCount > 1)	{
		QMessageBox::information (this, tr("Error."), tr ("Please select only one chapter to preview."), QMessageBox::Ok);
		return;
	}

	int iChapter = 0;
	QTime chapterTime, zeroTime;
	QString qsChapter = m_pListBoxChapters->currentText ();
	
	chapterTime = chapterTime.fromString (qsChapter);
	iChapter = zeroTime.secsTo (chapterTime);
	m_pMediaInterface->setPositionByTime (iChapter);
	m_pButtonPreview->setText (tr("Play"));
}

void DialogChapters::play ()
{
	if (m_pMediaInterface)	{
		if      (m_pMediaInterface->isPaused ())
			 m_pMediaInterface->play ();
		else if (m_pMediaInterface->isPlaying())
			 m_pMediaInterface->pause();
		else
			m_pMediaInterface->playMRL(m_sourceFileInfo.qsFileName);
	}
	m_pButtonPreview->setText (tr("Pause"));
}

void DialogChapters::pause ()
{
	play ();
	m_pButtonPreview->setText (tr("Preview"));
}

void DialogChapters::accept ()
{
	// Here we set the chapters to the SourceFileInfo ...
	uint t;
	m_sourceFileInfo.listChapters.clear ();

	for (t=0;t<m_pListBoxChapters->count ();t++)
		m_sourceFileInfo.listChapters.append(m_pListBoxChapters->text (t));
	QDialog::accept();
}

void DialogChapters::slotNewPosition(int, const QString &qsPosition)
{
	m_qsPosition = qsPosition;
	if (m_qsPosition.length() == 8)
		m_qsPosition += ".000";
	m_pEditAdd->setText (m_qsPosition);
	if (m_iMovieLength < 1)
		return;
	QTime posTime, zeroTime;
	posTime  = posTime.fromString (qsPosition);
	int iCurrentPosition = zeroTime.msecsTo (posTime);
	float fPosition = (float)iCurrentPosition / m_iMovieLength;

	m_pStartStopControl->setProgress ( fPosition );
}

