//////////////////////////////////////////////////////////////////////////
// mainWidget.cpp                                                       //
//                                                                      //
// Copyright (C)  2005  Lukas Tinkl <lukas@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., 51 Franklin Street, Fifth Floor, Boston, MA            //
// 02110-1301, USA.                                                     //
//////////////////////////////////////////////////////////////////////////

#include "mainWidget.h"
#include "tagListItem.h"
#include "bookmarkListItem.h"

#include <tqlistview.h>
#include <tqdom.h>
#include <tqpopupmenu.h>
#include <tqpushbutton.h>
#include <tqtimer.h>
#include <tqdatetime.h>

#include <kdebug.h>
#include <tdeio/job.h>
#include <krfcdate.h>
#include <tdelistview.h>
#include <tdelocale.h>
#include <tdeglobal.h>
#include <kiconloader.h>
#include <tdemessagebox.h>
#include <tdeconfig.h>
#include <kinputdialog.h>

MainWidget::MainWidget( TDEConfig * config, TQWidget * parent )
    : MainWidget_base( parent ), m_config( config )
{
    loadTags();

    TDEIconLoader * il = TDEGlobal::iconLoader();

    btnRefreshTags->setIconSet( il->loadIconSet( "reload", TDEIcon::Small ) );
    btnRefreshBookmarks->setIconSet( il->loadIconSet( "reload", TDEIcon::Small ) );
    btnNew->setIconSet( il->loadIconSet( "bookmark_add", TDEIcon::Small ) );

    connect( ( TQWidget * ) btnRefreshTags, TQ_SIGNAL( clicked() ),
             this, TQ_SLOT( slotGetTags() ) );

    connect( ( TQWidget * ) btnRefreshBookmarks, TQ_SIGNAL( clicked() ),
             this, TQ_SLOT( slotGetBookmarks() ) );

    connect( ( TQWidget * ) btnNew, TQ_SIGNAL( clicked() ),
             this, TQ_SLOT( slotNewBookmark() ) );

    connect( lvBookmarks, TQ_SIGNAL( executed( TQListViewItem * ) ),
             this, TQ_SLOT( slotBookmarkExecuted( TQListViewItem * ) ) );
    connect( lvBookmarks, TQ_SIGNAL( mouseButtonClicked ( int, TQListViewItem *, const TQPoint &, int ) ),
             this, TQ_SLOT( slotBookmarkClicked( int, TQListViewItem *, const TQPoint &, int ) ) );

    connect( lvTags, TQ_SIGNAL( contextMenuRequested( TQListViewItem *, const TQPoint &, int ) ),
             this, TQ_SLOT( slotTagsContextMenu( TQListViewItem *, const TQPoint &, int ) ) );

    connect( lvBookmarks, TQ_SIGNAL( contextMenuRequested( TQListViewItem *, const TQPoint &, int ) ),
             this, TQ_SLOT( slotBookmarksContextMenu( TQListViewItem *, const TQPoint &, int ) ) );

    m_updateTimer = new TQTimer( this );
    connect( m_updateTimer, TQ_SIGNAL( timeout() ), TQ_SLOT( slotGetBookmarks() ) );

    slotGetTags();
}

MainWidget::~MainWidget()
{
    saveTags();
}

void MainWidget::setCurrentURL( const KURL & url )
{
    m_currentURL = url;
}

void MainWidget::slotGetTags()
{
    kdDebug() << k_funcinfo << endl;

    TDEIO::StoredTransferJob * job = TDEIO::storedGet( "http://del.icio.us/api/tags/get" );
    connect( job, TQ_SIGNAL( result( TDEIO::Job * ) ),
             this, TQ_SLOT( slotFillTags( TDEIO::Job * ) ) );
}

void MainWidget::slotFillTags( TDEIO::Job * job )
{
    kdDebug() << k_funcinfo << endl;

    if ( job->error() )
    {
        job->showErrorDialog( this );
        return;
    }

    lvTags->clear();
    m_tags.clear();

    // fill lvTags with job->data()
    TQDomDocument doc;
    doc.setContent( static_cast<TDEIO::StoredTransferJob *>( job )->data() );
    TQDomNodeList tags = doc.elementsByTagName( "tag" );
    for ( uint i = 0; i < tags.length(); ++i )
    {
        TQDomElement tag = tags.item( i ).toElement();
        if ( !tag.isNull() )
        {
            TagListItem *item = new TagListItem( lvTags, tag.attribute( "tag" ), tag.attribute( "count" ).toInt() );
            m_tags.append( tag.attribute( "tag" ) );
            connect( item, TQ_SIGNAL( signalItemChecked( TagListItem * ) ), TQ_SLOT( itemToggled() ) );
        }
    }
}

void MainWidget::slotGetBookmarks()
{
    KURL url( "http://del.icio.us/api/posts/recent" );
    url.setQuery( "tag=" + checkedTags().join( " " ) );

    kdDebug() << k_funcinfo << url.url() << endl;

    TDEIO::StoredTransferJob * job = TDEIO::storedGet( url );
    connect( job, TQ_SIGNAL( result( TDEIO::Job * ) ),
             this, TQ_SLOT( slotFillBookmarks( TDEIO::Job * ) ) );
}

void MainWidget::slotFillBookmarks( TDEIO::Job * job )
{
    kdDebug() << k_funcinfo << endl;

    if ( job->error() )
    {
        job->showErrorDialog( this );
        return;
    }

    lvBookmarks->clear();

    // fill lvBookmarks with job->data()
    TQDomDocument doc;
    doc.setContent( static_cast<TDEIO::StoredTransferJob *>( job )->data() );
    TQDomNodeList posts = doc.elementsByTagName( "post" );

    for ( uint i = 0; i < posts.length(); ++i )
    {
        TQDomElement post = posts.item( i ).toElement();
        if ( !post.isNull() )
        {
            new BookmarkListItem( lvBookmarks, post.attribute( "href" ), post.attribute( "description" ),
                                  KRFCDate::parseDateISO8601( post.attribute( "time" ) ) );
        }
    }
}

TQStringList MainWidget::checkedTags() const
{
    TQListViewItemIterator it( lvTags, TQListViewItemIterator::Visible | TQListViewItemIterator::Checked );

    TQStringList tmp;

    while ( it.current() )
    {
        tmp.append( it.current()->text( 0 ) );
        ++it;
    }

    return tmp;
}

void MainWidget::slotBookmarkExecuted( TQListViewItem * item )
{
    BookmarkListItem * bookmark = static_cast<BookmarkListItem *>( item );
    if ( bookmark )
    {
        kdDebug() << k_funcinfo << "Clicked bookmark URL: " << bookmark->url()  << endl;
        emit signalURLClicked( bookmark->url() );
    }
}

void MainWidget::slotBookmarkClicked( int button, TQListViewItem * item, const TQPoint &, int )
{
    BookmarkListItem * bookmark = static_cast<BookmarkListItem *>( item );
    if ( bookmark && button == TQt::MidButton ) // handle middle click
    {
        kdDebug() << k_funcinfo << "Middle clicked bookmark URL: " << bookmark->url()  << endl;
        emit signalURLMidClicked( bookmark->url() );
    }
}

TQStringList MainWidget::tags() const
{
    return m_tags;
}

TQStringList MainWidget::bookmarks() const
{
    TQListViewItemIterator it( lvBookmarks );

    TQStringList tmp;

    while ( it.current() )
    {
        tmp.append( static_cast<BookmarkListItem *>( it.current() )->url().url() );
        ++it;
    }

    return tmp;
}

void MainWidget::slotTagsContextMenu( TQListViewItem *, const TQPoint & pos, int )
{
    if ( lvTags->childCount() == 0 )
        return;

    TQPopupMenu * tagMenu = new TQPopupMenu( this );
    TQ_CHECK_PTR( tagMenu );

    tagMenu->insertItem( i18n( "Check All" ), this, TQ_SLOT( slotCheckAllTags() ) );
    tagMenu->insertItem( i18n( "Uncheck All" ), this, TQ_SLOT( slotUncheckAllTags() ) );
    tagMenu->insertItem( i18n( "Toggle All" ), this, TQ_SLOT( slotToggleTags() ) );
    tagMenu->insertSeparator();
    tagMenu->insertItem( TDEGlobal::iconLoader()->loadIconSet( "edit", TDEIcon::Small ),
                         i18n( "Rename Tag..." ), this, TQ_SLOT( slotRenameTag() ) );

    tagMenu->exec( pos );
}

void MainWidget::slotCheckAllTags()
{
    TQListViewItemIterator it( lvTags );
    while ( it.current() )
    {
        TQCheckListItem * item = static_cast<TQCheckListItem *>( *it );
        if ( item )
            item->setOn( true );
        ++it;
    }
}

void MainWidget::slotUncheckAllTags()
{
    TQListViewItemIterator it( lvTags );
    while ( it.current() )
    {
        TQCheckListItem * item = static_cast<TQCheckListItem *>( *it );
        if ( item )
            item->setOn( false );
        ++it;
    }
}

void MainWidget::slotToggleTags()
{
    TQListViewItemIterator it( lvTags );
    while ( it.current() )
    {
        TQCheckListItem * item = static_cast<TQCheckListItem *>( *it );
        if ( item )
            item->setOn( !item->isOn() );
        ++it;
    }
}

void MainWidget::itemToggled()
{
    m_updateTimer->start( 2000, true );
}

void MainWidget::slotNewBookmark()
{
    emit signalURLClicked( "http://del.icio.us/post/?url=" + m_currentURL.url() );
}

void MainWidget::saveTags()
{
    m_config->writeEntry( "Tags", m_tags );
}

void MainWidget::loadTags()
{
    m_tags = m_config->readListEntry( "Tags" );
}

void MainWidget::slotRenameTag()
{
    TagListItem * tag = static_cast<TagListItem *>( lvTags->currentItem() );
    if ( tag )
    {
        TQString oldName = tag->name();
        TQString newName = KInputDialog::getText( i18n( "Rename Tag" ), i18n( "Provide a new name for tag '%1':" ).arg( oldName ) );
        if ( !newName.isEmpty() )
        {
            KURL url( "http://del.icio.us/api/tags/rename" );
            url.addQueryItem( "old", oldName );
            url.addQueryItem( "new", newName );
            TDEIO::get( url );    // rename the tag

            tag->setName( newName );
        }
    }
}

void MainWidget::slotBookmarksContextMenu( TQListViewItem *, const TQPoint & pos, int )
{
    if ( lvBookmarks->childCount() == 0 )
        return;

    TQPopupMenu * menu = new TQPopupMenu( this );
    TQ_CHECK_PTR( menu );

    menu->insertItem( TDEGlobal::iconLoader()->loadIconSet( "edit-delete", TDEIcon::Small ),
                      i18n( "Delete Bookmark" ), this, TQ_SLOT( slotDeleteBookmark() ) );

    menu->exec( pos );
}

void MainWidget::slotDeleteBookmark()
{
    BookmarkListItem * bookmark = static_cast<BookmarkListItem *>( lvBookmarks->currentItem() );
    if ( bookmark )
    {
        int result = KMessageBox::warningContinueCancel( this, i18n( "Do you really want to remove the bookmark\n%1?" ).arg( bookmark->desc() ),
                                                         i18n( "Delete Bookmark" ), KStdGuiItem::del() );

        if ( result == KMessageBox::Continue )
        {
            KURL url( "http://del.icio.us/api/posts/delete" );
            url.addQueryItem( "url", bookmark->url().url() );
            kdDebug() << k_funcinfo << url << endl;
            TDEIO::get( url );

            delete bookmark;

            slotGetTags();      // re-read the tags
        }
    }
}

#include "mainWidget.moc"
