/**********************************************************************
 * LeechCraft - modular cross-platform feature rich internet client.
 * Copyright (C) 2006-2014  Georg Rudoy
 *
 * Boost Software License - Version 1.0 - August 17th, 2003
 *
 * Permission is hereby granted, free of charge, to any person or organization
 * obtaining a copy of the software and accompanying documentation covered by
 * this license (the "Software") to use, reproduce, display, distribute,
 * execute, and transmit the Software, and to prepare derivative works of the
 * Software, and to permit third-parties to whom the Software is furnished to
 * do so, all subject to the following:
 *
 * The copyright notices in the Software and this entire statement, including
 * the above license grant, this restriction and the following disclaimer,
 * must be included in all copies of the Software, in whole or in part, and
 * all derivative works of the Software, unless such copies or derivative
 * works are solely in the form of machine-executable object code generated by
 * a source language processor.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 **********************************************************************/

#pragma once

#include <QObject>
#include <QList>
#include "xpcconfig.h"

namespace LC
{
namespace Util
{
	/** @brief Base class for signal-slot relays in plugin APIs.
	 *
	 * This class is typically used by plugins that support other plugins
	 * to relay signals from the internals of the root plugin to the
	 * subplugins.
	 *
	 * The interconnector automatically connects its signals with the
	 * matching slots (that is, with the same name and parameters) of
	 * subplugins added to it via AddPlugin(), and connects signals of
	 * the objects added via RegisterHookable() to its own matching
	 * signals.
	 *
	 * The usage is as follows:
	 * -# One subclasses from this class and lists all the signals that
	 *    should ever be relayed to plugins in the signals section of the
	 *    subclass. First parameter of the signals should always be
	 *    LC::IHookProxy_ptr.
	 * -# One adds the instance objects of the subplugins to the
	 *    interconnector via the AddPlugin() method.
	 * -# One registers the objects emitting signals that need to be
	 *    relayed to plugins via the RegisterHookable() method.
	 * -# Everything works.
	 *
	 * Please note that second and third steps can be done in arbitrary
	 * order and even be interleaved.
	 */
	class UTIL_XPC_API BaseHookInterconnector : public QObject
	{
		Q_OBJECT
	protected:
		QList<QObject*> Plugins_;
	public:
		/** @brief Creates the interconnector with the given parent.
		 *
		 * @param[in] parent The parent object of this interconnector.
		 */
		BaseHookInterconnector (QObject *parent = 0);

		/** @brief Virtual destructor.
		 */
		virtual ~BaseHookInterconnector ();

		/** @brief Adds a subplugin to this interconnector.
		 *
		 * This function is used to add a subplugin whose slots should
		 * be connected to the signals of this plugin.
		 *
		 * Every signal of this object with the name and parameters list
		 * matching a slot of \em plugin will be automatically connected
		 * to it.
		 *
		 * @param[in] plugin The subplugin to add to this interconnector.
		 *
		 * @sa RegisterHookable()
		 */
		virtual void AddPlugin (QObject *plugin);

		/** @brief Adds a hookable object from the root plugin.
		 *
		 * This function is used to add an object whose signals need to
		 * be exposed to subplugins.
		 *
		 * Every signal of \em hookable with the name and parameters list
		 * matching a signal of this object will be automatically
		 * connected to it.
		 *
		 * @param[in] hookable The hookable object from the root plugin
		 * to add.
		 *
		 * @sa AddPlugin()
		 */
		void RegisterHookable (QObject *hookable);
	};
}
}
