/***************************************************************************
                          emoticonspage.cpp -  description
                             -------------------
    begin                : Sun Dev 11 2005
    copyright            : (C) 2005 by Diederik van der Boor
    email                : "vdboor" --at-- "codingdomain.com"
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "emoticonspage.h"

#include "../dialogs/addemoticondialog.h"
#include "../currentaccount.h"
#include "../emoticonmanager.h"
#include "../kmessdebug.h"

#include <QDir>
#include <QListWidget>
#include <QPixmap>

#include <KMessageBox>
#include <KStandardDirs>


#ifdef KMESSDEBUG_EMOTICONS
  #define KMESSDEBUG_EMOTICONS_SETTINGS
#endif



/**
 * Constructor
 *
 * @param parent  Parent widget
 */
EmoticonsPage::EmoticonsPage( QWidget* parent )
  : QWidget(parent)
  , Ui::EmoticonsPage()
  , emoticonTheme_(0)
{
  // First setup the user interface
  setupUi( this );

  // Connect the signals we'll need for the Custom Emoticons tab
  connect( addEmoticonButton_,    SIGNAL(                clicked()                 ),
           this,                    SLOT(  showAddEmoticonDialog()                 ) );
  connect( renameEmoticonButton_, SIGNAL(                clicked()                 ),
           this,                    SLOT(   renameCustomEmoticon()                 ) );
  connect( removeEmoticonButton_, SIGNAL(                clicked()                 ),
           this,                    SLOT(   removeCustomEmoticon()                 ) );
  connect( customEmoticonsView_,  SIGNAL(        itemDoubleClicked(QListWidgetItem*) ),
           this,                    SLOT(   renameCustomEmoticon()                 ) );
  connect( customEmoticonsView_,  SIGNAL(   itemSelectionChanged()                 ),
           this,                    SLOT( customEmoticonSelected()                 ) );
  connect( customEmoticonsView_,  SIGNAL(            itemEntered(QListWidgetItem*) ),
           this,                    SLOT(         requestPreview(QListWidgetItem*) ) );

  previewMovie_ = new QMovie( this );
  previewMovie_->stop();
  previewMovie_->setCacheMode( QMovie::CacheAll );
  previewLabel_->setMovie( previewMovie_ );
  // the other properties of the widget are initialized
  // in the loadSettings() method
}



/**
 * Destructor
 */
EmoticonsPage::~EmoticonsPage()
{
  if( emoticonTheme_ != 0 )
  {
#ifdef KMESSDEBUG_EMOTICONS_SETTINGS
    kDebug() << "Deleting temporary theme.";
#endif
    delete emoticonTheme_;
  }
}



/**
 * Preview requested
 */
void EmoticonsPage::requestPreview( QListWidgetItem *item )
{

  // Stop the movie and set the new emoticon
  previewMovie_->stop();

  // If the new item is not null set the emoticon to preview
  if( item != 0 )
  {
    previewLabel_->setMovie( previewMovie_ );
    previewMovie_->setFileName( item->data( Qt::UserRole ).toString() );
  }
  else
  {
    // if the item is null, set empty pixmap
    previewLabel_->setPixmap( QPixmap() );
    return;
  }

  // Check if the file format is valid
  if( ! previewMovie_->isValid() )
  {
    return;
  }

  previewMovie_->start();

  // Scale the emoticon if it is larger than its container
  if( previewMovie_->currentPixmap().size().width()  > previewLabel_->size().width()
  ||  previewMovie_->currentPixmap().size().height() > previewLabel_->size().height() )
  {
    previewLabel_->setScaledContents( true );
  }
  else
  {
    previewLabel_->setScaledContents( false );
  }
}




/**
 * Update the Remove Button status when emoticons get selected
 */
void EmoticonsPage::customEmoticonSelected()
{
  bool hasSelection = ( ! customEmoticonsView_->selectedItems().isEmpty() );

  renameEmoticonButton_->setEnabled( hasSelection );
  removeEmoticonButton_->setEnabled( hasSelection );
}



/**
 * Load the settings of the dialog
 *
 * @param account  Account instance which settings will be loaded
 */
void EmoticonsPage::loadSettings( const Account *account )
{
  accountHandle_ = account->getHandle();

#ifdef KMESSDEBUG_EMOTICONS_SETTINGS
  kDebug() << "Loading emoticon settings for account " << accountHandle_ << " - Current is " << accountHandle_ << " .";
#endif

  // Read the settings and set current emoticons
  emoticonStyle_ = account->getEmoticonStyle();

  emoticonTheme_ = new EmoticonTheme();
  emoticonTheme_->loadTheme( accountHandle_, true );

  // Update the emoticon themes widget
  updateThemesList();

  // Update the custom emoticons widget
  updateCustomEmoticonView();

#ifdef KMESSDEBUG_EMOTICONS_SETTINGS
  kDebug() << "Done!";
#endif
}



/**
 * Delete the selected custom emoticon from the theme and the view
 */
void EmoticonsPage::removeCustomEmoticon()
{
  const QList<QListWidgetItem *>& selectedItems( customEmoticonsView_->selectedItems() );

  if( selectedItems.isEmpty() )
  {
    return;
  }

  const QListWidgetItem *item = selectedItems.first();

  // Request confirmation
  int result = KMessageBox::questionYesNo( this,
                                       i18n( "Are you sure you want to delete the emoticon \"%1\" ?", item->text() ),
                                       i18nc( "Dialog box title", "Delete Emoticon" ) );
  if( result != KMessageBox::Yes )
  {
    return;
  }

  // Remove the emoticon from the temporary theme, and if that succeeds, from the list
  int itemRow = customEmoticonsView_->row( item );
  
  previewMovie_->stop();
  previewLabel_->setMovie( 0 );

  if( emoticonTheme_->removeEmoticon( item->text() ) && itemRow >= 0 )
  {
    // Safe, takeItem() returns 0 on failure
    delete customEmoticonsView_->takeItem( itemRow );

    // Forcibly update the buttons status to disable the rename&remove buttons
    customEmoticonSelected();
  }
}



/**
 * Starts renaming of the selected custom emoticon
 */
void EmoticonsPage::renameCustomEmoticon()
{
  QListWidgetItem *item = customEmoticonsView_->currentItem();

  if( item == 0 )
  {
    return;
  }

  AddEmoticonDialog *dialog = new AddEmoticonDialog( emoticonTheme_, this );
  dialog->editEmoticon( item->data( Qt::UserRole ).toString(), item->text() );

  connect( dialog, SIGNAL(          changedEmoticon(const QString&) ),
           this,     SLOT( updateCustomEmoticonView()               ) );
}



/**
 * Save the settings to the account object
 *
 * @param account  Account instance which settings will be saved
 */
void EmoticonsPage::saveSettings( Account *account )
{
  // Save the changes we've made
  emoticonTheme_->saveTheme();

  // Enable emoticon styles only if there's one selected (the list may be empty)
  if( emoticonThemesList_->currentItem() )
  {
    account->setEmoticonStyle( emoticonThemesList_->currentItem()->text() );
  }
  else
  {
    account->setEmoticonStyle( QString() );
  }

  // Apply the changes to the current account, too
  if( accountHandle_ == CurrentAccount::instance()->getHandle() )
  {
    EmoticonManager::instance()->replaceCustomTheme( emoticonTheme_ );
  }
}



/**
 * Show the Add New Emoticon dialog to create a new custom emoticon
 */
void EmoticonsPage::showAddEmoticonDialog()
{
  AddEmoticonDialog *dialog = new AddEmoticonDialog( emoticonTheme_, this );

  connect( dialog, SIGNAL(            addedEmoticon(QString) ),
           this,     SLOT( updateCustomEmoticonView()        ) );
}



// Force the page onto a specific tab
void EmoticonsPage::switchToTab( int tabIndex )
{
  if( ( tabIndex < 0 ) || tabIndex > tabWidget_->count() )
  {
    kWarning() << "Invalid tab index" << tabIndex << "selected!";
    return;
  }

  tabWidget_->setCurrentIndex( tabIndex );
}



/**
 * Fill the widget which contains all the user's custom emoticons
 */
void EmoticonsPage::updateCustomEmoticonView()
{
  QListWidgetItem *item;

  customEmoticonsView_->clear();

  // Add all emoticons to the list
  const QList<Emoticon*>& emoticons( emoticonTheme_->getEmoticons() );
  foreach( Emoticon *emoticon, emoticons )
  {
    if( ! emoticon->isValid() )
    {
      continue;
    }

    item = new QListWidgetItem( QIcon( emoticon->getPicturePath() ), emoticon->getShortcut(), customEmoticonsView_ );
    item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
    item->setData( Qt::UserRole, emoticon->getPicturePath() );
  }

  // Force an update of the view's buttons
  customEmoticonSelected();
}



/**
 * Initialize the standard emoticon theme chooser
 */
void EmoticonsPage::updateThemesList()
{
  emoticonThemesList_->clear();

  // Browse all emoticon dirs, to get all emoticons
  const QStringList& themesDirs( KGlobal::dirs()->findDirs("emoticons", "") );

#ifdef KMESSDEBUG_EMOTICONS_SETTINGS
  kDebug() << "Theme dirs: " << themesDirs;
#endif

  QDir themesDir;
  foreach( const QString& themesPath, themesDirs )
  {
    // Browse for all themes in the emoticon dir
    themesDir.setPath( themesPath );

    // Grep all themes in current dir
    const QStringList& themes( themesDir.entryList( QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase ) );

    foreach( const QString& themePath, themes )
    {
#ifdef KMESSDEBUG_EMOTICONS_SETTINGS
      kDebug() << "Folder: " << themesPath << " - Theme: " << themePath;
#endif
      // Add the theme to the list, using the directory name; its first valid emoticon is used as a preview
      const QPixmap previewPixmap( EmoticonTheme::getThemeIcon( themesPath + themePath ) );
      new QListWidgetItem( previewPixmap, themePath, emoticonThemesList_ );
    }
  }

  // Highlight the selected emoticon
  QListWidgetItem* item = 0;
  QList<QListWidgetItem*> items( emoticonThemesList_->findItems( emoticonStyle_, Qt::MatchExactly | Qt::MatchCaseSensitive ) );

  if( items.isEmpty() )
  {
    kWarning() << "Current emoticon style was not found, attempting to revert to the default setting.";
    items = emoticonThemesList_->findItems( "KMess-new", Qt::MatchExactly | Qt::MatchCaseSensitive );
  }
  else
  {
    item = items.first();
  }

  // If there is an item, select it
  if( item != 0 )
  {
    emoticonThemesList_->setCurrentItem( item );
  }
  else
  {
    // select the first item otherwise
    emoticonThemesList_->setCurrentRow( 0 );
  }
}



#include "emoticonspage.moc"
