#ifndef COMPONENTPOSITION_H_
#define COMPONENTPOSITION_H_

#include <vector>
#include <set>
#include <map>
#include <list>
#include "float.h"
#include "math.h"
#include "quantities/onchipcommunication/IpGeometry.h"
#include "environment/onchipcommunication/InstallationSite.h"
#include "environment/onchipcommunication/InstallationFace.h"

namespace cosi {

namespace rules {

namespace onchipcommunication {

using namespace cosi::quantity::onchipcommunication;

using namespace cosi::environment::onchipcommunication;

using namespace std ;

class ComponentPosition {
public:
	ComponentPosition(std::vector< IpGeometry > Ip, IpGeometry ChipArea, double Density);

	virtual ~ComponentPosition();

	list< int > Neighbors(int V, int D, double Span);
	double Distance( int U , int V ) ;
	double GetX(int V) ;
	double GetY(int V) ;

	int Size() ;

	std::vector< InstallationSite > GetInstallationSites() ;

private:

	void SetUpCoordinates(std::vector< IpGeometry > Ip, IpGeometry ChipArea) ;
	set< pair< double , double > > IntervalsX( double pY ) ;
	list< int > LocalSearch( int A , double X , double Y , double D ) ;
	double VtoAdist( double X , double  Y , int A ) ;
	double VtoAdist( int V , int A ) ;
	double Distance( double X1 , double Y1 , double X2 , double Y2 ) ;
	Position Closest(int A, int V) ;

	std::vector< IpGeometry > mIp;
	std::vector< InstallationFace > mInstallationFaces;
	std::vector< InstallationSite > mInstallationSites;
	std::vector< InstallationSite > mCandidateCenters;
	std::vector< int > mCentersId;

	std::vector< double > mSXpos;
	std::vector< double > mSYpos;
	std::vector< double > mDXpos;
	std::vector< double > mDYpos;
	std::vector< double > mXbl;
	std::vector< double > mYbl;
	std::vector< double > mXtr;
	std::vector< double > mYtr;

	std::set< double > mY ;

	double mH , mW , mA , mDensity , mStep;
	int mNr ;

};

}
}
}

#endif /*COMPONENTPOSITION_H_*/
