/****************************************************************************
** DialogThumbnail
**
**   Created : Thu Jan 18 22:48:00 2007
**        by : Varol Okan using XEmacs
** Copyright : (c) Varol Okan
**   License : GPL v 2.0
**
****************************************************************************/

#include <qlabel.h>
#include <qslider.h>
#include <qdialog.h>
#include <qlistbox.h>
#include <qgroupbox.h>
#include <qfileinfo.h>
#include <qiconview.h>
#include <qlineedit.h>
#include <qcombobox.h>
#include <qpushbutton.h>
#include <qprogressbar.h>

#include "global.h"
#include "utils.h"
#include "dvdmenu.h"
#include "dialogfont.h"
#include "qdvdauthor.h"
#include "dialogframe.h"
#include "sourcefileentry.h"
#include "dialogthumbnail.h"
#include "dragndropcontainer.h"
#include "qplayer/mediacreator.h"

DialogThumbnail::TextAttr  DialogThumbnail::m_textAttr  = TextAttr  ( );
DialogThumbnail::FrameAttr DialogThumbnail::m_frameAttr = FrameAttr ( );

DialogThumbnail::ThumbnailRequest::ThumbnailRequest ( DialogThumbnail *pDialog, QIconViewItem *pItem, QString qsFile, long iOffset )
  : ExecuteJob ( pDialog )
{
  pImage          = new QImage;
  pOwnerItem      = pItem;
  pParent         = pDialog;
  iMSecondsOffset = iOffset;
  qsFileName      = qsFile;
}

DialogThumbnail::ThumbnailRequest::~ThumbnailRequest ( )
{
  if ( pImage )
    delete pImage;
}

bool DialogThumbnail::ThumbnailRequest::response ( )
{
  if ( ! pParent )
    return false;
  // Rather then copy data back and forth I simply steal the pointer to the QImage object
  QImage *pTempImage = pImage;
  pImage = NULL;
  pParent->initWork ( pOwnerItem, pTempImage, qsFileName );

  return true;
}

DialogThumbnail::WorkWaiting::WorkWaiting ( QIconViewItem *pViewItem, QImage *pImg, QString qsFile )
{
  pItem      = pViewItem;
  pImage     = pImg;
  qsFileName = qsFile;
}

DialogThumbnail::WorkWaiting::~WorkWaiting ( )
{
  if ( pImage )
    delete pImage; 
};


DialogThumbnail::DialogThumbnail ( QDVDAuthor *pDVDAuthor, const char *pName, WFlags f )
  : uiDialogThumbnail ( pDVDAuthor, pName, f )
{
  m_pSourceFileInfo  = NULL;
  m_pSourceFileEntry = NULL;
  m_iCurrentChapter  = 0;
  m_iThumbnailWidth  = 120;
  m_iThumbnailHeight = 120;
  m_iThumbnailStretchMode = 0;
  m_iSliderWidthStart     = 0;
  m_iSliderHeightStart    = 0;

  connect ( m_pButtonOk,        SIGNAL ( clicked ( ) ), this, SLOT ( hide        ( ) ) );
  connect ( m_pButtonFont,      SIGNAL ( clicked ( ) ), this, SLOT ( slotFont    ( ) ) );
  connect ( m_pButtonFrame,     SIGNAL ( clicked ( ) ), this, SLOT ( slotFrame   ( ) ) );
  connect ( m_pButtonRefresh,   SIGNAL ( clicked ( ) ), this, SLOT ( slotRefresh ( ) ) );
  connect ( m_pButtonReload,    SIGNAL ( clicked ( ) ), this, SLOT ( slotReload  ( ) ) );
  connect ( m_pSliderSize,      SIGNAL ( valueChanged ( int ) ), this, SLOT ( slotSizeChanged   ( int ) ) );
  connect ( m_pSliderSpace,     SIGNAL ( valueChanged ( int ) ), this, SLOT ( slotSpaceChanged  ( int ) ) );
  connect ( m_pComboTextType,   SIGNAL ( activated    ( int ) ), this, SLOT ( slotTextType      ( int ) ) );
  connect ( m_pSliderSize,      SIGNAL ( sliderPressed    ( ) ), this, SLOT ( slotSizePressed   ( ) ) );
  connect ( m_pSliderSize,      SIGNAL ( sliderReleased   ( ) ), this, SLOT ( slotSizeReleased  ( ) ) );
  connect ( m_pSliderSpace,     SIGNAL ( sliderReleased   ( ) ), this, SLOT ( slotSpaceReleased ( ) ) );
  connect ( m_pListBoxChapters, SIGNAL ( currentChanged   ( QListBoxItem * ) ), 
	    this, SLOT ( slotChapterChanged( QListBoxItem * ) ) );
}

DialogThumbnail::~DialogThumbnail ( )
{
  // remove any outstanding requests ...
  MediaCreator::unregisterFromMediaScanner ( this );
  if ( m_pSourceFileInfo )
    MediaCreator::unregisterFromMediaScanner ( m_pSourceFileInfo );
  if ( m_pSourceFileEntry )  {
    QValueList<SourceFileInfo *>::iterator it = m_pSourceFileEntry->listFileInfos.begin ( );
    SourceFileInfo *pInfo;
    while ( it != m_pSourceFileEntry->listFileInfos.end ( ) )  {
      pInfo = *it++;
      if ( ! pInfo )
        continue;
      MediaCreator::unregisterFromMediaScanner ( pInfo );
    }
  }
}

bool DialogThumbnail::haveSource ( )
{
  return ( m_pSourceFileInfo || m_pSourceFileEntry );
}

int DialogThumbnail::chapterCount ( )
{
  int i=0;
  if ( m_pSourceFileInfo )
   i = m_pSourceFileInfo->listChapters.count ( );
  if ( m_pSourceFileEntry )  {
    QValueList<SourceFileInfo *>::iterator it = m_pSourceFileEntry->listFileInfos.begin ( );
    SourceFileInfo *pInfo;
    while ( it != m_pSourceFileEntry->listFileInfos.end ( ) )  {
      pInfo = *it++;
      if ( ! pInfo )
        continue;
      if ( pInfo->listChapters.count  ( ) == 0 )
           pInfo->listChapters.append ( "00:00:00.000" );
      i += pInfo->listChapters.count  ( );
    }
  }

  return i;
}

QString DialogThumbnail::chapter ( int iChapterNumber )
{
  QString qsChapter ( "00:00:00.000" );
  if ( m_pSourceFileInfo )  {
    if ( (int)m_pSourceFileInfo->listChapters.count ( ) > iChapterNumber )
      qsChapter  =  m_pSourceFileInfo->listChapters     [ iChapterNumber ];
  }
  if ( m_pSourceFileEntry )  {
    int i=0;
    QValueList<SourceFileInfo *>::iterator it = m_pSourceFileEntry->listFileInfos.begin ( );
    SourceFileInfo *pInfo;
    while ( it != m_pSourceFileEntry->listFileInfos.end ( ) )  {
      pInfo = *it++;
      if ( ! pInfo )
        continue;
      if ( iChapterNumber < (int)( i + pInfo->listChapters.count ( ) ) )
           return pInfo->listChapters [ iChapterNumber - i ];
      i += pInfo->listChapters.count  ( );
    }
  }
  return qsChapter;
}

SourceFileInfo *DialogThumbnail::getInfoFromChapterNumber ( int iChapterNumber )
{
  if ( m_pSourceFileInfo )
    return m_pSourceFileInfo;
  if ( m_pSourceFileEntry )  {
    int i=0;
    QValueList<SourceFileInfo *>::iterator it = m_pSourceFileEntry->listFileInfos.begin ( );
    SourceFileInfo *pInfo;
    while ( it != m_pSourceFileEntry->listFileInfos.end ( ) )  {
      pInfo = *it++;
      if ( ! pInfo )
        continue;
      if ( iChapterNumber < (int)( i + pInfo->listChapters.count ( ) ) )
           return pInfo;
      i += pInfo->listChapters.count  ( );
    }
  }
  return NULL;
}

int DialogThumbnail::getChapterNumberFromKey ( QString qsKey )
{
  if ( ! m_pSourceFileEntry )
    return 0;

  // This is to assign the Chapter number to the QIconViewItem
  QString   qsActionString;
  QFileInfo fileInfo;
  int t, i=0;

  QValueList<SourceFileInfo *>::iterator it = m_pSourceFileEntry->listFileInfos.begin ( );
  SourceFileInfo *pInfo;
  while ( it != m_pSourceFileEntry->listFileInfos.end ( ) )  {
    pInfo = *it++;
    if ( ! pInfo )
      continue;
    fileInfo.setFile ( pInfo->qsFileName );

    for ( t=0; t<(int)pInfo->listChapters.count ( ); t++ )  {
      // This is a slow comparion but we deal only with a few chapters. Should not be in the thousands.
      qsActionString = QString ( "jump+-+%1+-+%2+-+%3" ).arg ( m_pSourceFileEntry->qsDisplayName ).arg ( fileInfo.fileName ( ) ).arg ( pInfo->listChapters[t] );
      if ( qsActionString == qsKey )
        return i;
      i++;
    }
  }
  return 0;
}

void DialogThumbnail::show ( )
{
  uiDialogThumbnail::show ( );
  if ( Global::pApp ) {
    DragNDropContainer *pDND = Global::pApp->getDragNDropContainer ( );
    DVDMenu *pDVDMenu = Global::pApp->getVMGMenu ( );
    m_pEditWidth ->setText ( QString ( "%1" ).arg ( pDND->sizeButton.width  ( ) ) );
    m_pEditHeight->setText ( QString ( "%1" ).arg ( pDND->sizeButton.height ( ) ) );
    m_textAttr.foregroundColor  = pDND->colorForeground.rgb ( ) & 0x00FFFFFF;
    m_textAttr.font             = pDND->font;
    if ( pDVDMenu )
      m_frameAttr.color         = pDVDMenu->getColor ( 1 ).rgb ( ); // def highlighted color
    //give the default DND font a more appropriate size ...
    if ( m_textAttr.font.pixelSize ( ) != -1 )
      m_textAttr.font.setPixelSize ( 14 );
    else 
      m_textAttr.font.setPointSize ( 14 );
  }
}

void DialogThumbnail::initSourceFileEntry ( SourceFileEntry *pEntry )
{
  m_pListBoxChapters   ->clear ( );
  m_pIconViewThumbnails->clear ( );

  if ( ! pEntry )
    return;

  setCaption ( QString ( "Thumbnail Dialog : " ) + pEntry->qsDisplayName );
  m_pSourceFileInfo  = NULL;
  m_pSourceFileEntry = pEntry;

  int t;
  QStringList listChapters;
  SourceFileInfo *pInfo = NULL;
  QFileInfo fileInfo;
  QString qsChapter;

  QValueList<SourceFileInfo *>::iterator it = pEntry->listFileInfos.begin ( );
  while ( it != pEntry->listFileInfos.end ( ) )  {
    pInfo = *it++;
    fileInfo.setFile ( pInfo->qsFileName );
    if ( pInfo->listChapters.count  ( ) == 0 )  // make sure at least one chapter is present ...
         pInfo->listChapters.append ( "00:00:00.000" );
    for ( t=0; t<(int)pInfo->listChapters.count ( ); t++ )  {
      qsChapter = pInfo->listChapters[t] + " : " + fileInfo.fileName ( );
      listChapters.append ( qsChapter );
    }
  }

  m_pListBoxChapters->insertStringList ( listChapters );
  m_pProgressBar->setTotalSteps ( pInfo->listChapters.count( ) - 1 );

  refreshEntry ( true );
}

void DialogThumbnail::initSourceFileInfo ( SourceFileInfo *pInfo, QString &qsAction )
{
  m_pListBoxChapters   ->clear ( );
  m_pIconViewThumbnails->clear ( );

  if ( ! pInfo )
    return;

  QFileInfo   fileInfo ( pInfo->qsFileName );
  setCaption ( QString ( "Thumbnail Dialog : " ) + fileInfo.fileName ( ) );
  m_pSourceFileInfo  = pInfo;
  m_pSourceFileEntry = NULL;
  m_qsActionString   = qsAction;
  m_pListBoxChapters->insertStringList ( pInfo->listChapters );
  m_pProgressBar->setTotalSteps ( pInfo->listChapters.count( ) - 1 );

  slotRefresh ( );
}

void DialogThumbnail::timerEvent ( QTimerEvent *pEvent )
{
  if ( haveSource ( ) )  {
    if ( pEvent->timerId ( ) == MEDIASCANNER_EVENT + 4 ) {
      int t;
      WorkWaiting *pWork;
      QValueList<WorkWaiting *> tempList;
      // to decrease threading issues, we quickly remove the used Work objects from the member list.
      for ( t=0;t<(int)m_listOfWorkToDo.count ( ); t++ ) {
        pWork = m_listOfWorkToDo [ t ];
        //m_listOfWorkToDo.remove ( pWork );
        tempList.append ( pWork );
      }
      m_listOfWorkToDo.clear ( );
      for ( t=0;t<(int)tempList.count ( ); t++ ) {
        pWork = tempList [ t ];
        updateItem ( pWork->pItem, pWork->pImage, pWork->qsFileName );
        delete pWork;
        m_pProgressBar->setProgress ( m_iProgress ++ );
      }
      if ( (int)m_iProgress >= m_pProgressBar->totalSteps ( )-2 )
        m_pIconViewThumbnails->arrangeItemsInGrid ( TRUE );
    }
  }
  uiDialogThumbnail::timerEvent ( pEvent );
}

void DialogThumbnail::initWork ( QIconViewItem *pItem, QImage *pImage, QString qsFile )
{
  WorkWaiting *pNewWork = new WorkWaiting ( pItem, pImage, qsFile );
  m_listOfWorkToDo.append ( pNewWork );
}

DialogThumbnail::TextAttr  *DialogThumbnail::textAttr  ( )
{
  return &m_textAttr;
}

DialogThumbnail::FrameAttr *DialogThumbnail::frameAttr ( )
{
  return &m_frameAttr;
}

QString DialogThumbnail::getChapter ( QIconViewItem *pItem )
{
  QString qsChapter;
  if ( pItem )  {
    QStringList list = QStringList::split ( STRING_SEPARATOR, pItem->key ( ) );
    if ( list.count ( ) > 0 )
      qsChapter = list[ list.size ( ) - 1 ];
    else
      qsChapter = "00:00:00.000";
  }
  return  qsChapter;
}

bool DialogThumbnail::updateItem ( QIconViewItem *pItem, QImage *pImage, QString qsFile )
{
  if ( ! pImage )
    return false;

  QString   qsFileName, qsChapter;
  Utils     theUtils;
//  QFileInfo fileInfo ( m_pSourceFileInfo->qsFileName );
  QFileInfo fileInfo ( qsFile );

  // At this point we should add the image to the IconView ...
  qsChapter  = getChapter         ( pItem );
  qsChapter  =  qsChapter.remove  ( ':' );
  qsChapter  =  qsChapter.replace ( '.', "_" );

  qsFileName  = theUtils.getTempPath ( fileInfo.baseName ( ) );
  qsFileName += QString ( "/thumb_%1.png" ).arg  ( qsChapter );
  pImage->save ( qsFileName, "PNG", 100 );

  if ( ! pItem )
    return false;

  QPixmap thePixmap;
  QImage::ScaleMode scaleMode = QImage::ScaleMin;
  if ( m_iThumbnailStretchMode ==  1 )
    scaleMode = QImage::ScaleMax;
  if ( m_iThumbnailStretchMode ==  2 )
    scaleMode = QImage::ScaleFree;  

  *pImage = pImage->smoothScale ( m_iThumbnailWidth, m_iThumbnailHeight, scaleMode );
  if ( thePixmap.convertFromImage ( *pImage ) )
    pItem->setPixmap ( thePixmap );

  return true;
}

bool DialogThumbnail::getBufferedThumbnail ( )
{
  QIconViewItem *pItem = NULL;

  while ( (int)m_iCurrentChapter < chapterCount ( ) ) {
    pItem = createCurrentItem ( false );
    if ( ! pItem )
      return true;

    m_pProgressBar->setProgress ( m_iProgress );
    m_iCurrentChapter ++;
  }
  return false;
}

void DialogThumbnail::slotFrame ( )
{
  DialogFrame frameDialog ( this );
  frameDialog.initMe      ( m_frameAttr.iStyle,
			    m_frameAttr.iWidth,
			    m_frameAttr.iJoin,
			    m_frameAttr.color );
  if (  frameDialog.exec  (  ) == QDialog::Rejected )
    return;

  m_frameAttr.iStyle = frameDialog.style         ( );
  m_frameAttr.iJoin  = frameDialog.join          ( );
  m_frameAttr.iWidth = frameDialog.frameWidth    ( );
  m_frameAttr.color  = frameDialog.color ( ).rgb ( );
}

void DialogThumbnail::slotFont ( )
{
  DialogFont fontDialog ( this );
  QString qsText ( "No Text" );
  if ( m_pComboTextType->currentItem ( ) == 0 )
    qsText = "00:00:00.000";
  else if ( m_pComboTextType->currentItem ( ) == 1 )
    qsText = "00:00:00";
  else if ( m_pComboTextType->currentItem ( ) == 2 )
    qsText = "Chapter 1";

  fontDialog.initMe     ( qsText );
  fontDialog.setTheFont ( m_textAttr.font );
  fontDialog.setBackgroundColor ( m_textAttr.backgroundColor );
  fontDialog.setForegroundColor ( m_textAttr.foregroundColor );
  if ( fontDialog.exec ( ) == QDialog::Rejected )
    return;

  m_textAttr.qsText = ""; // of no interest or the ThumbnailDialog.
  m_textAttr.font   = fontDialog.getFont ( );
  m_textAttr.backgroundColor = fontDialog.backgroundColor ( );
  m_textAttr.foregroundColor = fontDialog.foregroundColor ( );
}

void DialogThumbnail::slotTextType ( int iNewTextType )
{
  QIconViewItem *pItem = m_pIconViewThumbnails->firstItem ( );
  while ( pItem ) {
    setItemText ( pItem, iNewTextType );
    pItem = pItem->nextItem ( );
  }
}

void DialogThumbnail::setItemText ( QIconViewItem *pItem, int iTextType )
{
  // we support 4 different tet types
  // 0 == Timestamp          E.g. "00:00:00.000"
  // 1 == Timestamp seconds  E.g. "00:00:00"
  // 2 == Chapter No         E.g. "Chapter 2"
  // 3 == None               E.g. ""
  QString qsText;
  QString qsChapter = getChapter ( pItem );
  switch ( iTextType ) {
  case 0:
    qsText = qsChapter;
  break;
  case 1:
    qsText = qsChapter.left ( qsChapter.length ( ) - 4 );
  break;
  case 2: {
    if ( m_pSourceFileInfo )  {
      int t, iChapterCount = chapterCount ( );
      for  ( t=0;t<iChapterCount; t++ ) {
        if ( chapter  ( t ) == qsChapter ) {
          qsText = QString (  "Chapter %1" ).arg ( t + 1 );
          break;
        }
      }
    }
    if ( m_pSourceFileEntry )  {
      int  t = getChapterNumberFromKey ( pItem->key ( ) );
      qsText = QString (  "Chapter %1" ).arg  ( t + 1 );
    }
  }
  break;
  };

  pItem->setText ( qsText );
}

void DialogThumbnail::slotSpaceReleased ( )
{
  int iValue = m_pSliderSpace->value ( );
    m_iSliderWidthStart  = 0;
  m_iSliderHeightStart = 0;
  m_pIconViewThumbnails->setSpacing  ( iValue );
  QSize oldSize = m_pIconViewThumbnails->size ( );
  m_pIconViewThumbnails->resize ( oldSize.width( ), oldSize.height ( )+1 );
  m_pIconViewThumbnails->resize ( oldSize.width( ), oldSize.height ( ) );  
}

void DialogThumbnail::slotSpaceChanged ( int iNewValue )
{
  m_pLabelSpace->setText ( QString ( "<p align=\"center\"><b>%1</b></p>" ).arg ( iNewValue ) );
}

void DialogThumbnail::slotSizeReleased ( )
{
  refresh ( false );
  m_iSliderWidthStart  = 0;
  m_iSliderHeightStart = 0;
  m_pSliderSize->setValue ( 0 );
}

void DialogThumbnail::slotSizePressed ( )
{
  // we need to keep the start values of Width / Height ...
  m_iSliderWidthStart  = m_pEditWidth-> text ( ).toInt ( );
  m_iSliderHeightStart = m_pEditHeight->text ( ).toInt ( );
}

void DialogThumbnail::slotSizeChanged ( int iNewSize )
{
  if ( ( m_iSliderWidthStart < 1 ) || ( m_iSliderHeightStart < 1 ) )
    return;
  // Values are between [ -100 .. +100 ] representing - 100% (0 size) and + 100% ( double the start size )
  float fMult   = ( (float)iNewSize / 100.0f ) + 1.0f;
  float fWidth  = fMult * (float)m_iSliderWidthStart;
  float fHeight = fMult * (float)m_iSliderHeightStart;
  m_pEditWidth ->setText ( QString ( "%1" ).arg ( (int)fWidth  ) );
  m_pEditHeight->setText ( QString ( "%1" ).arg ( (int)fHeight ) );
}

void DialogThumbnail::slotChapterChanged ( QListBoxItem *pListBoxItem )
{
  // Called when te user selects items in the ListBox on the left hand side.
  if ( ! pListBoxItem )
    return;

  if ( m_pSourceFileEntry )
    chapterChanged ( pListBoxItem );

  int t;
  QString qsChapter    = pListBoxItem->text ( );
  QIconViewItem *pItem = m_pIconViewThumbnails->firstItem ( );
  // First we ensure the current item is visible
  while ( pItem ) {
    if  ( getChapter ( pItem ) == qsChapter ) {
      m_pIconViewThumbnails->clearSelection    ( );
      m_pIconViewThumbnails->ensureItemVisible ( pItem );
      break;
    }
    pItem = pItem->nextItem ( );
  }

  // Next we loop through the ListBox and find each 
  // chapter that has been selected (multiple selection)
  for ( t=0;t<(int)m_pListBoxChapters->count ( ); t++ ) {
    pListBoxItem = m_pListBoxChapters->item ( t );
    qsChapter    = pListBoxItem->text ( );
    if ( pListBoxItem && pListBoxItem->isSelected ( ) ) {
//printf ( "DialogThumbnail::chapterChanged <%p>\n", pListBoxItem );
      // Okay, and for this selected ListBox item, we find the 
      // associciated IconViewItem and do also sect it.
      pItem = m_pIconViewThumbnails->firstItem ( );
      // First we ensure the current item is visible
      while ( pItem ) {
        if  ( getChapter ( pItem ) == qsChapter ) {
          m_pIconViewThumbnails->setSelected ( pItem, TRUE, TRUE );
          pItem = NULL;
        }
        else
          pItem = pItem->nextItem ( );
      }
    }
  }
}

void DialogThumbnail::chapterChanged ( QListBoxItem *pListBoxItem )
{
  // Called when te user selects items in the ListBox on the left hand side.
  if ( ! pListBoxItem )
    return;
  // This function handles SourceFileEntries
  // key = 00:00:00.000 : FileName.mpg

  QStringList list = QStringList::split ( " : ", pListBoxItem->text ( ) );
  if ( list.count ( ) == 2 )  {
    QString qsChapter, qsFileName, qsSearchKey;
    qsChapter   = list[0];
    qsFileName  = list[1];
    qsSearchKey = QString ( "jump+-+%1+-+%2+-+%3" ).arg ( m_pSourceFileEntry->qsDisplayName ).arg ( qsFileName ).arg ( qsChapter );

    QIconViewItem *pItem = m_pIconViewThumbnails->firstItem ( );
    // First we ensure the current item is visible
    while ( pItem ) {
      if  ( pItem->key ( ) == qsSearchKey )  {
        m_pIconViewThumbnails->clearSelection    ( );
        m_pIconViewThumbnails->ensureItemVisible ( pItem );
        //m_pIconViewThumbnails->setSelected ( pItem, TRUE, TRUE );
        break;
      }
      pItem = pItem->nextItem ( );
    }
  }

  // Next we loop through the ListBox and find each 
  // chapter that has been selected (multiple selection)
  QIconViewItem *pItem = NULL;
  for ( int t=0;t<(int)m_pListBoxChapters->count ( ); t++ ) {
    pListBoxItem = m_pListBoxChapters->item ( t );
    if ( pListBoxItem && pListBoxItem->isSelected ( ) ) {
      QStringList list = QStringList::split ( " : ", pListBoxItem->text ( ) );
      if ( list.count ( ) == 2 )  {
        QString qsChapter, qsFileName, qsSearchKey;
        qsChapter   = list[0];
        qsFileName  = list[1];
        qsSearchKey = QString ( "jump+-+%1+-+%2+-+%3" ).arg ( m_pSourceFileEntry->qsDisplayName ).arg ( qsFileName ).arg ( qsChapter );

        // Okay, and for this selected ListBox item, we find the 
        // associciated IconViewItem and do also sect it.
        pItem = m_pIconViewThumbnails->firstItem ( );
        // First we ensure the current item is visible
        while ( pItem ) {
          if  ( pItem->key ( ) == qsSearchKey  ) {
            m_pIconViewThumbnails->setSelected ( pItem, TRUE, TRUE );
            pItem = NULL;
          }
          else
            pItem = pItem->nextItem ( );
        }
      }
    }
  }
}

void DialogThumbnail::slotReload ( )
{
  // Here we request the whole enchilada again ...
  refresh ( true );
}

void DialogThumbnail::slotRefresh ( )
{
  refresh ( false );
}

void DialogThumbnail::refresh ( bool bForceReload )
{
  bool bOkay;
  int  iChapterCount = chapterCount ( );

  m_pProgressBar->reset ( );
  m_pIconViewThumbnails->clear ( );
  m_iCurrentChapter = 0;
  m_iProgress       = iChapterCount;

  if ( iChapterCount < 1 )
    return;

  // First we should remove outstanding tasks ...
  MediaCreator::unregisterFromMediaScanner ( this );

  m_iThumbnailWidth = m_pEditWidth->text ( ).toInt ( &bOkay );
  if ( ! bOkay )
    m_iThumbnailWidth = 120;

  m_iThumbnailHeight = m_pEditHeight->text ( ).toInt ( &bOkay );
  if ( ! bOkay )
    m_iThumbnailHeight = 120;

  m_iThumbnailStretchMode = m_pComboStretch->currentItem ( );

  while ( (int)m_iCurrentChapter < iChapterCount ) {
    if  ( bForceReload || getBufferedThumbnail ( ) ) {
      ThumbnailRequest *pRequest = NULL;
      SourceFileInfo   *pInfo    = getInfoFromChapterNumber ( m_iCurrentChapter );
      if ( ! pInfo )
        continue;

      Utils theUtils;
      long  iMSecOffset    = theUtils.getMsFromString ( chapter ( m_iCurrentChapter ) );
      QIconViewItem *pItem = createCurrentItem ( true );

      pRequest = new ThumbnailRequest ( this, pItem, pInfo->qsFileName, iMSecOffset );
      MediaCreator::registerWithMediaScanner ( pRequest );
      m_iProgress --;       // for every requeste thumbnail we decrease the progress.
      m_iCurrentChapter ++; // Also every requested thumbnail should increase the currentCHapter counter.
    }
  }
  m_pProgressBar->setProgress ( m_iProgress );
  int iTextType = m_pComboTextType->currentItem ( );
  slotTextType ( iTextType );
}

void DialogThumbnail::refreshEntry ( bool bForceReload )
{
  // Only called from initSourceFileEntry ( )
  bool  bOkay;
  Utils theUtils;
  int   t, iChapterCount;

  m_pProgressBar->reset ( );
  m_pIconViewThumbnails->clear ( );
  m_iCurrentChapter = 0;
  m_iProgress       = 0;

  if ( ! m_pSourceFileEntry )
    return;

  iChapterCount = chapterCount ( );
  m_iProgress   = iChapterCount;

  // First we should remove outstanding tasks ...
  MediaCreator::unregisterFromMediaScanner ( this );

  m_iThumbnailWidth = m_pEditWidth->text ( ).toInt ( &bOkay );
  if ( ! bOkay )
    m_iThumbnailWidth = 120;

  m_iThumbnailHeight = m_pEditHeight->text ( ).toInt ( &bOkay );
  if ( ! bOkay )
    m_iThumbnailHeight = 120;

  m_iThumbnailStretchMode = m_pComboStretch->currentItem ( );

  QValueList<SourceFileInfo *>::iterator it = m_pSourceFileEntry->listFileInfos.begin ( );
  SourceFileInfo *pInfo;
  while ( it != m_pSourceFileEntry->listFileInfos.end ( ) )  {  //m_iCurrentChapter < iChapterCount ) {
    pInfo = *it++;
    if ( ! pInfo )
      continue;

    for ( t=0; t<(int)pInfo->listChapters.count ( ); t++ )  {
      if  ( bForceReload )  { //|| getBufferedThumbnail ( ) ) {
        ThumbnailRequest *pRequest = NULL;
        //pInfo->pPreview = new QImage (QImage().fromMimeSource( "please_wait.jpg" ));

        long iMSecOffset = theUtils.getMsFromString (               pInfo->listChapters [ t ] );
        QIconViewItem *pItem = createCurrentItem    (  pInfo, true, pInfo->listChapters [ t ] );
        pRequest = new ThumbnailRequest ( this, pItem, pInfo->qsFileName, iMSecOffset );
        MediaCreator::registerWithMediaScanner ( pRequest );
        m_iProgress --;       // for every requeste thumbnail we decrease the progress.
        m_iCurrentChapter ++; // Also every requested thumbnail should increase the currentCHapter counter.
      }
    }
  }
  m_pProgressBar->setProgress ( m_iProgress );
  int iTextType = m_pComboTextType->currentItem ( );
  slotTextType ( iTextType );
}

QIconViewItem *DialogThumbnail::createCurrentItem ( bool bPleaseWait )
{
  SourceFileInfo *pInfo = getInfoFromChapterNumber ( m_iCurrentChapter );
  return createCurrentItem ( pInfo, bPleaseWait, chapter ( m_iCurrentChapter ) );
}

QIconViewItem *DialogThumbnail::createCurrentItem ( SourceFileInfo *pInfo, bool bPleaseWait, QString qsChapter )
{
  QIconViewItem *pItem   = NULL;
  QImage  theImage;
  QString qsActionString = m_qsActionString;

  QImage::ScaleMode scaleMode = QImage::ScaleMin;
  if ( m_iThumbnailStretchMode ==  1 )
    scaleMode = QImage::ScaleMax;
  if ( m_iThumbnailStretchMode ==  2 )
    scaleMode = QImage::ScaleFree;

  if ( bPleaseWait )
    theImage = QImage ( QImage ( ).fromMimeSource ( "please_wait.jpg" ) );
  else if ( pInfo )  {
    Utils     theUtils;
    QString   qsFileName, qsBaseName, qsFNChapter;
    QFileInfo fileInfo ( pInfo->qsFileName );
    qsBaseName  = theUtils.getTempPath ( fileInfo.baseName ( ) );
    qsFNChapter = qsChapter;
    qsFNChapter = qsFNChapter.remove   ( ':' );
    qsFNChapter = qsFNChapter.replace  ( '.', "_" );
    qsFileName  = qsBaseName + QString ( "/thumb_%1.png" ).arg ( qsFNChapter );
    if ( ! theImage.load ( qsFileName ) )
      return NULL;

    if ( theImage.isNull ( ) )
      return NULL;
  }

  if ( pInfo && m_pSourceFileEntry )  {
    // The m_qsActionString for the m_pSourceFileEntry is always ""
    // So we'll have to build out command here ...
    QFileInfo fileInfo       ( pInfo->qsFileName );
    qsActionString = QString ( "jump+-+%1+-+%2+-+" ).arg ( m_pSourceFileEntry->qsDisplayName ).arg ( fileInfo.fileName ( ) );
  }

  theImage  = theImage.smoothScale ( m_iThumbnailWidth, m_iThumbnailHeight, scaleMode );
  pItem     = new QIconViewItem    ( m_pIconViewThumbnails, qsChapter );
  if ( pItem ) {
    QPixmap thePixmap;
    if ( thePixmap.convertFromImage ( theImage ) ) {
      pItem->setPixmap ( thePixmap );
      pItem->setKey    ( qsActionString + qsChapter );
    }
  }
  return pItem;
}

