#ifndef HEURISTICCHAINGENERATOR_H_
#define HEURISTICCHAINGENERATOR_H_

#include <iostream>
#include <iterator>
#include <string>
#include <list>
#include <map>
#include <algorithm>
#include "float.h"
#include "networks/wiredbas/WiredBasSpecificaion.h"
#include "networks/wiredbas/WiredBasPlatformInstance.h"
#include "networks/wiredbas/WiredBasImplementation.h"
#include "platforms/wiredbas/BusPlatform.h"

namespace cosi {

namespace algorithms {

namespace wiredbas {

using namespace std;

class Chain {
public:
	Chain(int Id);
	double Cost;
	double Delay;
	double Length;
	double Bandwidth;
	list< int > C;
	void AddLeft(int pV);
	void AddRight(int pV);
	int GetLeft();
	int GetRight();
	bool IsLeft(int pV);
	bool IsRight(int pV);
	bool Contains(int pV);
	int size() const;
	bool operator <(const Chain& C) const;
	set< int > NodeSet();
};

class HeuristicChainGenerator {
public:
	HeuristicChainGenerator(cosi::commstruct::wiredbas::Specification* pSpec,
			cosi::platforms::wiredbas::BusPlatform* pPlt);
	virtual ~HeuristicChainGenerator();
	void Run();
	std::list< cosi::commstruct::wiredbas::Implementation* > GetChains();
	std::set<int> GetRouters( ) ;
private:

	bool IsChainExtensible(Chain C , int RouterId , Position RotuerPosition);
	bool CheckLatency(cosi::commstruct::wiredbas::Implementation* I );
	cosi::commstruct::wiredbas::Implementation* GenerateBusInstance(Chain C , int RouterId , Position RotuerPosition);

	cosi::commstruct::wiredbas::Specification* mSpecification;
	cosi::platforms::wiredbas::BusPlatform* mPlt;


	cosi::commstruct::wiredbas::Implementation
				* mCompleteWiring ;

	cosi::commstruct::wiredbas::Implementation* GenerateCompleteWiring(map<int,Position> pRouters) ;

	set<int> mAssigned;

	Position mGatewayPosition;
	int mGateway;

	int mNsensors;
	int mNactuators;
	map<int,set<Chain> > mChains ;
	std::set<int> mRouters ;
	std::list<cosi::commstruct::wiredbas::Implementation* > mChainImplementation ;
};

}

}

}

#endif /*HEURISTICCHAINGENERATOR_H_*/
