/****************************************************************************
** Derived off of DialogLibrary
** Very similar functionality.
**
**   Created : Sun May 22 09:13:25 2009
**        by : Varol Okan, using Kat
** Copyright : (c) Varol Okan
**   License : GPL v 2.0
**
**
****************************************************************************/

#include <qdir.h>
#include <qtimer.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qpainter.h>
#include <qcheckbox.h>
#include <qlineedit.h>
#include <qcombobox.h>
#include <qtabwidget.h>
#include <qpushbutton.h>
#include <qprogressbar.h>
#include <qapplication.h>

#include "global.h"
#include "dialogalphatrans.h"

static const char * xpmNoCheck[] = {
"16 16 17 1",
"       c None",
".      c #110807",
"+      c #3A0D0F",
"@      c #B00000",
"#      c #A3080B",
"$      c #CD0000",
"%      c #C20407",
"&      c #E40A0B",
"*      c #862829",
"=      c #5C3440",
"-      c #C41A1E",
";      c #E51E21",
">      c #C4373A",
",      c #EA3037",
"'      c #AA545A",
")      c #E85B60",
"!      c #E99398",
"  >>)     -)'   ",
"  *!>     >!*.  ",
" +'!)@   @)!'+. ",
"=')))>@ #>)))'=.",
"=',,,,->-,,,,>==",
".+#&$$;);$$&#+. ",
" .+@%@@%@@%@+.  ",
"  .*-@@@@@-*+   ",
"   #>-####>#    ",
"  #@@@@@@@@@#   ",
" #-%@%$;$%@%-#  ",
">-%%$$&,&&$%%-> ",
")-$$&&&$&&&$$%>>",
"@%&&&&$ $&&&&%@ ",
" %;);&   $&;&%  ",
"  ;),     &,,   "};

static const char * xpmCheck[] = {
"16 16 17 1",
"       c None",
".      c #041504",
"+      c #024D01",
"@      c #3C5039",
"#      c #197313",
"$      c #148F0E",
"%      c #3C9237",
"&      c #32B229",
"*      c #53AA4B",
"=      c #7DB474",
"-      c #4AD53E",
";      c #78C570",
">      c #61D256",
",      c #A0CF9C",
"'      c #8EDF86",
")      c #6AF253",
"!      c #77F26C",
"                ",
"            ++  ",
"           $%%# ",
"          $*=%#+",
"         #*=*$#+",
"  %%#   $*;*$$#@",
" %,,%. $*;>&$#. ",
"#=,,;$$*'>-&#.  ",
"#*;'';;'>-&#.   ",
"##$>'''>)-$+    ",
" +#&-!!)-&#     ",
"  #$&))!&&      ",
"   $$>>>&       ",
"    &$*>        ",
"     )          ",
"                "};



DialogAlphaTrans::Item::Item ( QIconView *pIconView, const QString &qsText, const QPixmap &thePix, bool bChecked )
  : QIconViewItem ( pIconView )
{
  m_bChecked   = bChecked;
  m_pixmap     = thePix;
  m_qsFileName = qsText;
  refreshIcon ( );
}

QString DialogAlphaTrans::Item::fileName ( )
{
  return m_qsFileName;
}

void DialogAlphaTrans::Item::setChecked ( bool bChecked )
{
  m_bChecked = bChecked;
  refreshIcon ( );
}

void DialogAlphaTrans::Item::toggleCheck ( )
{
  m_bChecked = ! m_bChecked;
  QPoint position = pos ( );
  refreshIcon   ( );
  move ( position );
  iconView ( )->updateContents ( );
}

bool DialogAlphaTrans::Item::isChecked ( )
{
  return m_bChecked;
}

void DialogAlphaTrans::Item::calcRect ( const QString &string )
{
  QIconViewItem::calcRect ( string );
  QRect rect  ( 0, 0, 0, 0 );
  setTextRect ( rect );
  setItemRect ( pixmapRect ( ) );
}

void DialogAlphaTrans::Item::refreshIcon ( )
{
  QPixmap pixCheck, thePix;
  int iX, iY, iWidth, iHeight; //, iThumbSize;
  QColor clrBlue ( 120, 120, 255 );

  if ( m_bChecked )
    pixCheck = QPixmap ( xpmCheck   );
  else
    pixCheck = QPixmap ( xpmNoCheck );

  iX = iY = 1;
  iWidth  = m_pixmap.width  ( );
  iHeight = m_pixmap.height ( );

  int  iSize = iWidth;
  if ( iSize < iHeight )
       iSize = iHeight;
  if ( iSize < 16 )
       iSize = 16;
  thePix = QPixmap ( iSize + 2, iSize + 2 + 16);
  thePix.fill ( 0xFFFFFF );

  iX = (int)( ( iSize - iWidth  ) / 2.0 ) + 1;
  iY = (int)( ( iSize - iHeight ) / 2.0 ) + 1;

  copyBlt ( &thePix, iX, iY, &m_pixmap );

  // Frame the pix
  iWidth  += 2;
  iHeight += 2;
  QPainter thePainter ( &thePix );
  thePainter.setPen   ( clrBlue );
  thePainter.drawLine (       0,       0, iSize-1,       0 );
  thePainter.drawLine ( iSize-1,       0, iSize-1, iSize-1 );
  thePainter.drawLine ( iSize-1, iSize-1,       0, iSize-1 );
  thePainter.drawLine (       0, iSize-1,       0,       0 );

  // next we copy the check box
  iX = (int)( ( (float)iWidth - 16.0 ) / 2.0 );
  copyBlt ( &thePix, iX, iSize + 1, &pixCheck, 0, 0, 16, 16 );

  setPixmap ( thePix );
}

DialogAlphaTrans::FilterPart::FilterPart ( QIconView *pView, QString qsPath )
{
  pIconView    = pView;
  qsFilterPath = qsPath;
}

DialogAlphaTrans::DialogAlphaTrans ( QStringList &listEnabled, QWidget *pParent, const char *pName, bool bModal, WFlags flags )
  : uiDialogLibrary ( pParent, pName, bModal, flags )
{
  m_listEnabled = listEnabled;
  initMe ( );
}

DialogAlphaTrans::~DialogAlphaTrans ( )
{
  int t;
  for ( t=0; t<(int)m_listFilter.count ( ); t++ ) 
    delete m_listFilter[t];
}

void DialogAlphaTrans::initMe ( )
{
  // build all library tabs.
  int      t;
  QDir     theDir;
  QString  qsPrefixDir, qsDirName;
  QStringList listDirs, listFiles;

  qsPrefixDir = QString ("%1/share/qdvdauthor/slideshow/transitions").arg ( Global::qsSystemPath );
  if ( !  theDir.exists ( qsPrefixDir ) )
    return;

  m_iThumbSize = 80;
  m_pEditWidth->setText ( QString ( "%1" ).arg ( m_iThumbSize ) );
  m_pEditHeight->hide   ( );
  m_pLabelHeight->hide  ( );
  m_pComboStretch->hide ( );
  m_pLabelWidth->setText ( tr ( "Size : " ) );

  QWidget *pTab = m_pTabWidget->page ( 0 );
  while  ( pTab ) {
    delete pTab;
    pTab = m_pTabWidget->page ( 0 );
  }

  theDir.cd ( qsPrefixDir, TRUE );
  listDirs = theDir.entryList ( QDir::Dirs, QDir::Name );
  if ( listDirs.count ( ) < 3 ) // 3 = this dir / parent dir / background file
    return;

  // The following widgets will create th progress dialog on the fly.
  QDialog       progressDialog  ( NULL );
  QGridLayout  *pProgressLayout = new QGridLayout  ( &progressDialog ); //, 1, 1 ); //, 11, 6, "progressWidgetLayout" );
  QProgressBar *pProgressBar    = new QProgressBar ( &progressDialog );
  pProgressLayout->addWidget( pProgressBar, 0, 0 );
  progressDialog.resize( QSize(537, 50).expandedTo ( progressDialog.minimumSizeHint ( ) ) );
  progressDialog.show  ( );

  for ( t=0; t<(int)listDirs.count ( ); t++ )  {
    // Here we go through all directories 
    qsDirName = listDirs[t];
    if ( ( qsDirName == ".") || ( qsDirName == "..") )
      continue;

    progressDialog.setCaption ( tr ( "Creating preview for buttons : %1" ).arg ( listDirs[t] ) );

    // Next we need to get the file list of the found directory
    QString qsPath = qsPrefixDir + "/" + qsDirName;
    theDir.cd ( qsPath );
    listFiles = theDir.entryList ( QDir::Files, QDir::Name );
    createTab ( qsDirName, qsPath, listFiles );

    pProgressBar->setProgress ( (int)((float)t / listDirs.count ( ) * 100.0) );
    qApp->processEvents ( 100 ); // do some event processing ...
  }

  QSize size ( m_iThumbSize, m_iThumbSize );
  FilterPart *pFilterPart = NULL;
  for ( uint t=0; t<m_listFilter.size ( ); t++ )  {
    pFilterPart   = m_listFilter     [ t ];

//    pLibraryPart->pIconView->setGridX ( size.width  ( ) );
//    pLibraryPart->pIconView->setGridY ( size.height ( ) );
//    pLibraryPart->pIconView->arrangeItemsInGrid  ( size );
  }

  m_pCheckButtonMask->hide ( );
  connect ( m_pButtonRefresh,   SIGNAL ( clicked ( ) ), this, SLOT ( slotRefresh ( ) ) );
  QTimer::singleShot ( 200, this, SLOT ( slotAfterInit ( ) ) );
}

void DialogAlphaTrans::createTab ( QString qsDirName, QString qsPath, QStringList &listFiles )
{
  int t;
  if ( listFiles.count ( ) < 1 )
    return;

  // Okay, ready to create the tab ... 
  bool bChecked;
  QFileInfo fileInfo;
  QString qsFileName;
  QSize grid ( 80, 80 );
  QWidget     *pTab      = new QWidget     ( m_pTabWidget, "pTab" );
  QGridLayout *pLayout   = new QGridLayout ( pTab, 1, 1, 4, 2, "pLayout" );
  QIconView   *pIconView = new QIconView   ( pTab, "pIconViewLibrary" );
  FilterPart  *pNewPart  = new FilterPart  ( pIconView, qsPath );
  m_listFilter.append ( pNewPart );

  pLayout->addWidget        ( pIconView,  0, 0 );
  pIconView->setAutoArrange ( true  );
  m_pTabWidget->insertTab   ( pTab,  qsDirName );

  for ( t=0; t<(int)listFiles.count ( ); t++ ) {
    qsFileName = qsPath + "/" + listFiles[t];
    QPixmap thePix;
    QImage  theImage ( qsFileName );

    if ( theImage.isNull ( ) )
      continue;

    if ( ( theImage.width ( ) > m_iThumbSize ) || ( theImage.height ( ) > m_iThumbSize ) )
      theImage = theImage.smoothScale ( m_iThumbSize, m_iThumbSize, QImage::ScaleMin );

    thePix.convertFromImage ( theImage );

    fileInfo.setFile  ( listFiles[t] );
    qsFileName = fileInfo.baseName ( );
    bChecked   = isChecked ( qsFileName );

    new Item ( pIconView, listFiles[t], thePix, bChecked );
  }

  pIconView->setSelectionMode ( QIconView::NoSelection );
  pIconView->setAutoArrange   (  TRUE );
  pIconView->setItemsMovable  ( FALSE );
  pIconView->setResizeMode    ( QIconView::Adjust );
  pIconView->sort ( );
  pIconView->arrangeItemsInGrid ( grid, TRUE );

  connect ( pIconView, SIGNAL ( mouseButtonClicked ( int, QIconViewItem *, const QPoint & ) ), this, SLOT ( slotClicked ( int, QIconViewItem *, const QPoint & ) ) );
}

void DialogAlphaTrans::slotAfterInit ( )
{
  // Somehow the first IconView does not arrange in a grid.
  // so we have to force it to arrange
  if ( m_listFilter.count ( ) < 1 )
    return;

  FilterPart *pFilterPart = m_listFilter [ 0 ];
  pFilterPart->pIconView->sort ( true );
}

void DialogAlphaTrans::slotClicked ( int iButton, QIconViewItem *pItm, const QPoint & )
{
  if ( ! pItm )
    return;

  if ( iButton == Qt::LeftButton )  {
    Item *pItem = (Item *)pItm;
    pItem->toggleCheck ( );
  }
}

void DialogAlphaTrans::slotRefresh ( )
{
  bool bOkay, bChecked;
  int t;
  QDir         theDir;
  QFileInfo    fileInfo;
  QString      qsFileName;
  QStringList  listFiles;
  QIconView   *pCurrentView = NULL;
  FilterPart  *pFilterPart = NULL;
  int          iCurrentTab = m_pTabWidget->currentPageIndex ( );
  QSize        grid ( 10, 10 );
  if ( iCurrentTab <(int)m_listFilter.count ( ) )
    pFilterPart = m_listFilter [ iCurrentTab ];

  if ( ! pFilterPart )
    return;

  pCurrentView = pFilterPart->pIconView;
  pCurrentView->clear ( );

  m_iThumbSize = m_pEditWidth->text ( ).toInt ( &bOkay );
  if ( ! bOkay )
    m_iThumbSize = 80;

  theDir.cd ( pFilterPart->qsFilterPath );
  listFiles = theDir.entryList ( QDir::Files, QDir::Name );

  for ( t=0; t<(int)listFiles.count ( ); t++ ) {
    qsFileName = pFilterPart->qsFilterPath + "/" + listFiles[t];
    QPixmap thePix;
    QImage  theImage ( qsFileName );

    if ( theImage.isNull ( ) )
      continue;

    if ( ( theImage.width ( ) > m_iThumbSize ) || ( theImage.height ( ) > m_iThumbSize ) )
      theImage = theImage.smoothScale ( m_iThumbSize, m_iThumbSize, QImage::ScaleFree );

    thePix.convertFromImage ( theImage );

    fileInfo.setFile  ( listFiles[t] );
    qsFileName = fileInfo.baseName ( );
    bChecked   = isChecked ( qsFileName );

    new Item ( pCurrentView, listFiles[t], thePix, bChecked );
  }

  pCurrentView->arrangeItemsInGrid ( grid, TRUE );
}

bool DialogAlphaTrans::isChecked ( QString &qsString )
{
  QStringList::iterator it = m_listEnabled.begin ( );
  while ( it != m_listEnabled.end ( ) )  {
    if ( *it++ == qsString )
      return true;
  }

  return false;
}

void DialogAlphaTrans::accept ( )
{
  // do si do
  FilterPart *pPart     = NULL;
  Item       *pItem     = NULL;
  QIconView  *pIconView = NULL;
  QString     qsName ( "Cross Fade" );
  QFileInfo   fileInfo;
  if ( isChecked ( qsName ) ) {
    m_listEnabled.clear   ( );
    m_listEnabled.append  ( qsName );
  }
  else
    m_listEnabled.clear ( );

  for ( uint t=0; t<m_listFilter.count ( ) ; t++ )  {
    pPart = m_listFilter[t];
    pIconView = pPart->pIconView;
    pItem = (Item *)pIconView->firstItem ( );
    while ( pItem )  {
      if  ( pItem->isChecked ( ) )  {
        fileInfo.setFile ( pItem->fileName ( ) );
        qsName = fileInfo.baseName  ( );
        m_listEnabled.append ( qsName );
      }
      pItem = (Item *)pItem->nextItem ( );
    }
  }

  // Skip the DialogFilter accept
  uiDialogLibrary::accept ( );
}

