#include "VTPLib.h"

#include <iostream>
#include <iomanip>
#include <vector>
#include <math.h>

double cylinderReal(double x, double y, double z){
	// return analytical geodesic distance on a cylinder R 1 centered 0,0,0 with start at 1,0,0

	double dDist = sqrt((x-1)*(x-1) + y*y);
	double theta = (dDist*dDist/2 < 1e-3) ? 2.*asin(dDist/2): acos(1-dDist*dDist/2);

	return sqrt(theta*theta + z*z);
}

int main(int argc, char* argv[]){

	std::string meshFile;
	double lc;
	double distRef;

	if(argc > 3){
		meshFile = argv[1];
		lc = std::stod(argv[2]);
		distRef = std::stod(argv[3]);
	} else {
		std::cerr << "Not enough." << std::endl;
		return 1;
	}

	// définir points arrivée et départ
	/*
	double start[3];
	double target[3];
	if(argc > 9){
		meshFile = argv[1];
		lc = std::stod(argv[2]);
		distRef = std::stod(argv[3]);
		for (int i=0;i<3;++i)
		  start[i] = std::stod(argv[4+i]);
		for (int i=0;i<3;++i)
		  target[i] = std::stod(argv[7+i]);
		
	} else {
		std::cerr << "Not enough." << std::endl;
		return 1;
	}

	VTPLib algo(meshFile);

	algo.propagate(start);
	double distance=algo.getDistance(target);

	std::cout << std::scientific << std::setprecision(10);

	double error = fabs((distance-distRef)/distRef);

	std::cout << "h= " << lc << " n= " << distRef/lc << " nvert= " << algo.getNumberVertices() << " Lex= " << distRef << " Lapprox= " << distance << " e= " << error << std::endl;
	*/

//	algo.printMSHDistances("results.msh");

	// code Alex pour imprimer les erreurs absolues de référence
	double start[3] = {1.,0.,0.};

	VTPLib algo(meshFile);

	algo.propagate(start);

	std::string mshFilePrint = "cylindreErrorAbs_" + std::to_string(lc) + ".msh";

	int succeed = algo.printMSHErrorAbs(mshFilePrint, cylinderReal);

	if(succeed == 0){
		std::cerr << "Error print msh" << std::endl;
		return 1;
	} else {
		std::cout << "All done. Data saved in file : " << mshFilePrint << std::endl;
	}

	return 0;
}
