/***************************************************************************
 *   Copyright (C) 2004 by Sashmit Bhaduri                                 *
 *   smt@vfemail.net                                                       *
 *                                                                         *
 *   Licensed under GPL.                                                   *
 ***************************************************************************/

//#include "akregatorconfig.h"
//#include "feediconmanager.h"
#include "pageviewer.h"

#include <tdeaction.h>
#include <kbookmarkmanager.h>
#include <tdehtml_settings.h>
#include <kiconloader.h>
#include <tdelocale.h>
#include <tdepopupmenu.h>


#include <tqmetaobject.h>
#include <private/qucomextra_p.h>

using namespace KlamAV;

PageViewer::PageViewer(TQWidget *parent, const char *name)
    : Viewer(parent, name)
{
    // this hack is necessary since the part looks for []HTML Settings] in
    // TDEGlobal::config() by default, which is wrong when running in Kontact
    TDEHTMLSettings* s = const_cast<TDEHTMLSettings*> (settings());
    //s->init(Settings::self()->config());
    s->init();
    //setXMLFile(locate("data", "akregator/pageviewer.rc"), true);
    
    m_backAction = new TDEToolBarPopupAction(i18n("Back"), "back", 0, this, TQ_SLOT(slotBack()), actionCollection(), "pageviewer_back");

    connect(m_backAction->popupMenu(), TQ_SIGNAL(aboutToShow()),
            this, TQ_SLOT(slotBackAboutToShow()));
    connect(m_backAction->popupMenu(), TQ_SIGNAL(activated(int)),
            this, TQ_SLOT(slotPopupActivated(int)));

    
    m_forwardAction = new TDEToolBarPopupAction(i18n("Forward"), "forward", 0, this, TQ_SLOT(slotForward()), actionCollection(), "pageviewer_forward");

    connect(m_forwardAction->popupMenu(), TQ_SIGNAL(aboutToShow()),
            this, TQ_SLOT(slotForwardAboutToShow()));
    connect(m_forwardAction->popupMenu(), TQ_SIGNAL(activated(int)),
            this, TQ_SLOT(slotPopupActivated(int)));

    m_reloadAction = new TDEAction(i18n("Reload"), "reload", 0,
                            this, TQ_SLOT(slotReload()),
                            actionCollection(), "pageviewer_reload");
    m_stopAction = new TDEAction(i18n("Stop"), "stop", 0,
                                 this, TQ_SLOT(slotStop()),
                                 actionCollection(), "pageviewer_stop");

    //connect( this, TQ_SIGNAL(popupMenu(const TQString &, const TQPoint &)), this, TQ_SLOT(slotPopupMenu(const TQString &, const TQPoint &)));

    m_backAction->setEnabled(false);
    m_forwardAction->setEnabled(false);
    m_stopAction->setEnabled(false);
    
    connect(this, TQ_SIGNAL(started(TDEIO::Job *)), this, TQ_SLOT(slotStarted(TDEIO::Job* )));
    connect(this, TQ_SIGNAL(completed()), this, TQ_SLOT(slotCompleted()));
    connect(this, TQ_SIGNAL(canceled(const TQString &)), this, TQ_SLOT(slotCancelled(const TQString &)));

    connect(browserExtension(),
            TQ_SIGNAL(openURLRequest(const KURL&, const KParts::URLArgs&)),
            this,
            TQ_SLOT(formClicked(const KURL&, const KParts::URLArgs&)));
    
    m_current = m_history.end();
    m_restoring = false;
    // uncomment this to load konq plugins (doesn't work properly and clutters the GUI)
    //loadPlugins( partObject(), this, instance() );
}

// Taken from KDevelop (lib/widgets/kdevhtmlpart.cpp)
void PageViewer::slotBack()
{
    if ( m_current != m_history.begin() )
    {
        --m_current;
        m_restoring = true;
        openURL( (*m_current).url );
        m_restoring = false;
    }
}

// Taken from KDevelop (lib/widgets/kdevhtmlpart.cpp)
void PageViewer::slotForward()
{
    if (  m_current != m_history.fromLast() )
    {
        ++m_current;
        m_restoring = true;
        openURL( (*m_current).url );
        m_restoring = false;
    }
}

void PageViewer::slotBackAboutToShow()
{
    TDEPopupMenu *popup = m_backAction->popupMenu();
    popup->clear();

    if ( m_current == m_history.begin() )
        return;

    TQValueList<PageViewerHistoryEntry>::Iterator it = m_current;
    --it;
    
    int i = 0;
    while( i < 10 )
    {
        if ( it == m_history.begin() )
        {
            popup->insertItem( (*it).title, (*it).id );
            return;
        }
        
        popup->insertItem( (*it).title, (*it).id );
        ++i;
        --it;
    }
}

void PageViewer::slotForwardAboutToShow()
{
    TDEPopupMenu *popup = m_forwardAction->popupMenu();
    popup->clear();

    if ( m_current == m_history.fromLast() )
        return;

    TQValueList<PageViewerHistoryEntry>::Iterator it = m_current;
    ++it;
    
    int i = 0;
    while( i < 10 )
    {
        if ( it == m_history.fromLast() )
        {
            popup->insertItem( (*it).title, (*it).id );
            return;
        }
        
        popup->insertItem( (*it).title, (*it).id );
        ++i;
        ++it;
    }
}


void PageViewer::slotReload()
{
    openURL( url() );
}

void PageViewer::slotStop()
{
    closeURL();
}

// Taken from KDevelop (lib/widgets/kdevhtmlpart.cpp)
bool PageViewer::openURL(const KURL &url)
{
    Viewer::openURL(url);
    
    if (!m_restoring)
        addHistoryEntry(url);
    
    m_backAction->setEnabled( m_current != m_history.begin() );
    m_forwardAction->setEnabled( m_current != m_history.fromLast() );
  
 /*   TQString favicon = FeedIconManager::self()->iconLocation(url);
    if (!favicon.isEmpty()) 
        emit setTabIcon(TQPixmap(TDEGlobal::dirs()->findResource("cache", favicon+".png")));
    else
        emit setTabIcon(SmallIcon("text-html"));
 */   
    return true;
}

void PageViewer::slotOpenURLRequest(const KURL& url, const KParts::URLArgs& args)
{
    if (args.frameName == "_blank") // apparently this indicates that the MMB was pressed...
        Viewer::slotOpenURLRequest(url, args);
    else
        openURL(url);
}

void PageViewer::slotPopupActivated( int id )
{
    TQValueList<PageViewerHistoryEntry>::Iterator it = m_history.begin();
    while( it != m_history.end() )
    {
        if ( (*it).id == id )
        {
            m_current = it;
            m_restoring = true;
            openURL( (*m_current).url );
            m_restoring = false;
            return;
        }
        ++it;
    }
}

// Taken from KDevelop (lib/widgets/kdevhtmlpart.cpp)
void PageViewer::addHistoryEntry(const KURL& url)
{
    TQValueList<PageViewerHistoryEntry>::Iterator it = m_current;
    
    // if We're not already the last entry, we truncate the list here before adding an entry
    if ( it != m_history.end() && it != m_history.fromLast() )
    {
        m_history.erase( ++it, m_history.end() );
    }
    PageViewerHistoryEntry newEntry( url, url.url() );
    //kdDebug() << "PageViewer::addHistoryEntry() " << url.url() << endl;
    
    // Only save the new entry if it is different from the last
    if ( newEntry.url != (*m_current).url )
    {
        m_history.append( newEntry );
        m_current = m_history.fromLast();
    }
}

// Taken from KDevelop (lib/widgets/kdevhtmlpart.cpp)
void PageViewer::slotStarted( TDEIO::Job * )
{
    m_stopAction->setEnabled(true);
}

// Taken from KDevelop (lib/widgets/kdevhtmlpart.cpp)
void PageViewer::slotCompleted( )
{
    m_stopAction->setEnabled(false);
}

// Taken from KDevelop (lib/widgets/kdevhtmlpart.cpp)
void PageViewer::slotCancelled( const TQString & /*errMsg*/ )
{
    m_stopAction->setEnabled(false);
}


void PageViewer::slotSetCaption(const TQString& cap) {
    m_caption = cap;
    (*m_current).title = cap;
}

void PageViewer::slotPaletteOrFontChanged()
{
    //kdDebug() << "PageViewer::slotPaletteOrFontChanged()" << endl;
    // taken from KonqView (tdebase/konqueror/konq_view.cpp)
    
    TQObject *obj = KParts::BrowserExtension::childObject(this);
    if ( !obj ) // not all views have a browser extension !
        return;
    
    int id = obj->metaObject()->findSlot("reparseConfiguration()");
    if (id == -1)
        return;
    TQUObject o[1];

    obj->tqt_invoke(id, o);
    
    // this hack is necessary since the part looks for []HTML Settings] in
    // TDEGlobal::config() by default, which is wrong when running in Kontact
    // NOTE: when running in Kontact, immediate updating doesn't work
    TDEHTMLSettings* s = const_cast<TDEHTMLSettings*> (settings());
    //s->init(Settings::self()->config());
    s->init();
}

void PageViewer::slotGlobalBookmarkArticle()
{
    KBookmarkManager *mgr = KBookmarkManager::userBookmarksManager();
    KBookmarkGroup grp = mgr->root();
    grp.addBookmark(mgr, m_caption, toplevelURL());
    mgr->save();
}


void PageViewer::slotPopupMenu(KXMLGUIClient*, const TQPoint& p, const KURL& kurl, const KParts::URLArgs&, KParts::BrowserExtension::PopupFlags, mode_t)
{
    m_url = kurl;
    TQString url = kurl.url(); // maximal url confusion
    
    // if true show popup menu for link. Maybe that doesn't work properly when using frames
    bool isLink = kurl != Viewer::url();
    
//  TDEPopupMenu popup( i18n( "Documentation Viewer" ), this->widget() );
    TDEPopupMenu popup(this->widget());

//     bool needSep = false;
    int idNewWindow = -2;
    if (isLink)
    {
        idNewWindow = popup.insertItem(SmallIcon("tab_new"),i18n("Open Link in New &Tab"), this, TQ_SLOT(slotOpenLinkInForegroundTab()));
        popup.setWhatsThis(idNewWindow, i18n("<b>Open Link in New Tab</b><p>Opens current link in a new tab."));
        popup.insertItem(SmallIcon("window-new"), i18n("Open Link in External &Browser"), this, TQ_SLOT(slotOpenLinkInBrowser()));
                
        popup.insertSeparator();
        
        TDEAction *savelinkas = action("savelinkas");
        
        if (savelinkas)
                savelinkas->plug( &popup);
        
        TDEAction* copylinkaddress = action("copylinkaddress");
        if (copylinkaddress)
        {
            copylinkaddress->plug( &popup);
            popup.insertSeparator();
        }
    }
    else // we are not on a link
    {

        m_backAction->plug( &popup );
        m_forwardAction->plug( &popup );
        m_reloadAction->plug(&popup);
        m_stopAction->plug(&popup);

        popup.insertSeparator();
        action("viewer_copy")->plug(&popup);
        popup.insertSeparator();

        TDEAction* incFontAction = this->action("incFontSizes");
        TDEAction* decFontAction = this->action("decFontSizes");
        if ( incFontAction && decFontAction )
        {
            incFontAction->plug( &popup );
            decFontAction->plug( &popup );
            popup.insertSeparator();
        }
    
        popup.insertItem(SmallIcon("window-new"), i18n("Open Page in External Browser"), this, TQ_SLOT(slotOpenLinkInBrowser()));
    
        action("viewer_print")->plug(&popup);
        popup.insertSeparator();
        
        TDEAction *ac = action("setEncoding");
        if (ac)
            ac->plug(&popup);
        popup.insertItem(SmallIcon("bookmark_add"),i18n("Add to Konqueror Bookmarks"), this, TQ_SLOT(slotGlobalBookmarkArticle()));
    }
    
    int r = popup.exec(p);
    
    if (r == idNewWindow)
    {
        KURL kurl;
        if (!KURL(url).path().startsWith("/"))
        {
            //kdDebug() << "processing relative url: " << url << endl;
            if (url.startsWith("#"))
            {
                kurl = KURL(PageViewer::url());
                kurl.setRef(url.mid(1));
            }
            else
                kurl = KURL(PageViewer::url().upURL().url(true)+url);
        }
        else
            kurl = KURL(url);
//    kurl.addPath(url);
/*        if (kurl.isValid())
            slotOpenInNewWindow(kurl);*/
// //      openURL( kurl );
    }
}

void PageViewer::formClicked(const KURL& url, const KParts::URLArgs& args)
{
    if (args.doPost()) {
        browserExtension()->setURLArgs(args);
        openURL(url);
    }
}

#include "pageviewer.moc"
