/****************************************************************************
** listboxcolortext.h file.
**
** This file re-implements the QListBoxText class
** and adds only a background color to it.
**
** For later this could be enhanced to include a small Icon at the beginning
** Which indicates the type (I.e. single movie, movie collection, or dvd-slideshow).
**
** Another icon on the right side could indicate if a movie is already
** connected to a button or action.
**
** And yet another Icon could indicate the (intended) Format of the Movie.
**
*****************************************************************************/
#include <qfileinfo.h>
#include <qlistview.h>
#include <qpainter.h>
#include <qpixmap.h>
#include <qimage.h>

#include "global.h"
#include "messagebox.h"
#include "sourcefileentry.h"
#include "listviewitemmedia.h"

ListViewItemMedia::ListViewItemMedia (QListView *pListView, SourceFileEntry *pEntry, const QColor &theColor)
	: QListViewItem (pListView, QString (), pEntry->qsDisplayName)
{
	initMe (pEntry, theColor);
}

ListViewItemMedia::ListViewItemMedia (QListViewItem *pListViewItem, SourceFileEntry *pEntry, const QColor &theColor)
	: QListViewItem (pListViewItem, QString (), pEntry->qsDisplayName)
{
	initMe (pEntry, theColor);
}

ListViewItemMedia::ListViewItemMedia (QListView *pListView, QListViewItem *pAfterItem, SourceFileEntry *pEntry, const QColor &theColor)
	: QListViewItem (pListView, pAfterItem, QString (), pEntry->qsDisplayName)
{
	initMe (pEntry, theColor);
}

ListViewItemMedia::ListViewItemMedia (QListViewItem *pListViewItem, SourceFileInfo *pInfo, const QColor &color, QString t1, QString t2, QString t3)
	: QListViewItem (pListViewItem, t1, t2, t3)
{
	m_iButtonState     = StateStop;
	m_backgroundColor  = color;
	m_pSourceFileEntry = NULL;
	m_pSourceFileInfo  = pInfo;
}

ListViewItemMedia::~ListViewItemMedia ()
{
}

void ListViewItemMedia::initMe (SourceFileEntry *pEntry, const QColor &theBaseColor)
{
  // Here we create the sub items according to the SourceFileEntry -> listFileInfos
  int t;
  QColor              theColor;
  QFileInfo           fileInfo;
  SourceFileInfo     *pInfo;
  m_backgroundColor  = theBaseColor;
  m_pSourceFileEntry = pEntry;
  m_pSourceFileInfo  = NULL;
  m_iButtonState     = StateStop;
  m_iPreviousButtonState = 1000;
  
  sortChildItems (-1, false);
  setOpen (true);
  setDragEnabled (true);
  setDropEnabled (true);
  for(t=pEntry->listFileInfos.count()-1;t>=0;t--)	{
    pInfo = pEntry->listFileInfos[t];
    if ( ! pInfo )
      continue;
    if ( pInfo->pTranscodeInterface )
      theColor = QColor ( COLOR_MOVIE_TRANSCODE );
    else
      theColor = theBaseColor;
    fileInfo.setFile ( pInfo->qsFileName );
    
    QString qsInfo (fileInfo.fileName () + QString ("\n") + pInfo->qsLength);
    ListViewItemMedia *pItem = new ListViewItemMedia (this, pInfo, theColor, QString(), qsInfo, QString());
    pItem->setOpen (true);
    pItem->setDragEnabled (true);
    pItem->setDropEnabled (true);
    if (pInfo->pPreview)	{
      QPixmap thePixmap;
      QImage scaledImage (pInfo->pPreview->smoothScale (pEntry->sizeThumbnail, QImage::ScaleMin));
      if (pEntry->bSoundSource)	// No buttons for a sound - SourceFileEntry ...
	thePixmap = QPixmap (scaledImage);
      else
	thePixmap = pItem->attachButtons (scaledImage, pEntry->sizeThumbnail);
      pItem->setPixmap (0, thePixmap);
    }
    pItem->setDragEnabled (true);
  }
}

void ListViewItemMedia::updateItem ()
{
  SourceFileInfo *pInfo = sourceFileInfo ();
  if ( ! pInfo )
    return;

  m_backgroundColor   = QColor (COLOR_MOVIE_FILES_OK);
  if ( pInfo->pTranscodeInterface )
    m_backgroundColor = QColor (COLOR_MOVIE_TRANSCODE);
  else if (pInfo->qsStatus != QString ("Ok"))
    m_backgroundColor = QColor (COLOR_MOVIE_FILES_BAD);
}

void ListViewItemMedia::replaceInfo (SourceFileInfo *pInfo)
{
  SourceFileEntry *pEntry = NULL;
  if (sourceFileInfo() == pInfo)	{
    pEntry = ((ListViewItemMedia *)parent())->sourceFileEntry();
    if (!pEntry)
      return;
    
    QImage scaledImage ( pInfo->pPreview->smoothScale (pEntry->sizeThumbnail, QImage::ScaleMin ) );
    QFileInfo fileInfo ( pInfo->qsFileName );
    QString   qsInfo   ( fileInfo.fileName () + QString ("\n") + pInfo->qsLength );
    setText (1, qsInfo);
    m_backgroundColor   = QColor (COLOR_MOVIE_FILES_OK);
    if ( pInfo->pTranscodeInterface )
      m_backgroundColor = QColor (COLOR_MOVIE_TRANSCODE);
    else if (pInfo->qsStatus != QString ("Ok"))
      m_backgroundColor = QColor (COLOR_MOVIE_FILES_BAD);
    
    // attach the buttons and force a repaint of the buttons ...
    m_iPreviousButtonState = StateUndef;
    QPixmap thePixmap = attachButtons (scaledImage, pEntry->sizeThumbnail);
  }
  else if (sourceFileEntry ())	{
    pEntry = sourceFileEntry();
    ListViewItemMedia *pChild = (ListViewItemMedia *)firstChild ();
    while (pChild)	{
      pChild->replaceInfo (pInfo);
      pChild = (ListViewItemMedia *)pChild->nextSibling ();
    }
    // Here we check for the color of the header ... only if all status's are Ok do we give
    // the Ok color to the header too .
    m_backgroundColor     = QColor (COLOR_MOVIE_FILES_OK);
    for (uint t=0; t<pEntry->listFileInfos.count ();t++)	{
      if (pEntry->listFileInfos[t]->qsStatus != QString ("Ok"))	{
	m_backgroundColor = QColor (COLOR_MOVIE_FILES_BAD);
	break;
      }
    }
  }
}

QPixmap &ListViewItemMedia::attachButtons (QImage &theImage, QSize sizeThumbnail)
{
	static QPixmap thePixmap;
	// This function will attach the buttons to the left side of the image.
	// Play / Stop / Back
	int iThirdHeight = (int)((float)sizeThumbnail.height() / 3.0);
	int iOffset = iThirdHeight;
	int iDeltaY = (int)((sizeThumbnail.height()-theImage.height()) / 2.0);
	if ( (iDeltaY < 1) || (iDeltaY > sizeThumbnail.height()) )
		iDeltaY = 0;
	// Here we create the final imageExtension (empty QImage)
	QImage finalImage (sizeThumbnail.width() + iOffset, sizeThumbnail.height(), theImage.depth());
	finalImage.fill (0); // fill all black 
	// Next we fill in the image
	bitBlt ( &finalImage, iOffset, iDeltaY, (const QImage *)&theImage, 0, 0, theImage.width(), theImage.height(), Qt::CopyROP);

	thePixmap.convertFromImage(finalImage);
	// And then we draw the Buttons ...
	drawButtonState(&thePixmap);
	return thePixmap;
}

void ListViewItemMedia::drawButtonState (QPixmap *pPixmap)
{
	// For speed purposes: If nothing has changed, the state remains the same,
	// then the pixmap does not need to get re-drawn ...
	if (m_iPreviousButtonState == m_iButtonState)
		return;
	// This function will draw the buttons over the passed Pixmap
	uint t;
	bool bSelected;
	QPixmap theButton;
	QImage theImage;
	char *arrayNormalButtonState [] = {"button_play.png",  "button_stop.png",  "button_back.png"};
	char *arrayPressedButtonState[] = {"button_cplay.png", "button_cstop.png", "button_cback.png"};
	int iThirdHeight = (int)((float)pPixmap->height() / 3.0);
	int iOffset = iThirdHeight;

	for (t=0;t<3;t++)	{
		bSelected = false;
		if ((t == 0) && (m_iButtonState == StatePlay) )
			bSelected = true;
		else if ((t == 1) && (m_iButtonState == StateStop) )
			bSelected = true;
		else if ((t == 2) && (m_iButtonState == StateBack) )
			bSelected = true;

		if (bSelected)
			theImage = QImage().fromMimeSource(arrayPressedButtonState[t]).smoothScale (iOffset, iThirdHeight);
		else
			theImage = QImage().fromMimeSource(arrayNormalButtonState[t]).smoothScale(iOffset, iThirdHeight);
		theButton = theImage;
		bitBlt (pPixmap, 0, t*iThirdHeight, &theButton, 0, 0, theButton.width(), theButton.height(),  Qt::CopyROP);
	}
	setPixmap (0, *pPixmap);
	m_iPreviousButtonState = m_iButtonState;
}

void ListViewItemMedia::paintCell (QPainter *pPainter, const QColorGroup &cg, int iColumn, int iWidth, int iAlign)
{
	// FIXME:
	// Still some improvements to have the full width colored in  the m_backgroundColor
	QColorGroup theColors = cg;
	if (isSelected())	{
		theColors.setColor(QColorGroup::Base, theColors.highlight() );
		theColors.setColor(QColorGroup::Text, theColors.highlightedText() );
	}
	else
		theColors.setColor(QColorGroup::Base, m_backgroundColor);

	QListViewItem::paintCell (pPainter, theColors, iColumn, iWidth, iAlign);
//	pPainter->drawLine (0, 0, iWidth, 0);
	pPainter->drawLine (0, height()-1, iWidth, height()-1);
	// After we have drawn the full cell, we are going to draw the button states
	// If we have a SourceFileInfo - object

	if ( (iColumn == 0) && (sourceFileEntry() == NULL) )	{
		// Need to check if we have a SoundEntry.
		SourceFileEntry *pSourceFileEntry = ((ListViewItemMedia *)parent())->sourceFileEntry();
		if (pSourceFileEntry->bSoundSource)
			return;
		drawButtonState ((QPixmap *)pixmap(0));
	}
}

QColor ListViewItemMedia::backgroundColor ()
{
	return m_backgroundColor;

}

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

SourceFileInfo *ListViewItemMedia::sourceFileInfo ()
{
	return m_pSourceFileInfo;
}

void ListViewItemMedia::itemClicked(QPoint &thePoint)
{
	// Okay if the header is clicked, we simply return ...
	if (!sourceFileInfo ())
		return;
	SourceFileEntry *pSourceFileEntry = sourceFileEntry();
	if (!pSourceFileEntry)
		pSourceFileEntry = ((ListViewItemMedia *)parent())->sourceFileEntry();
	if (pSourceFileEntry->bSoundSource)
		return;
	// this function is called when the user clicks in the ListView.
	// Here we check if it hit one of the buttons ...
	QPoint p = listView()->mapFromGlobal (thePoint);
	QRect rect = listView()->itemRect (this);
	int iStartWidth  = listView()->treeStepSize() * 2;
	int iThirdHeight = (int)((float)height() / 3.0);
	// Play /Stop / Back is th order
	if ( (p.x() > iStartWidth) && (p.x() < iStartWidth + iThirdHeight)  && (p.y() < rect.y() + rect.height()) )	{
		if (p.y() > rect.y())
			m_iButtonState = StatePlay;
		if (p.y() > rect.y() + iThirdHeight)
			m_iButtonState = StateStop;
		if (p.y() > rect.y() + iThirdHeight * 2.0)
			m_iButtonState = StateBack;
	}
	// Next is to see what the user wants to do.
	if (m_iButtonState != m_iPreviousButtonState)	{
		QFileInfo fileInfo (sourceFileInfo()->qsFileName);
		QString qsState ("Play");
		if (m_iButtonState == StateStop)
			qsState = QString ("Stop");
		else if (m_iButtonState == StateBack)
			qsState = QString ("Back");
		QString qsMessage;
		qsMessage = QString("%1 %2 not yet implemented.").arg(qsState).arg(fileInfo.fileName());
		MessageBox::warning (NULL, "Not implemented", qsMessage, QMessageBox::Ok, QMessageBox::NoButton);
//		ListViewMedia *pListView = (ListViewMedia *)listView();
	}
	drawButtonState ((QPixmap *)pixmap(0));
	listView()->triggerUpdate();
}

/*
// Here is how multithreading support works.
	- Create QThread derived class
	- Implement run()
	- Generate screenshot of MediaStream in pListFileInfo->pPreview
	- When update is available then call QTimerEvent of FRAME_AVAILABLE to get back to the main thread.
	- in QTimer event handler, update the GUI pixmap.
	- When no more frames avail, then send QTimerEvent of END_OF_MEDIA
	- When user clicks on "Stop" kill QThread class after a Timeout of 30 sec. 
	-> set m_bDestroyMe = true;
	-> In Thread, before updating pSourceFileInfo->pPixmap , check for m_bDestroyMe
		-> if found emit QTimerEvent of DESTRTOY_ME
		-> exit run()

What is needed 
o	pListViewEntry		- to update Preview
o	ListViewItemMedia	- to update Pixmap of ListViewItem
o	SourceToolBar		- to get MediaEngine
o	QThreadClass communicates with QListViewMedia class where the QTimer events are handled.
o	Also needed is a structure to allow for multiple playing of source files at the same time
o	After clicking on [Back], have the Back state for 2 sec before switching to STOP state and starting the destruction of the MediaEngine

QThreadClass holds pointer to pSourceFileInfo->pPreview
MediaEngine pointer of its own MediaEngine.

TimerEvents : 
-	DESTROY_ME
-	STOP (same as DESTROY_ME)
-	END_OF_MEDIA
-	FRAME_AVAILABLE
-	BACK
*/

