/*
    This file is part of Kontact.
    Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>

    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.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <qlabel.h>
#include <qlayout.h>
#include <qlineedit.h>
#include <qpushbutton.h>
#include <qspinbox.h>

#include <dcopref.h>
#include <kaboutdata.h>
#include <kaccelmanager.h>
#include <kconfig.h>
#include <kdebug.h>
#include <kdialogbase.h>
#include <klistview.h>
#include <klocale.h>

#include "kcmkontactknt.h"

extern "C"
{
  KCModule *create_kontactknt( QWidget *parent, const char * )
  {
    return new KCMKontactKNT( parent, "kcmkontactnt" );
  }
}

class NewsEditDialog : public KDialogBase
{
  public:
    NewsEditDialog( const QString &url, int count, QWidget *parent )
      : KDialogBase( Plain, i18n( "News Source Configuration" ), Ok | Cancel,
                     Ok, parent, 0, true, true )
    {
      QWidget *page = plainPage();
      QGridLayout *layout = new QGridLayout( page, 2, 3, marginHint(),
                                             spacingHint() );

      QLabel *label = new QLabel( i18n( "URL:" ), page );
      layout->addWidget( label, 0, 0 );

      mURL = new QLineEdit( page );
      label->setBuddy( mURL );
      layout->addMultiCellWidget( mURL, 0, 0, 1, 2 );

      label = new QLabel( i18n( "Number of articles:" ), page );
      layout->addWidget( label, 1, 0 );

      mCount = new QSpinBox( 1, 10, 1, page );
      label->setBuddy( mCount );
      layout->addMultiCellWidget( mCount, 1, 1, 1, 2 );

      mURL->setText( url );
      mCount->setValue( count );
    }

    QString url() const { return mURL->text(); }
    int count() const { return mCount->value(); }

  private:
    QLineEdit *mURL;
    QSpinBox *mCount;
};

class NewsItem : public QListViewItem
{
  public:
    NewsItem( QListView *parent, const QString& url, int count )
      : QListViewItem( parent ), mUrl( url ), mCount( count )
    {
    }

    void setUrl( const QString& url ) { mUrl = url; }
    QString url() const { return mUrl; }

    void setCount( int count ) { mCount = count; }
    int count() const { return mCount; }

    virtual QString text( int column ) const
    {
      if ( column == 0 )
        return mUrl;
      else if ( column == 1 )
        return QString::number( mCount );
      else
        return QListViewItem::text( column );
    }

  private:
    QString mUrl;
    int mCount;
};

KCMKontactKNT::KCMKontactKNT( QWidget *parent, const char *name )
  : KCModule( parent, name )
{
  QGridLayout *layout = new QGridLayout( this, 4, 2, KDialog::marginHint(),
                                         KDialog::spacingHint() );
  layout->setRowStretch( 3, 1 );
  layout->setColStretch( 0, 1 );

  mNewsView = new KListView( this );
  mNewsView->addColumn( i18n( "URL" ) );
  mNewsView->addColumn( i18n( "Number of Articles" ) );
  layout->addMultiCellWidget( mNewsView, 0, 3, 0, 0 );

  QPushButton *button = new QPushButton( i18n( "Add..." ), this );
  layout->addWidget( button, 0, 1 );

  mEditButton = new QPushButton( i18n( "Edit" ), this );
  mEditButton->setEnabled( false );
  layout->addWidget( mEditButton, 1, 1 );

  mRemoveButton = new QPushButton( i18n( "Remove" ), this );
  mRemoveButton->setEnabled( false );
  layout->addWidget( mRemoveButton, 2, 1 );

  connect( mNewsView, SIGNAL( selectionChanged( QListViewItem* ) ),
           this, SLOT( selectionChanged( QListViewItem* ) ) );
  connect( button, SIGNAL( clicked() ), this, SLOT( addNews() ) );
  connect( mEditButton, SIGNAL( clicked() ), this, SLOT( editNews() ) );
  connect( mRemoveButton, SIGNAL( clicked() ), this, SLOT( removeNews() ) );
  connect( mNewsView, SIGNAL( doubleClicked ( QListViewItem *, const QPoint &, int ) ),
           this, SLOT( editNews() ) );

  KAcceleratorManager::manage( this );

  load();
}

void KCMKontactKNT::addNews()
{
  NewsEditDialog dlg( "", 4, this );

  if ( dlg.exec() ) {
    if ( !dlg.url().isEmpty() && dlg.count() != 0 ) {
      new NewsItem( mNewsView, dlg.url(), dlg.count() );
      mNewsView->update();

      emit changed( true );
    }
  }
}

void KCMKontactKNT::editNews()
{
  NewsItem *item = dynamic_cast<NewsItem*>( mNewsView->currentItem() );
  if ( !item )
    return;

  NewsEditDialog dlg( item->url(), item->count(), this );
  if ( dlg.exec() ) {
    if ( !dlg.url().isEmpty() && dlg.count() != 0 ) {
      item->setUrl( dlg.url() );
      item->setCount( dlg.count() );
      mNewsView->update();

      emit changed( true );
    }
  }
}

void KCMKontactKNT::removeNews()
{
  QListViewItem *item = mNewsView->currentItem();
  mNewsView->takeItem( item );
  delete item;

  if ( mNewsView->childCount() == 0 )
    selectionChanged( 0 );

  emit changed( true );
}

void KCMKontactKNT::selectionChanged( QListViewItem *item )
{
  bool state = ( item != 0 );

  mEditButton->setEnabled( state );
  mRemoveButton->setEnabled( state );
}

void KCMKontactKNT::load()
{
  KConfig config( "kcmkontactkntrc" );

  mNewsView->clear();

  DCOPRef dcopCall( "rssservice", "RSSService" );
  QStringList urls = dcopCall.call( "list()" );

  if ( urls.count() == 0 ) {
    dcopCall.send( "add(QString)", "http://www.kde.org/dotkdeorg.rdf" );
    urls = dcopCall.call( "list()" );
  }

  QStringList::Iterator it;
  for ( it = urls.begin(); it != urls.end(); ++it ) {
    config.setGroup( *it );
    int count = config.readNumEntry( "NumArticles", 4 );

    new NewsItem( mNewsView, *it, count );
  }

  emit changed( false );
}

void KCMKontactKNT::save()
{
  KConfig config( "kcmkontactkntrc" );
  DCOPRef dcopCall( "rssservice", "RSSService" );

  // remove all old url entries first
  QStringList oldUrls = dcopCall.call( "list()" );

  // add the new one...
  QListViewItemIterator it( mNewsView );
  while ( it.current() ) {
    NewsItem *item = dynamic_cast<NewsItem*>( it.current() );

    if ( !oldUrls.contains( item->url() ) )
      dcopCall.call( "add(QString)", item->url() );

    config.setGroup( item->url() );
    config.writeEntry( "NumArticles", item->count() );

    oldUrls.remove( item->url() );

    ++it;
  }

  for ( uint i = 0; i < oldUrls.count(); ++i ) {
    dcopCall.call( "remove(QString)", oldUrls[ i ] );
    config.deleteGroup( oldUrls[ i ] );
  }

  config.sync();

  emit changed( false );
}

void KCMKontactKNT::defaults()
{
  mNewsView->clear();
  new NewsItem( mNewsView, "http://www.kde.org/dotkdeorg.rdf", 4 );

  emit changed( true );
}

const KAboutData* KCMKontactKNT::aboutData() const
{
  KAboutData *about = new KAboutData( I18N_NOOP( "kcmkontactknt" ),
                                      I18N_NOOP( "Newsticker Configuration Dialog" ),
                                      0, 0, KAboutData::License_GPL,
                                      I18N_NOOP( "(c), 2003 Tobias Koenig" ) );

  about->addAuthor( "Tobias Koenig", 0, "tokoe@kde.org" );

  return about;
}

#include "kcmkontactknt.moc"
