#ifndef MESHTOPOLOGY_H_
#define MESHTOPOLOGY_H_

#include <sstream>
#include <vector>
#include <set>
#include "include/CosiGlobal.h"
#include "include/onchipcommunication/CosiGlobal.h"
#include "networks/onchipcommunication/Specification.h"
#include "networks/onchipcommunication/PlatformInstance.h"
#include "networks/onchipcommunication/Implementation.h"
#include "networks/graph/RealWeightedGraph.h"
#include "platforms/onchipcommunication/Platform.h"
#include "io/onchipcommunication/ParquetCodeGen.h"
#include "io/onchipcommunication/PlacementParser.h"
#include "algorithms/graph/ShortestPath.h"
#include "algorithms/onchipcommunication/NetworkCost.h"
#include "io/onchipcommunication/ConfigParser.h"

namespace cosi {

namespace algorithms {

namespace onchipcommunication {

class MeshTopology {
public:
	MeshTopology(cosi::commstruct::onchipcommunication::Specification* Spec,
			cosi::platforms::onchipcommunication::Platform* Plt);
	virtual ~MeshTopology();
	bool Run();
	cosi::io::onchipcommunication::PlacementParser* GetPlacement();
	cosi::commstruct::onchipcommunication::Implementation* GetImplementation();
private:
	bool MeshSetup();
	int GetCommunicationCenter();
	void AddCommunicationCenter(int FirstNode);
	int GetNextNode();
	void AddNextNode(int NextNode);
	bool FindRoutes();
	bool FindRoutesIncremental();
	bool CleanUp();
	bool Floorplan();
	void Swap(int U , int V) ;
	double ComputeCost() ;

	cosi::commstruct::onchipcommunication::Specification* mSpec;
	cosi::platforms::onchipcommunication::Platform* mPlt;
	cosi::commstruct::onchipcommunication::Implementation* mI;
	cosi::io::onchipcommunication::PlacementParser* mPlacement;

	int mMeshSize;

	std::map<int,int> mRouterToCore;
	std::map<int,int> mCoreToRouter;
	std::vector< std::vector< int > > mIdMatrix;
	std::map<int, pair<int,int> > mRouterCoordinates;

	double mMinCost;
	std::map<int,int> mBestRouterToCore;
	std::map<int,int> mBestCoreToRouter;
	cosi::commstruct::onchipcommunication::Implementation* mBestI;
	cosi::io::onchipcommunication::PlacementParser* mBestPlacement;

	double mRoutingCost ;

};

}

}

}

#endif /*MESHTOPOLOGY_H_*/
