//
// C++ Implementation: kmfpluginfactory
//
// Description:
//
//
// Author: Christian Hubinger <chubinger@gmail.com>, (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
// License: GPL
//
#include "kmfpluginfactory.h"

// QT includes
#include <qobject.h>


// KDE includes
#include <kparts/part.h>
#include <kparts/plugin.h>
#include <kparts/factory.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <ktrader.h>
#include <klibloader.h>
#include <klocale.h>

// project includes
#include "../interfaces/kmfcompilerinterface.h"
#include "../interfaces/kmfruleoptioneditinterface.h"
#include "../interfaces/kmfruletargetoptioneditinterface.h"
#include "../interfaces/kmfiptinstallerinterface.h"

#include "kmferror.h"
// #include "kmfconfiguration.h"
#include "kmfconfig.h"
KMFPluginFactory::KMFPluginFactory() {}
KMFPluginFactory::~KMFPluginFactory() {}


KParts::ReadWritePart* KMFPluginFactory::KMFMainView( KParts::MainWindow* parent, KMFError* err )  {
	err->setErrType( KMFError::OK );
	QString libName;
	if ( KMFConfig::useGenericInterface() ) {
		kdDebug() << "Loading generic GUI" << endl;
		libName = "libkmfgenericinterfacepart";
	} else {
		kdDebug() << "Loading iptables GUI" << endl;
		libName = "libkmfipteditorpart";
	}
	
		KLibFactory * factory = KLibLoader::self() ->factory( libName.latin1() );
		if ( factory ) {
			KParts::ReadWritePart * m_ruleeditpart = static_cast<KParts::ReadWritePart *>( factory->create( parent,
			                 libName.latin1() , "KParts::ReadWritePart" ) );

			if ( m_ruleeditpart ) {
				return  m_ruleeditpart;
			}
			err->setErrType( KMFError::FATAL );
			err->setErrMsg( i18n( "Could not cast plugin to type: KParts::ReadWritePart." ) );
			return 0;
		} else {
			err->setErrType( KMFError::FATAL );
			err->setErrMsg( i18n( "Could not find %1 in the library search path." ).arg( libName ) );
			return 0;
		}
		err->setErrType( KMFError::FATAL );
		err->setErrMsg( i18n( "Could not find libkmfgenericinterfacepart in the library search path." ) );
		return 0;
}


KMFCompilerInterface* KMFPluginFactory::KMFCompiler( const QString& platform, const QString& language, QObject *parent ) {
	kdDebug() << "KMFCompilerInterface* KMFGenericDoc::compiler()" << endl;
	kdDebug() << "Start query" << endl;
	KTrader::OfferList offers = KTrader::self()->query( "KMyFirewall/Compiler", "[X-KMyFirewall-Language] == '" + language +"' AND [X-KMyFirewall-Platform] == '" + platform + "'" );
	kdDebug() << "Query performed" << endl;
	KService::Ptr ptr = offers.first();
	KTrader::OfferList::iterator it;
	if ( offers.empty() ) {
		KMessageBox::error(0, i18n("<qt><b>Could not find a matching compiler plugin.</b></qt>") );
		kdDebug() << "NO MATCHING PLUGIN FOUND" << endl;
		return 0;
	}
	kdDebug() << "KMFGenericDoc found Plugin: " << ptr->name()  << "\nLibrary: "<<  ptr->library().local8Bit().data()  <<endl;
	KLibFactory *factory = KLibLoader::self()->factory( ptr->library().local8Bit().data() );
	kdDebug() << KLibLoader::self()->lastErrorMessage() << endl;

	if ( !factory ) {
		KMessageBox::error( 0, i18n("<qt><b>Compiler plugin could not be loaded.</b></qt>") );
		kdDebug() << "Couldn't load plugin: "  <<  ptr->name() << endl;
		return 0;
	}
	
	if ( KMFCompilerInterface *part = dynamic_cast<KMFCompilerInterface*> ( factory->create( parent , "KMFCompilerInterface") ) ) {
		kdDebug() << "Returning Compiler Plugin." << endl;
		return part;
	}
	return 0; 
} 

QPtrList<KMFRuleOptionEditInterface>* KMFPluginFactory::KMFRuleOptionEditors( QObject *parent ){
	QPtrList<KMFRuleOptionEditInterface> *list = new QPtrList<KMFRuleOptionEditInterface>;
	KTrader::OfferList offers = KTrader::self()->query( "KMyFirewall/RuleOptionEdit");
	kdDebug() << "Query performed" << endl;
	
	KTrader::OfferList::iterator it;
	for ( it = offers.begin(); it != offers.end(); ++it ) {
		KService::Ptr ptr = *it;
		kdDebug() << "Found KMFRuleOptionEdit Plugin: " << ptr->name()  << "\nLibrary: "<<  ptr->library().local8Bit().data()  <<endl;
		KLibFactory *factory = KLibLoader::self()->factory( ptr->library().local8Bit().data() );
		kdDebug() << KLibLoader::self()->lastErrorMessage() << endl;
		if ( !factory ) {
			kdDebug() << "Couldn't load plugin: "  <<  ptr->name() << endl;
		}
		if (  KMFRuleOptionEditInterface *part = dynamic_cast<KMFRuleOptionEditInterface*> ( factory->create( parent , "KMFRuleOptionEditInterface") ) ) {
			if ( ! part ) {
				KMessageBox::error(0, "Couldn't load plugin");
			}
			list->append( part );
			kdDebug() << "Initialiesed Plugin." << endl;
		}
	}
	return list;
}

QPtrList<KMFRuleTargetOptionEditInterface>* KMFPluginFactory::KMFRuleTargetOptionEditors( QObject *parent ) {
	QPtrList<KMFRuleTargetOptionEditInterface> *list = new QPtrList<KMFRuleTargetOptionEditInterface>;
	KTrader::OfferList offers = KTrader::self()->query( "KMyFirewall/RuleTargetOptionEdit");
	kdDebug() << "Query performed" << endl;
	
	KTrader::OfferList::iterator it;
	for ( it = offers.begin(); it != offers.end(); ++it ) {
		KService::Ptr ptr = *it;
		kdDebug() << "Found KMFRuleTargetOptionEdit Plugin: " << ptr->name()  << "\nLibrary: "<<  ptr->library().local8Bit().data()  <<endl;
		KLibFactory *factory = KLibLoader::self()->factory( ptr->library().local8Bit().data() );
		kdDebug() << KLibLoader::self()->lastErrorMessage() << endl;
		if ( !factory ) {
			kdDebug() << "Couldn't load plugin: "  <<  ptr->name() << endl;
		}
		if (  KMFRuleTargetOptionEditInterface *part = dynamic_cast<KMFRuleTargetOptionEditInterface*> ( factory->create(  parent , "KMFRuleTargetOptionEditInterface") ) ) {
			if ( ! part ) {
				KMessageBox::error(0, "Couldn't load plugin");
			}
			list->append( part );
			kdDebug() << "Initialiesed Plugin." << endl;
		}
	}
	return list;
}

KMFIPTInstallerInterface* KMFPluginFactory::KMFIPTInstaller( const QString& platform, const QString& language, QObject* parent  ) {

	KTrader::OfferList offers = KTrader::self()->query( "KMyFirewall/Installer", "[X-KMyFirewall-Language] == '" + language +"'  AND [X-KMyFirewall-Platform] == '"+ platform +"'" );
	kdDebug() << "Query performed" << endl;
	KService::Ptr ptr = offers.first();
	KTrader::OfferList::iterator it;
	if ( offers.empty() ) {
		kdDebug() << "NO MATCHING PLUGIN FOUND" << endl;
		return 0;
	}
	kdDebug() << "KMFPluginFactory found Plugin: " << ptr->name()  << "\nLibrary: "<<  ptr->library().local8Bit().data()  <<endl;
	KLibFactory *factory = KLibLoader::self()->factory( ptr->library().local8Bit().data() );
	kdDebug() << KLibLoader::self()->lastErrorMessage() << endl;
	
	if ( !factory ) {
		kdDebug() << "Couldn't load plugin: "  <<  ptr->name() << endl;
		return 0;
	}
	if (  KMFIPTInstallerInterface *part = dynamic_cast<KMFIPTInstallerInterface*> ( factory->create( parent , "KMFIPTInstallerInterface") )
		) {
		if ( ! part ) {
			KMessageBox::error(0, "Couldn't load plugin");
			return 0;
		}
		kdDebug() << "Returning KMFIPTInstallerInterface" << endl;
		return part;
	}
	kdDebug() << "Returning 0-Pointer" << endl;
	return 0;
} 







