/***************************************************************************
                          miscellaneouspage.h -  description
                             -------------------
    begin                : Sat May 3 2008
    copyright            : (C) 2008 by Antonio Nastasi
    email                : sifcenter@gmail.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 "miscellaneouspage.h"
#include "kmessdebug.h"

#include <KApplication>
#include <KFileDialog>
#include <KMessageBox>
#include <KMimeTypeTrader>
#include <KProcess>
#include <KUrlCompletion>



/**
 * Constructor
 *
 * @param parent  Parent widget
 */
MiscellaneousPage::MiscellaneousPage( QWidget *parent )
: QWidget(parent)
{
  // First setup the user interface
  setupUi( this );

  // Connect the radio buttons signals
  connect( useListedBrowserRadio_,    SIGNAL(     toggled(bool) ), browsersCombo_,        SLOT(         setEnabled(bool) ) );
  connect( useCustomBrowserRadio_,    SIGNAL(     toggled(bool) ), customBrowserEdit_,    SLOT(         setEnabled(bool) ) );
  connect( useCustomBrowserRadio_,    SIGNAL(     toggled(bool) ), customBrowserInfo_,    SLOT(         setEnabled(bool) ) );
  connect( useListedMailClientRadio_, SIGNAL(     toggled(bool) ), mailClientsCombo_,     SLOT(         setEnabled(bool) ) );
  connect( useCustomMailClientRadio_, SIGNAL(     toggled(bool) ), customMailClientEdit_, SLOT(         setEnabled(bool) ) );
  connect( useCustomMailClientRadio_, SIGNAL(     toggled(bool) ), customMailClientInfo_, SLOT(         setEnabled(bool) ) );
  connect( lowestTransferPort_,       SIGNAL( valueChanged(int) ), this,                  SLOT( checkPortsInterval()     ) );
  connect( highestTransferPort_,      SIGNAL( valueChanged(int) ), this,                  SLOT( checkPortsInterval()     ) );

  // Prepare and browse the list of available browsers
  const KService::List browserServices = KMimeTypeTrader::self()->query( "text/html", "Application" );
  for( KService::List::ConstIterator it = browserServices.begin() ; it != browserServices.end() ; ++it )
  {
    KService::Ptr servicePointer = *it;
    KService *service = servicePointer.data();

    // This application isn't valid or is already listed
    if( ! service || browsersCombo_->findData( QVariant( service->exec() ) ) != -1 )
    {
      continue;
    }

#ifdef KMESSDEBUG_SETTINGSDIALOG
    kDebug() << "Adding browser to list:" << service->name() << " -> " << service->exec();
#endif
    browsersCombo_->addItem( KIcon( service->icon() ), service->name(), QVariant( service->exec() ) );
  }

  if( browsersCombo_->count() == 0 )
  {
    useCustomBrowserRadio_->setChecked( true );
    useListedBrowserRadio_->setEnabled( false );
    browsersCombo_->addItem( i18n("No selectable web browsers detected.") );
    browsersCombo_->setEnabled( false );
  }

  // Prepare and browse the list of available email clients
  const KService::List mailServices = KMimeTypeTrader::self()->query( "application/x-mimearchive", "Application" );
  for( KService::List::ConstIterator it = mailServices.begin() ; it != mailServices.end() ; ++it )
  {
    KService::Ptr servicePointer = *it;
    KService *service = servicePointer.data();

    // This application isn't valid or is already listed
    if( ! service || mailClientsCombo_->findData( QVariant( service->exec() ) ) != -1 )
    {
      continue;
    }

#ifdef KMESSDEBUG_SETTINGSDIALOG
    kDebug() << "Adding mail client to list:" << service->name() << " -> " << service->exec();
#endif
    mailClientsCombo_->addItem( KIcon( service->icon() ), service->name(), QVariant( service->exec() ) );
  }

  if( mailClientsCombo_->count() == 0 )
  {
    useCustomMailClientRadio_->setChecked( true );
    useCustomMailClientRadio_->setEnabled( false );
    mailClientsCombo_->addItem( i18n("No selectable email clients detected.") );
    mailClientsCombo_->setEnabled( false );
  }

  // Prepare and connect the directory selection button
  chooseDirButton_->setIcon( KIcon( "folder-open" ) );
  connect( chooseDirButton_, SIGNAL( clicked() ), this, SLOT( slotChooseDirectory() ) );

  // Make the directory selection friendlier
  KUrlCompletion *dirCompletion = new KUrlCompletion( KUrlCompletion::DirCompletion );
  dirCompletion->setParent( this );
  receivedFilesDirEdit_->setCompletionObject( dirCompletion );
  receivedFilesDirEdit_->setClearButtonShown( true );
}



/**
 * Destructor
 */
MiscellaneousPage::~MiscellaneousPage()
{
}



/**
 * @brief Ensure that the specified P2P ports interval is valid
 */
void MiscellaneousPage::checkPortsInterval()
{
  int lowerPortValue = lowestTransferPort_->value();

  // Allow a minimum of two ports in the interval
  if( lowerPortValue >= highestTransferPort_->value() )
  {
    highestTransferPort_->setValue( lowerPortValue + 1 );
  }
}



/**
 * @brief Load the widget state
 */
void MiscellaneousPage::loadSettings( const KConfigGroup &group )
{
  // Read the settings into the widgets
  customBrowserEdit_   ->setText   ( group.readEntry( "customBrowser",       QString()        ) );
  customMailClientEdit_->setText   ( group.readEntry( "customMailClient",    QString()        ) );
  receivedFilesDirEdit_->setText   ( group.readEntry( "receivedFilesDir",    QDir::homePath() ) );
  useLiveMailCheckbox_ ->setChecked( group.readEntry( "useLiveMail",         true             ) );
  useReceivedFilesDir_ ->setChecked( group.readEntry( "useReceivedFilesDir", false            ) );
  lowestTransferPort_  ->setValue  ( group.readEntry( "lowestTransferPort",  6891             ) );
  highestTransferPort_ ->setValue  ( group.readEntry( "highestTransferPort", 6900             ) );

  int pos;
  QString userChoice;
  KService::Ptr servicePointer;
  KService *service;

  // Read the browser's radio buttons setting
  userChoice = group.readEntry( "useBrowser", "KDE" );
  if( userChoice == "KDE" )
  {
    useKDEBrowserRadio_->setChecked( true );
  }
  else if( userChoice == "listed" )
  {
    useListedBrowserRadio_->setChecked( true );
  }
  else
  {
    useCustomBrowserRadio_->setChecked( true );
  }

  userChoice = group.readEntry( "useMailClient", "KDE" );
  if( userChoice == "KDE" )
  {
    useKDEMailClientRadio_->setChecked( true );
  }
  else if( userChoice == "listed" )
  {
    useListedMailClientRadio_->setChecked( true );
  }
  else
  {
    useCustomMailClientRadio_->setChecked( true );
  }

  // Find the browser and select it
  pos = browsersCombo_->findData( group.readEntry( "listedBrowser", QString() ) );
  if( pos > -1 )
  {
#ifdef KMESSDEBUG_SETTINGSDIALOG
    kDebug() << "Browser setting - Changing current index to" << pos;
#endif
    browsersCombo_->setCurrentIndex( pos );
  }
  else
  {
    // If there's no preference set, allow KDE to choose
    servicePointer = KMimeTypeTrader::self()->preferredService( "text/html", "Application" );
    service = servicePointer.data();

    if( service )
    {
      pos = browsersCombo_->findData( service->exec() );

      if( pos > -1 )
      {
#ifdef KMESSDEBUG_SETTINGSDIALOG
        kDebug() << "Setting system preferred browser to" << pos;
#endif
        browsersCombo_->setCurrentIndex( pos );
      }
      else
      {
#ifdef KMESSDEBUG_SETTINGSDIALOG
        kDebug() << "Not setting any browser";
#endif
      }
    }
#ifdef KMESSDEBUG_SETTINGSDIALOG
    else
    {
      kDebug() << "No service found: not setting any browser";
    }
#endif
  }

  // Find the mail client and select it
  pos = mailClientsCombo_->findData( group.readEntry( "listedMailClient", QString() ) );
  if( pos > -1 )
  {
#ifdef KMESSDEBUG_SETTINGSDIALOG
    kDebug() << "Mail Client setting - Changing current index to" << pos;
#endif
    mailClientsCombo_->setCurrentIndex( pos );
  }
  else
  {
    // If there's no preference set, allow KDE to choose
    servicePointer = KMimeTypeTrader::self()->preferredService( "application/x-mimearchive", "Application" );
    service = servicePointer.data();

    if( service )
    {
      pos = mailClientsCombo_->findData( service->exec() );

      if( pos > -1 )
      {
#ifdef KMESSDEBUG_SETTINGSDIALOG
        kDebug() << "Setting system preferred mail client to" << pos;
#endif
        mailClientsCombo_->setCurrentIndex( pos );
      }
      else
      {
#ifdef KMESSDEBUG_SETTINGSDIALOG
        kDebug() << "Not setting any mail client";
#endif
      }
    }
#ifdef KMESSDEBUG_SETTINGSDIALOG
    else
    {
      kDebug() << "No service found: not setting any mail client";
    }
#endif
  }
}



/**
 * @brief Save account information from the misc options widget
 */
bool MiscellaneousPage::saveSettings( KConfigGroup &group )
{
  // Make sure there's a custom browser selected if the relevant option is set
  if( useCustomBrowserRadio_->isChecked() )
  {
    if( customBrowserEdit_->text().isEmpty() )
    {
      KMessageBox::error( 0, i18n( "You have to specify a console command to launch a custom web browser!" ) );
      return false;
    }
    else if( ! customBrowserEdit_->text().contains( "%u" ) )
    {
      int result = KMessageBox::warningYesNoCancel( 0, i18n( "<html>The console command you have specified to launch a custom web browser "
                                                             "does not contain the '%u' parameter. Without this, opening web "
                                                             "sites will not work.<br />Do you want KMess to add it for you?</html>" ) );

      // Only add the parameter if the user wants to
      switch( result )
      {
        case KMessageBox::Yes:
          customBrowserEdit_->setText( customBrowserEdit_->text().append( " %u" ) );
          break;

        case KMessageBox::No:
          break;

        default:
          return false;
      }
    }
  }

  // Make sure there's a custom mail client selected if the relevant option is set
  if( useCustomMailClientRadio_->isChecked() )
  {
    if( customMailClientEdit_->text().isEmpty() )
    {
      KMessageBox::error( 0, i18n( "You have to specify a console command to launch a custom email client!" ) );
      return false;
    }
    else if( ! customMailClientEdit_->text().contains( "%u" ) )
    {
      int result = KMessageBox::warningYesNoCancel( 0, i18n( "<html>The console command you specified to launch a custom email client "
                                                             "does not contain the '%u' parameter. Without this, composing "
                                                             "emails will not work.<br />Do you want KMess to add it for you?</html>" ) );

      // Only add the parameter if the user wants to
      switch( result )
      {
        case KMessageBox::Yes:
          customMailClientEdit_->setText( customMailClientEdit_->text().append( " %u" ) );
          break;

        case KMessageBox::No:
          break;

        default:
          return false;
      }
    }
  }

  // Make sure there's a selected directory if the Save files in a directory option is set
  if( useReceivedFilesDir_->isChecked() && receivedFilesDirEdit_->text().isEmpty() )
  {
    KMessageBox::error( 0, i18n( "You have to select a directory for the received files!" ) );
    return false;
  }

  QString userChoice;

  // Save the checked browser option
  if( useKDEBrowserRadio_->isChecked() )
  {
    userChoice = "KDE";
  }
  else if( useListedBrowserRadio_->isChecked() )
  {
    userChoice = "listed";
  }
  else
  {
    userChoice = "custom";
  }
  group.writeEntry( "useBrowser", userChoice );

  // Save the checked mail client option
  if( useKDEMailClientRadio_->isChecked() )
  {
    userChoice = "KDE";
  }
  else if( useListedMailClientRadio_->isChecked() )
  {
    userChoice = "listed";
  }
  else
  {
    userChoice = "custom";
  }
  group.writeEntry( "useMailClient", userChoice );

  // Save the state of the other widgets
  group.writeEntry( "customBrowser",       customBrowserEdit_   ->text()      );
  group.writeEntry( "customMailClient",    customMailClientEdit_->text()      );
  group.writeEntry( "receivedFilesDir",    receivedFilesDirEdit_->text()      );
  group.writeEntry( "useReceivedFilesDir", useReceivedFilesDir_ ->isChecked() );
  group.writeEntry( "useLiveMail",         useLiveMailCheckbox_ ->isChecked() );
  group.writeEntry( "lowestTransferPort",  lowestTransferPort_  ->value()     );
  group.writeEntry( "highestTransferPort", highestTransferPort_ ->value()     );

  int index = browsersCombo_->currentIndex();
  group.writeEntry( "listedBrowser",    browsersCombo_   ->itemData( index ) );
  index = mailClientsCombo_->currentIndex();
  group.writeEntry( "listedMailClient", mailClientsCombo_->itemData( index ) );

  return true;
}



/**
 * Allow the user to navigate the filesystem and choose a directory
 */
void MiscellaneousPage::slotChooseDirectory()
{
  const KUrl url( KFileDialog::getExistingDirectoryUrl( receivedFilesDirEdit_->text(),
                                                        this,
                                                        i18n( "Select Directory") ) );

  if( ! url.isEmpty() )
  {
    receivedFilesDirEdit_->setText( url.path() );
  }
}



#include "miscellaneouspage.moc"
