#ifndef _KVI_MODULEEXTENSION_H_
#define _KVI_MODULEEXTENSION_H_
//
//   File : kvi_moduleextension.h
//   Creation date : Tue Sep 10 01:16:24 2002 GMT by Szymon Stefanek
//
//   This file is part of the KVirc irc client distribution
//   Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)
//
//   This program is FREE software. You can redistribute it and/or
//   modify it under the terms of the GNU General Public License
//   as published by the Free Software Foundation; either version 2
//   of the License, or (at your opinion) any later version.
//
//   This program is distributed in the HOPE that it will be USEFUL,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//   See the GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public License
//   along with this program. If not, write to the Free Software Foundation,
//   Inc. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//

#include "kvi_string.h"
#include "kvi_list.h"
#include <qasciidict.h>

class KviModule;
class KviModuleExtension;
class KviModuleExtensionDescriptor;

typedef KviModuleExtension * (*KviModuleExtensionAllocRoutine)(KviModuleExtensionDescriptor *,void *);

class KviModuleExtensionDescriptor
{
	friend class KviModuleExtension;
	friend class KviModuleExtensionManager; // only the manager allocates and deallocates these structures
protected:
	KviModuleExtensionDescriptor(KviModule * m,const KviStr &szType,const KviStr &szName,const KviStr &szVisibleName,KviModuleExtensionAllocRoutine r);
public: // this has to be public because of QPtrList... but should be protected
	~KviModuleExtensionDescriptor();
private:
	int                              m_iId;            // unique id assigned at creation time
	KviStr                           m_szType;         // name of the service (toolbar , crypt engine...)
	KviStr                           m_szName;         // 
	KviStr                           m_szVisibleName;  // name that is VISIBLE and possibly translated
	KviStr                           m_szAuthor;       // Author (visible)
	KviStr                           m_szDescription;  // Description (visible!)
	int                              m_iFlags;         // Flags (0 if not applicable)
	KviModuleExtensionAllocRoutine   m_allocRoutine;
	KviPtrList<KviModuleExtension> * m_pObjectList;

	KviModule                      * m_pModule;        // module pointer
public:
	KviModuleExtension * allocate(void * par);

	int id(){ return m_iId; };
	KviModule * module(){ return m_pModule; };
	const KviStr &type(){ return m_szType; };
	const KviStr &name(){ return m_szName; };
	const KviStr &visibleName(){ return m_szVisibleName; };
	const KviStr &author(){ return m_szAuthor; };
	const KviStr &description(){ return m_szDescription; };
	int flags(){ return m_iFlags; };

	void setAuthor(const KviStr &szAuthor){ m_szAuthor = szAuthor; };
	void setDescription(const KviStr &szDescription){ m_szDescription = szDescription; };
	void setVisibleName(const KviStr &szVisibleName){ m_szVisibleName = szVisibleName; };
	void setFlags(int iFlags){ m_iFlags = iFlags; };
	
protected:
	void registerObject(KviModuleExtension * e);
	void unregisterObject(KviModuleExtension * e);
};


typedef KviPtrList<KviModuleExtensionDescriptor> KviModuleExtensionDescriptorList;

class KviModuleExtensionManager
{
	friend class KviModule;
	friend class KviApp;
protected:
	KviModuleExtensionManager(); // KviApp calls this
	~KviModuleExtensionManager(); // and this
protected:
	QAsciiDict<KviModuleExtensionDescriptorList> * m_pExtensionDict;
protected:
	// Only KviModule can call this
	KviModuleExtensionDescriptor * registerExtension(KviModule * m,const KviStr &szType,const KviStr &szName,const KviStr &szVisibleName,KviModuleExtensionAllocRoutine r);
	void unregisterExtensionsByModule(KviModule * m);
public:
	KviModuleExtensionDescriptorList * getExtensionList(const KviStr &szType);
	KviModuleExtension * allocateExtension(const KviStr &szType,const KviStr &szName,void * param,const char * preloadModule = 0);
	KviModuleExtension * allocateExtension(const KviStr &szType,int id,void * param,const char * preloadModule = 0);
private:
	KviModuleExtensionDescriptorList * allocateExtensionGetDescriptorList(const KviStr &szType,const char * preloadModule);

};



class KviModuleExtension
{
public:
	KviModuleExtension(KviModuleExtensionDescriptor * d);
	~KviModuleExtension();
private:
	KviModuleExtensionDescriptor * m_pDescriptor;
public:
	KviModuleExtensionDescriptor * descriptor(){ return m_pDescriptor; };
	// A module extension MUST implement die() as "delete this"
	virtual void die() = 0;
};

#ifndef _KVI_MODULEEXTENSION_CPP_
	extern KVIRC_API KviModuleExtensionManager * g_pModuleExtensionManager;
#endif


#endif //_KVI_MODULEEXTENSION_H_
