/**********************************************************************
 * 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 PLUGINTREEBUILDER_H
#define PLUGINTREEBUILDER_H
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/properties.hpp>
#include <QObjectList>
#include <QSet>
#include <QHash>

namespace LeechCraft
{
	class PluginTreeBuilder
	{
		QObjectList Instances_;

		struct VertexInfo
		{
			bool IsFulfilled_;

			/* Needs/provides dependencies: on what features does this
			 * plugin depend.
			 */
			QSet<QString> AllFeatureDeps_;

			/* Second-level plugins dependencies: on what first-level
			 * plugins does this plugin depend.
			 */
			QSet<QByteArray> AllP2PDeps_;

			QSet<QString> UnfulfilledFeatureDeps_;
			QSet<QByteArray> UnfulfilledP2PDeps_;

			QSet<QString> FeatureProvides_;
			QSet<QByteArray> P2PProvides_;

			QObject *Object_;

			VertexInfo ();
			VertexInfo (QObject*);
		};

		typedef boost::property<boost::vertex_color_t, boost::default_color_type,
				VertexInfo> VertexProperty;
		typedef boost::adjacency_list<boost::vecS, boost::vecS,
				boost::bidirectionalS, VertexProperty> Graph_t;
		typedef Graph_t::vertex_descriptor Vertex_t;
		typedef Graph_t::edge_descriptor Edge_t;
		typedef Graph_t::out_edge_iterator OutEdgeIterator_t;
		typedef Graph_t::in_edge_iterator InEdgeIterator_t;

		Graph_t Graph_;

		QHash<QObject*, Vertex_t> Object2Vertex_;
		QObjectList Result_;
	public:
		PluginTreeBuilder ();

		void AddObjects (const QObjectList&);
		void RemoveObject (QObject*);
		void Calculate ();
		QObjectList GetResult () const;
	private:
		void CreateGraph ();
		QMap<Edge_t, QPair<Vertex_t, Vertex_t>> MakeEdges ();
	};
}

#endif
