//##########################################################################
//#                                                                        #
//#                            CLOUDCOMPARE                                #
//#                                                                        #
//#  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; version 2 of the License.               #
//#                                                                        #
//#  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.                          #
//#                                                                        #
//#          COPYRIGHT: EDF R&D / TELECOM ParisTech (ENST-TSI)             #
//#                                                                        #
//##########################################################################

#pragma once

//Qt
#include <QIcon>
#include <QList>
#include <QObject>
#include <QPair>
#include <QString>

//Qt version
#include <qglobal.h>

class ccExternalFactory;
class ccCommandLineInterface;

//! Plugin type
enum  CC_PLUGIN_TYPE
{
    CC_STD_PLUGIN       = 1,
    CC_GL_FILTER_PLUGIN = 2,
    CC_IO_FILTER_PLUGIN = 4,
};

//! Standard CC plugin interface
/** Version 3.2
**/
class ccPluginInterface
{
public:	
	// Contact represents a person and is used for authors and maintainer lists
	struct Contact
	{
		QString name;
		QString email;
	};
	
	using ContactList = QList<Contact>;
	
	// Reference represents a journal article or online post about the plugin where
	// the user can find more information.
	struct Reference
	{
		QString article;
		QString	url;
	};
	
	using ReferenceList = QList<Reference>;
	
public:
	//! Virtual destructor
	virtual ~ccPluginInterface() = default;
	
	//! Returns plugin type (standard or OpenGL filter)
	virtual CC_PLUGIN_TYPE getType() const = 0;

	//! Is this plugin a core plugin?
	virtual bool isCore() const = 0;
	
	//! Returns (short) name (for menu entry, etc.)
	virtual QString getName() const = 0;

	//! Returns long name/description (for tooltip, etc.)
	virtual QString getDescription() const = 0;

	//! Returns icon
	/** Should be reimplemented if necessary
	**/
	virtual QIcon getIcon() const = 0;
	
	//! Returns a list of references (articles and websites) for the plugin
	//! This is optional.
	//! See qDummyPlugin for a real example.
	//! Added in v3.1 of the plugin interface.
	virtual ReferenceList getReferences() const = 0;
	
	//! Returns a list of the authors' names and email addresses
	//! This is optional.
	//! See qDummyPlugin for a real example.
	//! Added in v3.1 of the plugin interface.
	virtual ContactList getAuthors() const = 0;
	
	//! Returns a list of the maintainers' names and email addresses
	//! This is optional.
	//! See qDummyPlugin for a real example.
	//! Added in v3.1 of the plugin interface.
	virtual ContactList getMaintainers() const = 0;
	
	//! Starts the plugin
	/** Should be reimplemented if necessary.
		Used when 'starting' a plugin from the command line
		(to start a background service, a thread, etc.)
	**/
	virtual bool start() = 0;

	//! Stops the plugin
	/** Should be reimplemented if necessary.
		Used to stop a plugin previously started (see ccPluginInterface::start).
	**/
	virtual void stop() = 0;

	//! Returns the plugin's custom object factory (if any)
	/** Plugins may provide a factory to build custom objects.
		This allows qCC_db to properly code and decode the custom
		objects stream in BIN files. Custom objects must inherit the
		ccCustomHObject or ccCustomLeafObject interfaces.
	**/
	virtual ccExternalFactory* getCustomObjectsFactory() const = 0;

	//! Optional: registers commands (for the command line mode)
	/** Does nothing by default.
		\warning: don't use keywords that are already used by the main application or other plugins!
			(use a unique prefix for all commands if possible)
	**/
	virtual void registerCommands(ccCommandLineInterface* cmd) = 0;
	
protected:	
	friend class ccPluginManager;

	//! Set the IID of the plugin (which comes from Q_PLUGIN_METADATA).
	//! It is used to uniquely identify the plugin.
	virtual void setIID( const QString& iid ) = 0;
	
	//! Get the IID of the plugin.
	virtual const QString& IID() const = 0;
};

Q_DECLARE_METATYPE(const ccPluginInterface *);

Q_DECLARE_INTERFACE(ccPluginInterface, "cccorp.cloudcompare.ccPluginInterface/3.2")
