/*********************************************************************************
* C++ Implementation: connectioninterface.cpp
* Description:
*
* Begin : lör maj 24 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 <qapplication.h>
//////////////////////////////////////////////////////////////////////
// KDE specific include files
#include <kio/slave.h>
#include <kio/scheduler.h>
#include <kdebug.h>
//////////////////////////////////////////////////////////////////////
// System specific include files
//////////////////////////////////////////////////////////////////////
// Application specific include files
#include "connectioninterface.h"
#include "connectionmanager.h"
#include "kbearmainwiniface.h"
#include "kbearcore.h"

#include "connectioninterface.moc"

using namespace KBear;
//-----------------------------------------------
ConnectionInterface::ConnectionInterface( const SiteInfo& info )
	:	m_siteInfo( info )
{
}
//-----------------------------------------------
ConnectionInterface::ConnectionInterface()
{
}
//-----------------------------------------------
ConnectionInterface::~ConnectionInterface() {
	kdDebug()<<k_funcinfo<<" ID="<<m_siteInfo.ID()<<endl;
}
//-----------------------------------------------
bool ConnectionInterface::openConnection() {
	return ( getSlave() ? true : false);
}
//-----------------------------------------------
KIO::Slave* ConnectionInterface::getSlave() {
	if( ! m_slave || ! m_slave->isAlive() || ! m_slave->isConnected() )
		setupSlave();

	return m_slave;
}
//-----------------------------------------------
void ConnectionInterface::setupSlave() {
	fillMetaData();
	KBearMainWindowInterface::getInstance()->core()->emitMetaDataNeeded( m_metaData );
/*
	if( m_slave ) {
		QObject::disconnect( m_slave, 0, this, 0 );
		KIO::Scheduler::disconnectSlave( m_slave );
	}
*/
	m_slave = KIO::Scheduler::getConnectedSlave( m_siteInfo.url(), m_metaData );
	if( ! m_slave ) {
		kdError() << "Didn't receive a slave from Scheduler in Connection::setupSlave()" << endl;
		return;
	}
	QObject::connect( m_slave, SIGNAL( infoMessage( const QString& ) ), this, SLOT( slotInfoMessage( const QString& ) ) );
	QObject::connect( m_slave, SIGNAL( connected() ), this, SLOT( slotConnected() ) );
	QObject::connect( m_slave, SIGNAL( error( int, const QString& ) ), this, SLOT( slotSlaveError( int, const QString& ) ) );
}
//-----------------------------------------------
void ConnectionInterface::slotSlaveError( int err, const QString& errMsg ) {
	if( ! m_slave || ! m_slave->isAlive() || ! m_slave->isConnected() ) {
		emit notConnected( m_siteInfo.ID() );
	}
	switch( err ) {
		case KIO::ERR_SLAVE_DIED: {
			slaveDied();
			break;
		}
	}
	emit error( m_siteInfo.ID(), err, errMsg );
}
//-----------------------------------------------
void ConnectionInterface::addJob( KIO::SimpleJob* job ) {
	if( job == 0L )
		return;

	KIO::Slave* slave = getSlave();
	KIO::Scheduler::assignJobToSlave( slave , job );

	m_jobList.append( job );
	connect( job, SIGNAL( result( KIO::Job* ) ), this, SLOT( slotJobResult( KIO::Job* ) ) );
	// Do we need this ?
	// connect( job, SIGNAL( destroyed( QObject* ) ), this, SLOT( slotJobDestroyed( QObject* ) ) );

	// Anything else to do ?
}
//-----------------------------------------------
void ConnectionInterface::removeJob( KIO::SimpleJob* job ) {
	if( job == 0L )
		return;

	if( ! m_jobList.remove( job )  ) {
		kdError() << k_funcinfo<< "BUG !!!!! Could not remove job="<<job<<" not in list" << endl;
	}
}
//-----------------------------------------------
void ConnectionInterface::slotJobResult( KIO::Job* job ) {
	removeJob( dynamic_cast<KIO::SimpleJob*>( job ) );
}
//-----------------------------------------------
SiteInfo ConnectionInterface::getInfo() const {
	return m_siteInfo;
}
//-----------------------------------------------
void ConnectionInterface::slotConnected() {
	emit connected( m_siteInfo.ID() );
}
//-----------------------------------------------
void ConnectionInterface::slaveDied() {
	kdError() << k_funcinfo<< endl;
	m_slave = 0L;
	m_jobList.clear();
	// Anything else to do ?
}
//-----------------------------------------------
void ConnectionInterface::slotInfoMessage( const QString& message ) {
	if( m_siteInfo.enableLog() )  {// Only post if log is enabled
		emit infoMessage( m_siteInfo.ID(), message );
	}
}
//-----------------------------------------------
void ConnectionInterface::fillMetaData() {
	m_metaData.clear();
	m_metaData.insert( "EnableLog", m_siteInfo.enableLog()?"true":"false" );
	m_metaData.insert( "DisablePassiveMode", m_siteInfo.passiveMode()?"false":"true" );
	m_metaData.insert( "DisableEPSV", m_siteInfo.extendedPassiveMode()?"false":"true" );
	m_metaData.insert( "ListCommand", m_siteInfo.listCommand() );
	m_metaData.insert( "MarkPartial", m_siteInfo.markPartial()?"true":"false" );
	m_metaData.insert( "Encoding", m_siteInfo.fileSysEncoding() );
}
//-----------------------------------------------
