/**********************************************************************
 * 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.
 **********************************************************************/

#ifndef INTERFACES_CORE_IHOOKPROXY_H
#define INTERFACES_CORE_IHOOKPROXY_H
#include <memory>
#include <QMetaType>

class QVariant;
class QByteArray;

namespace LeechCraft
{
	/** @brief Class for hook-based communication between plugins.
	 *
	 * This interface is designed to be implemented by classes that
	 * allow plugins to communicate with each other using hooks. Usage
	 * of somewhat standard implementation, Util::DefaultHookProxy, is
	 * encouraged.
	 *
	 * The implementation of this interface may also be considered to be
	 * used as a container for parameters that could be passed to hooks,
	 * modified there and used back in the default handler. For that,
	 * GetValue() and SetValue() members are used.
	 *
	 * Parameters are identified by their names, and the names are
	 * usually documented for each corresponding hook.
	 *
	 * So, a hook should get the current value of the parameter by
	 * calling GetValue(), do the required work and possibly update the
	 * parameter by calling SetValue().
	 *
	 * Please note that if several hooks are connected to a single hook
	 * point, the changes to parameters made by previously called hooks
	 * would be visible to next hooks in chain. That is intentional and
	 * by design.
	 *
	 * It only makes sense to pass parameters like that for objects of
	 * types that are copyable and are usually passed by value or by
	 * reference. For example, that may be standard scalar types (int,
	 * bool), or QString, QByteArray and such.
	 *
	 * The hook may cancel the default handler of an event by calling
	 * CancelDefault().
	 *
	 * @sa Util::DefaultHookProxy
	 */
	class Q_DECL_EXPORT IHookProxy
	{
	public:
		virtual ~IHookProxy () {}

		/** @brief Cancels default handler of the event.
		 *
		 * A canceled event handler can't be uncanceled later.
		 */
		virtual void CancelDefault () = 0;

		/** @brief Returns the current "return value" of this hook call chain.
		 *
		 * @return The current "return value".
		 */
		virtual const QVariant& GetReturnValue () const = 0;

		/** @brief Sets the "return value" of this hook chain.
		 *
		 * Consequent calls to this function would overwrite the
		 * previously set value.
		 *
		 * @param[in] value The new return value of this hook.
		 */
		virtual void SetReturnValue (const QVariant& value) = 0;

		/** @brief Returns the value of the given parameter.
		 *
		 * This function returns current value of the given parameter,
		 * or a null QVariant() if no such parameter has been set.
		 *
		 * @param[in] name The name of the parameter.
		 * @return The parameter's value or null QVariant() if no such
		 * parameter exists.
		 *
		 * @sa SetValue()
		 */
		virtual QVariant GetValue (const QByteArray& name) const = 0;

		/** @brief Updates the value of the given parameter.
		 *
		 * This function sets the value of the parameter identified by
		 * name, possibly overwriting previous value (if any).
		 *
		 * Setting a null QVariant as value effectively erases the
		 * parameter value.
		 *
		 * @param[in] name The name of the parameter.
		 * @param[in] value The new value of the parameter.
		 *
		 * @sa GetValue()
		 */
		virtual void SetValue (const QByteArray& name, const QVariant& value) = 0;
	};

	typedef std::shared_ptr<IHookProxy> IHookProxy_ptr;
}

Q_DECLARE_METATYPE (LeechCraft::IHookProxy_ptr);

#endif
