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

// TQt includes
#include <tqobject.h>


// KDE includes
#include <tdeparts/part.h>
#include <tdeparts/plugin.h>
#include <tdeparts/factory.h>
#include <tdemessagebox.h>
#include <kdebug.h>
#include <ktrader.h>
#include <klibloader.h>
#include <tdelocale.h>
#include <tdeapplication.h>
// project includes
#include "kmfcompilerinterface.h"
#include "kmfruleoptioneditinterface.h"
#include "kmfruletargetoptioneditinterface.h"
#include "kmfinstallerinterface.h"
#include "kmftarget.h"
#include "kmftargetconfig.h"
#include "kmferror.h"
#include "kmfconfig.h"

namespace KMF {

KMFPluginFactory::KMFPluginFactory() {}
KMFPluginFactory::~KMFPluginFactory() {}


KParts::ReadWritePart* KMFPluginFactory::KMFMainView( KParts::MainWindow* parent, KMFError* err )  {
	err->setErrType( KMFError::OK );
	TQString 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;
}







TQValueList<KMFCompilerInterface*>* KMFPluginFactory::CompilersForInstaller( const TQString& osName ) {
	TQValueList<KMFCompilerInterface*> *list = new TQValueList<KMFCompilerInterface*>();	
	kdDebug() << "Query: KMyFirewall/Compiler [X-KMyFirewall-Platform] == '" << osName.lower() << "'" << endl;
	TDETrader::OfferList offers = TDETrader::self()->query( "KMyFirewall/Compiler", "[X-KMyFirewall-Platform] == '" + osName.lower() + "'");
	TDETrader::OfferList::iterator it;
	if ( offers.empty() ) {
		kdDebug() << "NO MATCHING PLUGIN FOUND - KMyFirewall/Compiler" << endl;
	}
	for ( it = offers.begin(); it != offers.end(); ++it ) {
		KService::Ptr ptr = *it;
		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 ( KMFCompilerInterface *part = dynamic_cast<KMFCompilerInterface*> ( factory->create( 0 , "KMFCompilerInterface") ) ) {
			list->append ( part );
			
		}
	}
	return list;
}

TQPtrList<KMFRuleOptionEditInterface>* KMFPluginFactory::KMFRuleOptionEditors( TQObject *parent ){
	TQPtrList<KMFRuleOptionEditInterface> *list = new TQPtrList<KMFRuleOptionEditInterface>;
	TDETrader::OfferList offers = TDETrader::self()->query( "KMyFirewall/RuleOptionEdit");
	kdDebug() << "Query performed" << endl;
	
	TDETrader::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() " <<  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;
}

TQPtrList<KMFRuleTargetOptionEditInterface>* KMFPluginFactory::KMFRuleTargetOptionEditors( TQObject *parent ) {
	TQPtrList<KMFRuleTargetOptionEditInterface> *list = new TQPtrList<KMFRuleTargetOptionEditInterface>;
	TDETrader::OfferList offers = TDETrader::self()->query( "KMyFirewall/RuleTargetOptionEdit");
	kdDebug() << "Query performed" << endl;
	
	TDETrader::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(): " <<  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;
}

KMFInstallerInterface* KMFPluginFactory::KMFInstaller( KMFTarget* target ) {

	TDETrader::OfferList offers = TDETrader::self()->query( "KMyFirewall/Installer", " [X-KMyFirewall-Platform] == '"+ target->config()->oS().lower() +"'" );
	kdDebug() << "Query performed" << endl;
	KService::Ptr ptr = offers.first();
	TDETrader::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(): " <<  KLibLoader::self()->lastErrorMessage() << endl;
	
	if ( !factory ) {
		kdDebug() << "Couldn't load plugin: "  <<  ptr->name() << endl;
		return 0;
	}
	if (  KMFInstallerInterface *part = dynamic_cast<KMFInstallerInterface*> ( factory->create( tdeApp  , "KMFInstallerInterface") )
		) {
		if ( ! part ) {
			KMessageBox::error(0, "Couldn't load plugin");
			return 0;
		}
// 		kdDebug() << "Returning KMFInstallerInterface" << endl;
		return part;
	}
	kdDebug() << "Returning 0-Pointer" << endl;
	return 0;
} 

KMFCompilerInterface* KMFPluginFactory::KMFCompiler( KMFTarget* target ) {
	kdDebug() << "KMFCompilerInterface* KMFGenericDoc::compiler()" << endl;
	kdDebug() << "Start query" << endl;
	TDETrader::OfferList offers = TDETrader::self()->query( "KMyFirewall/Compiler", "[X-KMyFirewall-Language] == '" + target->config()->backend().lower() +"' and [X-KMyFirewall-Platform] == '" + target->config()->oS().lower() + "'" );
	kdDebug() << "Query performed" << endl;
	KService::Ptr ptr = offers.first();
	TDETrader::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(): " <<  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( tdeApp , "KMFCompilerInterface" ) ) ) {
		kdDebug() << "Returning Compiler Plugin." << endl;
		return part;
	}
	return 0; 
} 


}





