#ifndef KDE_USE_FINAL
#define QT_NO_CAST_ASCII
#endif
// configuredialog_p.cpp: classes internal to ConfigureDialog
// see configuredialog.cpp for details.


// my header:
#include "configuredialog_p.h"

// other KMail headers:
#include "globalsettings.h"
#include "kmacctcachedimap.h"

// other kdenetwork headers: (none)

// other KDE headers:
#include <kconfig.h>
#include <kcombobox.h>
#include <kstandarddirs.h>
#include <ktabwidget.h>
#include <klocale.h>
#include <kdebug.h>
#include <kconfiggroup.h>
#include <kbuttongroup.h>
#include <kpimidentities/identitymanager.h>

// Qt headers:
#include <QRadioButton>
#include <QLabel>
#include <QHBoxLayout>
#include <QShowEvent>
#include <QVBoxLayout>
#include <QResizeEvent>

// Other headers:
#include <assert.h>


NewIdentityDialog::NewIdentityDialog( const QStringList & identities,
                                      QWidget *parent )
  : KDialog( parent )
{
  setCaption( i18n("New Identity") );
  setButtons( Ok|Cancel|Help );
  setHelp( QString::fromLatin1("configure-identity-newidentitydialog") );
  QWidget *page = new QWidget( this );
  setMainWidget( page );
  QVBoxLayout * vlay = new QVBoxLayout( page );
  vlay->setSpacing( spacingHint() );
  vlay->setMargin( 0 );

  // row 0: line edit with label
  QHBoxLayout * hlay = new QHBoxLayout(); // inherits spacing
  vlay->addLayout( hlay );
  mLineEdit = new KLineEdit( page );
  mLineEdit->setFocus();
  mLineEdit->setClearButtonShown( true );
  QLabel *l = new QLabel( i18n("&New identity:"), page );
  l->setBuddy( mLineEdit );
  hlay->addWidget( l );
  hlay->addWidget( mLineEdit, 1 );
  connect( mLineEdit, SIGNAL(textChanged(const QString&)),
           this, SLOT(slotEnableOK(const QString&)) );

  mButtonGroup = new QButtonGroup( page );

  // row 1: radio button
  QRadioButton *radio = new QRadioButton( i18n("&With empty fields"), page );
  radio->setChecked( true );
  vlay->addWidget( radio );
  mButtonGroup->addButton( radio, (int)Empty );

  // row 2: radio button
  radio = new QRadioButton( i18n("&Use Control Center settings"), page );
  vlay->addWidget( radio );
  mButtonGroup->addButton( radio, (int)ControlCenter );

  // row 3: radio button
  radio = new QRadioButton( i18n("&Duplicate existing identity"), page );
  vlay->addWidget( radio );
  mButtonGroup->addButton( radio, (int)ExistingEntry );

  // row 4: combobox with existing identities and label
  hlay = new QHBoxLayout(); // inherits spacing
  vlay->addLayout( hlay );
  mComboBox = new KComboBox( page );
  mComboBox->setEditable( false );
  mComboBox->addItems( identities );
  mComboBox->setEnabled( false );
  QLabel *label = new QLabel( i18n("&Existing identities:"), page );
  label->setBuddy( mComboBox );
  label->setEnabled( false );
  hlay->addWidget( label );
  hlay->addWidget( mComboBox, 1 );

  vlay->addStretch( 1 ); // spacer

  // enable/disable combobox and label depending on the third radio
  // button's state:
  connect( radio, SIGNAL(toggled(bool)),
           label, SLOT(setEnabled(bool)) );
  connect( radio, SIGNAL(toggled(bool)),
           mComboBox, SLOT(setEnabled(bool)) );

  enableButtonOk( false ); // since line edit is empty
}

NewIdentityDialog::DuplicateMode NewIdentityDialog::duplicateMode() const {
  int id = mButtonGroup->checkedId();
  assert( id == (int)Empty
          || id == (int)ControlCenter
          || id == (int)ExistingEntry );
  return static_cast<DuplicateMode>( id );
}

void NewIdentityDialog::slotEnableOK( const QString & proposedIdentityName ) {
  // OK button is disabled if
  QString name = proposedIdentityName.trimmed();
  // name isn't empty
  if ( name.isEmpty() ) {
    enableButtonOk( false );
    return;
  }
  // or name doesn't yet exist.
  if ( ! kmkernel->identityManager()->isUnique( name ) ) {
    enableButtonOk( false );
    return;
  }
  enableButtonOk( true );
}

ListView::ListView( QWidget *parent )
  : QTreeWidget( parent )
{
  setAllColumnsShowFocus( true );
  setAlternatingRowColors( true );
  setSelectionMode( QAbstractItemView::SingleSelection );
  setRootIsDecorated( false );
}


void ListView::resizeEvent( QResizeEvent *e )
{
  QTreeWidget::resizeEvent(e);
  resizeColums();
}


void ListView::showEvent( QShowEvent *e )
{
  QTreeWidget::showEvent(e);
  resizeColums();
}


void ListView::resizeColums()
{
  int c = columnCount();
  if( c == 0 )
  {
    return;
  }

  int w1 = viewport()->width();
  int w2 = w1 / c;
  int w3 = w1 - (c-1)*w2;

  for( int i=0; i<c-1; i++ )
  {
    setColumnWidth( i, w2 );
  }
  setColumnWidth( c-1, w3 );
}

QSize ListView::sizeHint() const
{
  QSize s = QTreeWidget::sizeHint();

  // FIXME indentation is horizontal distance
  /*int h = fontMetrics().height() + 2*indentation();
  if( h % 2 > 0 ) { h++; }

  s.setHeight( h*mVisibleItem + lineWidth()*2 + header()->sizeHint().height());*/
  return s;
}

//
//
//  ProfileDialog
//
//

ProfileDialog::ProfileDialog( QWidget * parent )
  : KDialog( parent )
{
  setCaption( i18n("Load Profile") );
  setButtons( Ok|Cancel );
  // tmp. vars:
  QWidget *page = new QWidget( this );
  setMainWidget( page );
  QVBoxLayout * vlay = new QVBoxLayout( page );
  vlay->setSpacing( spacingHint() );
  vlay->setMargin( 0 );

  mListView = new QTreeWidget( page );
  mListView->setObjectName( "mListView" );
  mListView->setHeaderLabels( 
    QStringList () << i18n("Available Profiles") << i18n("Description") 
  );
  mListView->setAllColumnsShowFocus( true );
  mListView->setSortingEnabled( false );
  mListView->setRootIsDecorated( false );
  mListView->setSelectionMode( QAbstractItemView::SingleSelection );

  QLabel *l = new QLabel( i18n("&Select a profile and click 'OK' to "
                               "load its settings:"), page );
  l->setBuddy( mListView );
  vlay->addWidget( l );
  vlay->addWidget( mListView, 1 );

  setup();

  connect( mListView, SIGNAL(itemSelectionChanged()),
           SLOT(slotSelectionChanged()) );
  /* FIXME The dialog does not close when double click an item, but 
   * the profile is selected. If the user clicks on Cancel after double
   * click he has changed the profile.
   */
  //connect( mListView, SIGNAL(itemDoubleClicked ( QTreeWidgetItem*, int ) ),
  //   SLOT(slotOk()) );

  connect( this, SIGNAL(finished()), SLOT(deleteLater()) );
  connect( this, SIGNAL(okClicked()), SLOT( slotOk() ) );

  enableButtonOk( false );
}

void ProfileDialog::slotSelectionChanged()
{
  enableButtonOk( mListView->currentItem() );
}

void ProfileDialog::setup() {
  mListView->clear();
  // find all profiles (config files named "profile-xyz-rc"):
  const QString profileFilenameFilter = QString::fromLatin1("kmail/profile-*-rc");
  mProfileList = KGlobal::dirs()->findAllResources( "data", profileFilenameFilter );

  kDebug() << "Profile manager: found" << mProfileList.count()
               << "profiles:";

  // build the list and populate the list view:
  QTreeWidgetItem * listItem = 0;
  for ( QStringList::const_iterator it = mProfileList.constBegin() ;
        it != mProfileList.constEnd() ; ++it ) {
    KConfig _profile( *it, KConfig::NoGlobals  );
    KConfigGroup profile(&_profile, "KMail Profile");
    QString name = profile.readEntry( "Name" );
    if ( name.isEmpty() ) {
      kWarning() << "File \"" << (*it)
                     << "\" doesn't provide a profile name!";
      name = i18nc("Missing profile name placeholder","Unnamed");
    }
    QString desc = profile.readEntry( "Comment" );
    if ( desc.isEmpty() ) {
      kWarning() << "File \"" << (*it)
                     << "\" doesn't provide a description!";
      desc = i18nc("Missing profile description placeholder","Not available");
    }
    listItem = new QTreeWidgetItem( mListView, listItem );
    listItem->setText( 0, name );
    listItem->setText( 1, desc );
  }
}

void ProfileDialog::slotOk() {
  if ( !mListView->currentItem() )
    return; // none selected

  const int index = mListView->indexOfTopLevelItem( mListView->currentItem() );
  if ( index < 0 )
    return; // none selected

  assert( index < mProfileList.count() );

  KConfig profile( mProfileList.at( index), KConfig::NoGlobals );
  emit profileSelected( &profile );
}


ConfigModuleWithTabs::ConfigModuleWithTabs( const KComponentData &instance, QWidget *parent )
  : ConfigModule( instance, parent )
{
  QVBoxLayout *vlay = new QVBoxLayout( this );
  vlay->setSpacing( KDialog::spacingHint() );
  vlay->setMargin( 0 );
  mTabWidget = new KTabWidget( this );
  vlay->addWidget( mTabWidget );
}

void ConfigModuleWithTabs::addTab( ConfigModuleTab* tab, const QString & title ) {
  mTabWidget->addTab( tab, title );
  connect( tab, SIGNAL(changed( bool )),
           this, SIGNAL(changed( bool )) );
}

void ConfigModuleWithTabs::load() {
  for ( int i = 0 ; i < mTabWidget->count() ; ++i ) {
    ConfigModuleTab *tab = dynamic_cast<ConfigModuleTab*>( mTabWidget->widget(i) );
    if ( tab )
      tab->load();
  }
  KCModule::load();
}

void ConfigModuleWithTabs::save() {
  KCModule::save();
   for ( int i = 0 ; i < mTabWidget->count() ; ++i ) {
    ConfigModuleTab *tab = dynamic_cast<ConfigModuleTab*>( mTabWidget->widget(i) );
    if ( tab )
      tab->save();
  }
}

void ConfigModuleWithTabs::defaults() {
  ConfigModuleTab *tab = dynamic_cast<ConfigModuleTab*>( mTabWidget->currentWidget() );
  if ( tab )
    tab->defaults();
  KCModule::defaults();
}

void ConfigModuleWithTabs::installProfile( KConfig *profile ) {
  for ( int i = 0 ; i < mTabWidget->count() ; ++i ) {
    ConfigModuleTab *tab = dynamic_cast<ConfigModuleTab*>( mTabWidget->widget(i) );
    if ( tab )
      tab->installProfile( profile );
  }
}

void ConfigModuleTab::load()
{
  doLoadFromGlobalSettings();
  doLoadOther();
}

void ConfigModuleTab::defaults()
{
  // reset settings which are available via GlobalSettings to their defaults
  // (stolen from KConfigDialogManager::updateWidgetsDefault())
  const bool bUseDefaults = GlobalSettings::self()->useDefaults( true );
  doLoadFromGlobalSettings();
  GlobalSettings::self()->useDefaults( bUseDefaults );
  // reset other settings to default values
  doResetToDefaultsOther();
}

void ConfigModuleTab::slotEmitChanged( void ) {
   emit changed( true );
}


#include "configuredialog_p.moc"
