#pragma once
#include <string>
#include <vector>
#include <fstream>
#include <QPoint>
#include <map>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>



struct SolutionPointData {
	int iteration;
	double objectiveFunction;
	int particleNumber;
	std::vector<bool> bitVec;
};
struct GraphDataPoint {
	double x;
	double y;
	SolutionPointData* orginalPoint;
	QColor color;
	GraphDataPoint() :x(0), y(0), orginalPoint(nullptr) {}
	GraphDataPoint(double x, double y, SolutionPointData* orginalPoint = nullptr);
	GraphDataPoint(double x, double y, QColor color, SolutionPointData* orginalPoint = nullptr);
	bool existLink();
	QPointF toQPointF() const;
	double squaredDistance(QPointF& graphPoint) const;
};

class RunData
{
public:
	std::string name;
	std::string information;
	std::string filePath;
	std::vector<SolutionPointData> solutionVec;
	RunData();
	RunData(std::string filePath);
	

	std::vector<GraphDataPoint> bestSolutionPerIteration;
	std::vector<GraphDataPoint> averageSolutionPerItertion;
	std::vector<GraphDataPoint> minSolutionPerItertion;
	std::vector<GraphDataPoint> maxSolutionPerItertion;
	std::vector<GraphDataPoint> dotsForDistribution;
	std::vector<GraphDataPoint> dotsForBitField;
	std::vector<GraphDataPoint> meanHammingDistancePerIteration;
	std::map<int, std::vector<GraphDataPoint>> particleMap;
private:
	bool badFileFlag = false;
	std::fstream fileStream;
	int actualLine = 0;
	void getLine(std::string& bufferString);

	void calculateBestAndAverageIter();
	void calculateParticleSolution();
	void calculateDotsForDistribution();
	void calculateBitFieldData();
	void calculateMeanHammingDistance();
	int static hammingdistance(std::vector<bool>& bitVecA, std::vector<bool>& bitVecB);
	double static meanHammingDistance(std::vector<SolutionPointData>::iterator begin, std::vector<SolutionPointData>::iterator end);

	boost::multiprecision::cpp_int binominal(const int n, const int k);
	boost::multiprecision::cpp_int positionInPermutation(std::vector<bool>::iterator begin, std::vector<bool>::iterator end, int amountOfSetBits);
};

