/***************************************************************************
 *   Copyright (C) 2004-2009 by Thomas Fischer                             *
 *   fischer@unix-ag.uni-kl.de                                             *
 *                                                                         *
 *   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.             *
 ***************************************************************************/
#include <qlabel.h>
#include <qlayout.h>
#include <qregexp.h>
#include <qbuffer.h>
#include <qcstring.h>
#include <qiodevice.h>
#include <qspinbox.h>
#include <qcheckbox.h>
#include <qfile.h>
#include <qdatetime.h>

#include <klocale.h>
#include <kmessagebox.h>
#include <kio/netaccess.h>
#include <klineedit.h>
#include <kcombobox.h>
#include <kpushbutton.h>
#include <kiconloader.h>

#include <settings.h>
#include "webquerycsb.h"

namespace KBibTeX
{
    WebQueryCSBWidget::WebQueryCSBWidget( QWidget *parent, const char *name )
            : WebQueryWidget( parent, name )
    {
        init();

        Settings *settings = Settings::self();
        QString value = settings->getWebQueryDefault( "CSB_query" );
        value = value == QString::null ? "" : value;
        lineEditQuery->setText( value );
        value = settings->getWebQueryDefault( "CSB_field" );
        value = value == QString::null || value.isEmpty() ? "0" : value;
        comboBoxField->setCurrentItem( value.toInt() );
        value = settings->getWebQueryDefault( "CSB_yearCheck" );
        value = value == QString::null || value.isEmpty() ? "0" : value;
        checkBoxYear->setChecked( value == "1" );
        value = settings->getWebQueryDefault( "CSB_yearType" );
        value = value == QString::null || value.isEmpty() ? "0" : value;
        comboBoxYear->setCurrentItem( value.toInt() );
        value = settings->getWebQueryDefault( "CSB_yearValue" );
        value = value == QString::null ? "2000" : value;
        spinBoxYear->setValue( value.toInt() );
        value = settings->getWebQueryDefault( "CSB_sortBy" );
        value = value == QString::null || value.isEmpty() ? "0" : value;
        comboBoxSortBy->setCurrentItem( value.toInt() );
        value = settings->getWebQueryDefault( "CSB_onlinePapersOnly" );
        value = value == QString::null || value.isEmpty() ? "0" : value;
        checkBoxOnlinePapersOnly->setChecked( value == "1" );
        slotTextChanged( value, true );
    }

    void WebQueryCSBWidget::init()
    {
        QVBoxLayout *vLayout = new QVBoxLayout( this, 0, KDialog::spacingHint() );

        QHBoxLayout *hLayout = new QHBoxLayout( );
        vLayout->addLayout( hLayout );
        KPushButton *clearSearchText = new KPushButton( this );
        clearSearchText->setIconSet( QIconSet( SmallIcon( "locationbar_erase" ) ) );
        hLayout->addWidget( clearSearchText );
        QLabel *label = new QLabel( i18n( "Search &term:" ), this );
        hLayout->addWidget( label );
        lineEditQuery = new KLineEdit( this );
        KCompletion *completionQuery = lineEditQuery->completionObject();
        hLayout->addWidget( lineEditQuery );
        label->setBuddy( lineEditQuery );
        hLayout->addSpacing( KDialog::spacingHint() * 2 );
        label = new QLabel( i18n( "Here, \"Field\" refers to a parameter for the CSB search (author, title, any)", "&Field:" ), this );
        hLayout->addWidget( label );
        comboBoxField = new KComboBox( false, this );
        hLayout->addWidget( comboBoxField );
        label->setBuddy( comboBoxField );
        connect( clearSearchText, SIGNAL( clicked() ), lineEditQuery, SLOT( clear() ) );
        connect( lineEditQuery, SIGNAL( textChanged( const QString& ) ), this, SLOT( slotTextChanged( const QString& ) ) );
        hLayout->setStretchFactor( lineEditQuery, 5 );
        connect( lineEditQuery, SIGNAL( returnPressed() ), this, SIGNAL( startSearch() ) );
        connect( lineEditQuery, SIGNAL( returnPressed( const QString& ) ), completionQuery, SLOT( addItem( const QString& ) ) );

        hLayout = new QHBoxLayout( );
        vLayout->addLayout( hLayout );
        label = new QLabel( i18n( "&Number of results:" ), this );
        hLayout->addWidget( label );
        spinBoxMaxHits = new QSpinBox( 1, 500, 1, this );
        spinBoxMaxHits->setValue( 10 );
        hLayout->setStretchFactor( spinBoxMaxHits, 3 );
        hLayout->addWidget( spinBoxMaxHits );
        label->setBuddy( spinBoxMaxHits );
        hLayout->addSpacing( KDialog::spacingHint() * 2 );
        checkBoxYear = new QCheckBox( i18n( "&Year:" ), this );
        hLayout->setStretchFactor( checkBoxYear, 1 );
        checkBoxYear->setChecked( true );
        hLayout->addWidget( checkBoxYear );
        connect( checkBoxYear, SIGNAL( toggled( bool ) ), this, SLOT( slotYearCheckToggled() ) );
        comboBoxYear = new KComboBox( false, this );
        hLayout->setStretchFactor( comboBoxYear, 3 );
        hLayout->addWidget( comboBoxYear );
        spinBoxYear = new QSpinBox( 1800, 2100, 1, this );
        spinBoxYear->setValue( QDate::currentDate().year() );
        hLayout->setStretchFactor( spinBoxYear, 6 );
        hLayout->addWidget( spinBoxYear );

        hLayout->addSpacing( KDialog::spacingHint() * 2 );
        label = new QLabel( i18n( "Sort &by:" ), this );
        hLayout->addWidget( label );
        comboBoxSortBy = new KComboBox( false, this );
        hLayout->setStretchFactor( comboBoxSortBy, 8 );
        hLayout->addWidget( comboBoxSortBy );
        label->setBuddy( comboBoxSortBy );

        hLayout = new QHBoxLayout( );
        vLayout->addLayout( hLayout );
        checkBoxOnlinePapersOnly = new QCheckBox( i18n( "Online papers only" ), this );
        hLayout->addWidget( checkBoxOnlinePapersOnly );

        comboBoxField->insertItem( i18n( "any" ) );
        comboBoxField->insertItem( i18n( "author" ) );
        comboBoxField->insertItem( i18n( "title" ) );
        comboBoxYear->insertItem( i18n( "exact" ) );
        comboBoxYear->insertItem( i18n( "until" ) );
        comboBoxYear->insertItem( i18n( "from" ) );
        comboBoxYear->setCurrentItem( 1 );
        comboBoxSortBy->insertItem( i18n( "none" ) );
        comboBoxSortBy->insertItem( i18n( "score" ) );
        comboBoxSortBy->insertItem( i18n( "year" ) );
    }

    void WebQueryCSBWidget::slotYearCheckToggled()
    {
        bool yearEnabled = checkBoxYear->isChecked();
        comboBoxYear->setEnabled( yearEnabled );
        spinBoxYear->setEnabled( yearEnabled );
    }

    WebQueryCSB::WebQueryCSB( QWidget* parent ): WebQuery( parent )
    {
        m_importer = new BibTeX::FileImporterBibTeX( FALSE );
        m_importer->setIgnoreComments( TRUE );
        m_widget = new WebQueryCSBWidget( parent );
    }

    WebQueryCSB::~WebQueryCSB()
    {
        delete m_widget;
        delete m_importer;
    }

    QString WebQueryCSB::title()
    {
        return i18n( "Computer Science Bibliographies" );
    }

    QString WebQueryCSB::disclaimer()
    {
        return i18n( "Copyright for the Bibliography Collection" );
    }

    QString WebQueryCSB::disclaimerURL()
    {
        return "http://liinwww.ira.uka.de/bibliography/Copyright.html";
    }

    WebQueryWidget *WebQueryCSB::widget()
    {
        return m_widget;
    }

    void WebQueryCSB::query()
    {
        WebQuery::query();

        Settings *settings = Settings::self();
        settings->setWebQueryDefault( "CSB_query", m_widget->lineEditQuery->text() );
        settings->setWebQueryDefault( "CSB_field", QString::number( m_widget->comboBoxField->currentItem() ) );
        settings->setWebQueryDefault( "CSB_yearCheck", m_widget->checkBoxYear->isChecked() ? "1" : "0" );
        settings->setWebQueryDefault( "CSB_yearType", QString::number( m_widget->comboBoxYear->currentItem() ) );
        settings->setWebQueryDefault( "CSB_yearValue", QString::number( m_widget->spinBoxYear->value() ) );
        settings->setWebQueryDefault( "CSB_sortBy", QString::number( m_widget->comboBoxSortBy->currentItem() ) );
        settings->setWebQueryDefault( "CSB_onlinePapersOnly", m_widget->checkBoxOnlinePapersOnly->isChecked() ? "1" : "0" );

        setNumStages( 1 );

        int numberOfResults = m_widget->spinBoxMaxHits->value();
        QString searchTerm = m_widget->lineEditQuery->text().stripWhiteSpace().replace( '$', "" );

        QString year;
        if ( m_widget->checkBoxYear->isChecked() )
        {
            switch ( m_widget->comboBoxYear->currentItem() )
            {
            case 1: year = QString( "before=%1" ).arg( m_widget->spinBoxYear->value() ); break;
            case 2: year = QString( "since=%1" ).arg( m_widget->spinBoxYear->value() ); break;
            default: year = QString( "year=%1" ).arg( m_widget->spinBoxYear->value() ); break;
            }
        }

        QString field;
        switch ( m_widget->comboBoxField->currentItem() )
        {
        case 1: field = "au"; break;
        case 2: field = "ti"; break;
        default: field = ""; break;
        }

        QString sortBy;
        switch ( m_widget->comboBoxSortBy->currentItem() )
        {
        case 1: sortBy = "&sort=score"; break;
        case 2: sortBy = "&sort=year"; break;
        default: sortBy = ""; break;
        }

        QString onlinePapersOnly = m_widget->checkBoxOnlinePapersOnly->isChecked() ? "&online=on" : "";

        KURL url = KURL( QString( "http://liinwww.ira.uka.de/csbib?query=%4&results=bibtex&maxnum=%1&%2&field=%3" ).arg( numberOfResults ).arg( year ).arg( field ).arg( searchTerm.replace( "%", "%25" ).replace( "+", "%2B" ).replace( " ", "%20" ).replace( "#", "%23" ).replace( "&", "%26" ).replace( "?", "%3F" ) ).append( onlinePapersOnly ).append( sortBy ) );

        QString rawText = download( url );
        if ( rawText != NULL && !m_aborted )
        {
            QRegExp removeXML( "<[^>]+>" );
            rawText.replace( removeXML, "" );

            BibTeX::FileImporterBibTeX importer( FALSE );
            importer.setIgnoreComments( TRUE );
            QBuffer buffer;

            buffer.open( IO_WriteOnly );
            QTextStream ts( &buffer );
            ts.setEncoding( QTextStream::UnicodeUTF8 );
            ts << rawText << endl;
            buffer.close();

            buffer.open( IO_ReadOnly );
            BibTeX::File *tmpBibFile = importer.load( &buffer );
            buffer.close();

            if ( tmpBibFile != NULL && tmpBibFile->count() > 0 )
            {
                for ( BibTeX::File::ElementList::iterator it = tmpBibFile->begin(); !m_aborted && it != tmpBibFile->end(); ++it )
                {
                    BibTeX::Entry *entry = dynamic_cast<BibTeX::Entry*>( *it );
                    if ( entry != NULL )
                        emit foundEntry( new BibTeX::Entry( entry ), false );
                }

                setEndSearch( WebQuery::statusSuccess );
            }
            else
                setEndSearch( WebQuery::statusError );

            if ( tmpBibFile != NULL )
                delete tmpBibFile;
        }
        else if ( !m_aborted )
        {
            QString message = KIO::NetAccess::lastErrorString();
            if ( message.isEmpty() )
                message.prepend( '\n' );
            message.prepend( QString( i18n( "Querying database '%1' failed." ) ).arg( title() ) );
            KMessageBox::error( m_parent, message );
            setEndSearch( WebQuery::statusError );
        }
        else
            setEndSearch( WebQuery::statusAborted );
    }

}
#include "webquerycsb.moc"
