/*********************************************************************************
* C++ Implementation: kbearrecentconnectionsplugin..cpp
* Description:
*
* Begin : fre jun 27 2003
* Author : Björn Sahlström <kbjorn@users.sourceforge.net> (C) 2003
* Copyright : See COPYING file that comes with this distribution
**********************************************************************************/

//////////////////////////////////////////////////////////////////////
// Qt specific include files
#include <qvbox.h>
#include <qpopupmenu.h>
//////////////////////////////////////////////////////////////////////
// KDE specific include files
//////////////////////////////////////////////////////////////////////
// System specific include files
#include <klocale.h>
#include <kglobal.h>
#include <kapplication.h>
#include <kaction.h>
#include <kprotocolinfo.h>
#include <kconfig.h>
#include <kmessagebox.h>
#include <kinstance.h>
#include <kiconloader.h>
#include <kgenericfactory.h>
#include <dcopclient.h>
#include <kstatusbar.h>
#include <kdebug.h>
//////////////////////////////////////////////////////////////////////
// Application specific include files
#include "misc.h"
#include "kbearapi.h"
#include "kbearcore.h"
#include "kbearmainwiniface.h"

#include "kbearrecentconnectionsplugin.h"


using namespace KBear;

#include "kbearrecentconnectionsplugin.moc"
//-----------------------------------------------
typedef KGenericFactory<KBearRecentConnectionsPlugin> KBearRecentConnectionsPluginFactory;
K_EXPORT_COMPONENT_FACTORY( kbearrecentconnections, KBearRecentConnectionsPluginFactory( "kbearrecentconnections" ) );
//-----------------------------------------------
KBearRecentConnectionsPlugin::KBearRecentConnectionsPlugin(QObject *parent, const char*, const QStringList& )
	:	KBearPlugin( parent, "KBearRecentConnectionsPlugin" )
{
	(void) KGlobal::locale()->insertCatalogue("kbear");
	setInstance(KBearRecentConnectionsPluginFactory::instance());
	setXMLFile("kbearrecentconnections.rc");

	m_recentAction = new KSelectAction( i18n("Open &Recent"), 0, actionCollection(), "open_recent_list" );
	m_clearRecentAction = new KAction( i18n("Cl&ear Recent"), 0, 0, this, SLOT( slotClearRecent() ), actionCollection(), "clear_recent_list" );
	m_clearRecentAction->setToolTip( i18n("Clear the recent menu") );
	m_openRecentAction = new KAction( i18n("O&pen Selected"), 0, 0, this, SLOT( slotOpenSelected() ), actionCollection(), "open_recent" );
	m_openRecentAction->setEnabled( false );

	connect( m_recentAction, SIGNAL( activated( const QString& ) ), this, SLOT(slotOpenRecent( const QString& ) ) );
	connect( core(), SIGNAL( newSite( const SiteInfo&, const SiteInfo& ) ), this, SLOT(slotAddToRecent( const SiteInfo&, const SiteInfo& ) ) );

	m_config = KBearRecentConnectionsPluginFactory::instance()->config();

	m_outputWidget = new KBearRecentConnectionsOutputWidget( m_config, 0L, "KBearRecentConnectionsOutputWidget" );

}
//-----------------------------------------------
KBearRecentConnectionsPlugin::~KBearRecentConnectionsPlugin() {
	mainWindow()->removeOutputPluginView( m_outputWidget );
	m_config->sync();
	delete m_outputWidget;
}
//-----------------------------------------------
void KBearRecentConnectionsPlugin::slotInit() {
	connect( actionCollection(), SIGNAL( actionStatusText(const QString &) ), mainWindow()->statusBar(), SLOT( message(const QString &) ) );
	connect( actionCollection(), SIGNAL( clearStatusText() ), mainWindow()->statusBar(), SLOT( clear() ) );
	connect( m_outputWidget, SIGNAL( contextMenu(KListView*, QListViewItem*, const QPoint& ) ),
					this, SLOT( slotContextMenu( KListView*, QListViewItem*, const QPoint& ) ) );
	// this method will be automatically called when the plugin gets loaded
	// if you need to do any initializatione stuff, this is the place to do it

  // if you want to embed a widget as an outputview, simply uncomment
  // the following line.
	mainWindow()->embedOutputPluginView( m_outputWidget, i18n("Recent Connections"), i18n("Give access to the latest used connections") );

	loadRecent();
}
//-----------------------------------------------
void KBearRecentConnectionsPlugin::slotOpenRecent( const QString& path) {
	static const QString& ftpStr = KGlobal::staticQString("ftp");
	static const QString& kbearFTPStr = KGlobal::staticQString("kbearftp");

	QString tmp = path;
	if( path.right( 1 ) == "/" )
		tmp = path.left( path.length() -1 );
	QStringList list = QStringList::split( "/", tmp );
	SiteInfo site;
	site.setLabel( list.last() );
	site.setParent( path.left( path.length() - site.label().length() -1 ) );

	QByteArray data, replyData;
	QDataStream arg( data, IO_WriteOnly );
	QCString replyType;
	arg << site;
	if( kapp->dcopClient()->call("kbearsitemanagerdb", "SiteManagerDBInterface", "getSite(SiteInfo)", data, replyType, replyData, true ) ) {
		QDataStream answer( replyData, IO_ReadOnly );
		SiteInfo s;
		answer >> s;
		if( ! s.label().isEmpty() ) {
			s.setPass( decodePassword( s.pass() ) );
			QStringList protList = KProtocolInfo::protocols();
			bool hasKBearFtp = false;
			for( QStringList::Iterator it = protList.begin(); it != protList.end(); ++it ) {
				if( *it == kbearFTPStr )
					hasKBearFtp = true;
			}
			if( s.protocol() == ftpStr && hasKBearFtp )
				s.setProtocol( kbearFTPStr );

			m_api->core()->openSite( s );
		}
		else {
			QString entry = site.parent() + "/" + site.label();
			KMessageBox::error ( kapp->mainWidget(), i18n("Can't find the site: %1\n"
										"It's probably removed from the SiteManager.\n"
										"It will now also be removed from the list over recent connections")
										.arg( entry ), i18n("Error opening recent...") );

			m_config->setGroup( "RecentConnections" );
			QStringList list = m_recentAction->items();
			list.remove( entry );
			m_config->writeEntry( "List", list );

			m_config->deleteGroup( entry );
			m_recentAction->setItems( list );
			m_outputWidget->removeFromRecent( entry );
		}
	}
	else {
		kdDebug()<<"DCOP call getSite(SiteInfo) failed !!!!"<<endl;
		KMessageBox::error ( kapp->mainWidget(), i18n("Could not communicate with the Site Database"), i18n("Communication error...") );
	}
}
//-----------------------------------------------
void KBearRecentConnectionsPlugin::slotOpenSelected() {
	QListViewItem* item = m_outputWidget->selectedItem();
	if( item ) {
		slotOpenRecent( item->text( 0 ) );
	}
}
//-----------------------------------------------
void KBearRecentConnectionsPlugin::slotClearRecent() {
	QStringList groups = m_config->groupList();
	for( QStringList::Iterator it = groups.begin(); it != groups.end(); ++it ) {
		m_config->deleteGroup( *it );
	}
	m_config->sync();
	loadRecent();
}
//-----------------------------------------------
void KBearRecentConnectionsPlugin::slotAddToRecent( const SiteInfo& site, const SiteInfo& ) {
	QString entry = site.parent() + "/" + site.label();
	m_config->deleteGroup( entry );

	m_config->setGroup( "RecentConnections" );
	QStringList list = m_config->readListEntry( "List" );

	// remove file if already in list
	list.remove( entry );

	// remove last item if already maxitems in list
	while( list.count() >= 10 ) {
		// remove last item
		list.remove( list.last() );
	}

	// add file to list
	list.prepend( entry );
	m_recentAction->setItems( list );
	m_config->writeEntry( "List", list );
	m_config->setGroup( entry );

	m_outputWidget->addToRecent( site );

}
//-----------------------------------------------
void KBearRecentConnectionsPlugin::loadRecent() {
	m_config->setGroup( "RecentConnections" );
	QStringList list = m_config->readListEntry( "List" );

	m_recentAction->setItems( list );

	m_outputWidget->loadRecent();

}
//-----------------------------------------------
void KBearRecentConnectionsPlugin::slotContextMenu( KListView*, QListViewItem*, const QPoint& p ) {
	QPopupMenu* menu = ( factory() ? static_cast<QPopupMenu*>(factory()->container("recentconnections_popup", this)) : 0 );
	if( menu ) {
		QListViewItem* item = m_outputWidget->selectedItem();
		m_openRecentAction->setEnabled( item && item->isSelected() );
		menu->popup( p );
	}
}
//-----------------------------------------------


