/*
    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 <qlayout.h>
#include <qpixmap.h>
#include <qhbox.h>

#include <dcopclient.h>
#include <kapplication.h>
#include <kconfig.h>
#include <kdebug.h>
#include <klocale.h>
#include <kurllabel.h>

#include "summarywidget.h"

SummaryWidget::SummaryWidget( QWidget *parent, const char *name )
  : Kontact::Summary( parent, name ),
    DCOPObject( "NewsTickerPlugin" ), mServiceAvailable( true ), mLayout( 0 )
{
  QVBoxLayout *vlay = new QVBoxLayout( this );

  mBaseWidget = new QWidget( this, "baseWidget" );
  vlay->addWidget( mBaseWidget );

  QString error;
  QCString appID;

  if ( !kapp->dcopClient()->isApplicationRegistered( "rssservice" ) ) {
    if ( KApplication::startServiceByDesktopName( "rssservice", QStringList(), &error, &appID ) ) {
      kdDebug() << "No service available..." << endl;
      mServiceAvailable = false;
    }
  }

  connectDCOPSignal( 0, 0, "added(QString)", "documentAdded(QString)", false );
  connectDCOPSignal( 0, 0, "removed(QString)", "documentRemoved(QString)", false );

  updateDocuments();
}

void SummaryWidget::documentAdded( QString )
{
  updateDocuments();
}

void SummaryWidget::documentRemoved( QString )
{
  updateDocuments();
}

void SummaryWidget::configChanged()
{
  updateView();
}

void SummaryWidget::updateDocuments()
{
  mFeeds.clear();

  if ( mServiceAvailable ) {
    DCOPRef dcopCall( "rssservice", "RSSService" );
    QStringList urls;
    dcopCall.call( "list()" ).get( urls );

    if ( urls.isEmpty() ) { // add default
      urls.append( "http://www.kde.org/dotkdeorg.rdf" );
      dcopCall.send( "add(QString)", urls[ 0 ] );
    }

    QStringList::Iterator it;
    for ( it = urls.begin(); it != urls.end(); ++it ) {
      DCOPRef docRef = dcopCall.call( "document(QString)", *it );

      Feed feed;
      feed.ref = docRef;
      feed.url = *it;
      mFeeds.append( feed );

      connectDCOPSignal( "rssservice", docRef.obj(), "documentUpdated(DCOPRef)",
                         "documentUpdated(DCOPRef)", false );

      docRef.send( "refresh()" );
    }

    connect( &mTimer, SIGNAL( timeout() ), this, SLOT( timeout() ) );
    mTimer.start( 30 * 1000 );
  }
}

void SummaryWidget::documentUpdated( DCOPRef docRef )
{
  ArticleMap map;

  int numArticles = docRef.call( "count()" );
  for ( int i = 0; i < numArticles; ++i ) {
    DCOPRef artRef = docRef.call( "article(int)", i );
    QString title, url;

    artRef.call( "title()" ).get( title );
    artRef.call( "link()" ).get( url );
    QPair<QString, KURL> article(title, url);
    map.append( article );
  }

  bool found = false;
  QValueList<Feed>::Iterator it;
  for ( it = mFeeds.begin(); it != mFeeds.end(); ++it ) {
    if ( (*it).ref.obj() == docRef.obj() ) {
      (*it).map = map;
      found = true;
      break;
    }
  }

  if ( !found ) {
    Feed feed;
    feed.ref = docRef;
    feed.map = map;
    feed.url = "";
    mFeeds.append( feed );
  }

  updateView();
}

void SummaryWidget::timeout()
{
  mTimer.stop();

  QValueList<Feed>::Iterator it;
  for ( it = mFeeds.begin(); it != mFeeds.end(); ++it ) {
    DCOPRef docRef = (*it).ref;
    docRef.send( "refresh()" );
  }

  mTimer.start( 180 * 1000 );
}

void SummaryWidget::updateView()
{
  KConfig config( "kcmkontactkntrc" );

  mLabels.setAutoDelete( true );
  mLabels.clear();
  mLabels.setAutoDelete( false );

  delete mLayout;
  mLayout = new QVBoxLayout( mBaseWidget, 3 );

  QFont boldFont;
  boldFont.setBold( true );
  boldFont.setPointSize( boldFont.pointSize() + 2 );

  QValueList<Feed>::Iterator it;
  for ( it = mFeeds.begin(); it != mFeeds.end(); ++it ) {
    DCOPRef docRef = (*it).ref;

    QHBox *hbox = new QHBox( mBaseWidget );
    mLayout->addWidget( hbox );
    hbox->show();

    // icon
    KURLLabel *urlLabel = new KURLLabel( hbox );
    urlLabel->setURL( docRef.call( "link()" ) );
    urlLabel->setPixmap( docRef.call( "pixmap()" ) );
    mLabels.append( urlLabel );

    connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ),
             kapp, SLOT( invokeBrowser( const QString& ) ) );

    // header
    QLabel *label = new QLabel( hbox );
    label->setText( docRef.call( "title()" ) );
    label->setAlignment( AlignLeft|AlignVCenter );
    label->setTextFormat( RichText );
    label->setFont( boldFont );
    label->setIndent( 6 );
    label->setSizePolicy( QSizePolicy::MinimumExpanding,
                          QSizePolicy::Preferred );
    mLabels.append( label );

    // max article count
    config.setGroup( (*it).url );
    int maxArticles = config.readNumEntry( "NumArticles", 4 );

    // articles
    ArticleMap articles = (*it).map;
    ArticleMap::Iterator artIt;
    int numArticles = 0;
    for ( artIt = articles.begin(); artIt != articles.end() && numArticles < maxArticles; ++artIt ) {
      urlLabel = new KURLLabel( (*artIt).second.url(), (*artIt).first, mBaseWidget );
      mLabels.append( urlLabel );
      mLayout->addWidget( urlLabel );

      connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ),
               kapp, SLOT( invokeBrowser( const QString& ) ) );

      numArticles++;
    }
  }
  mLayout->addStretch();

  for ( QLabel *label = mLabels.first(); label; label = mLabels.next() )
    label->show();

}

QStringList SummaryWidget::configModules() const
{
  return "kcmkontactknt.desktop";
}

#include "summarywidget.moc"
