#include <iostream>
#include <fstream>
#include <limits>
#include <iomanip>

#include "FastMarching.h"
#include "gmshNode.h"
#include "gmshElement.h"
#include "GmshGlobal.h"
#include "FMField.h"
#include "FindMiniPath.h"


bool getParameters(int argc, char* argv[], std::string* ptsFile, double* lc_, double* distRel){
  if(argc > 3){
    *ptsFile = argv[1];
    *lc_ = atof(argv[2]);
    *distRel = atof(argv[3]);
    return true;
  } else {
    *ptsFile = "";
    *lc_ = 0.;
    *distRel = 0.;
    return false;
  }
}

int main(int argc, char* argv[]){
  std::string fileMesh;
  double lc, valReal;
  
  if(!getParameters(argc,argv,&fileMesh,&lc,&valReal)){
      std::cout<<"\nWrong arguments."<<std::endl;
      return 1;
  }
    
  // std::vector<SPoint3> seeds{SPoint3(-.5,-.5,0.),SPoint3(.5,.5,0.)}; // "carre" case
  // std::vector<SPoint3> seeds{SPoint3(1.,0.,0.),SPoint3(-1,0.,5.)}; // "labysmooth" case
  // std::vector<SPoint3> seeds{SPoint3(0.,0.,1.), SPoint3(sqrt(2)/2,sqrt(2)/2,0.)}; // sphere
  double scale = 1.;
  std::vector<SPoint3> seeds{SPoint3(scale,0.,0.),SPoint3(-scale,0.,3.141592653589793*scale)}; // scale case A
  // std::vector<SPoint3> seeds{SPoint3(scale,0.,0.),SPoint3(0,scale,3.141592653589793*scale/2)}; // scale case B
  
  GmshInitialize();
  FM::FMModel *model = new FM::FMModel();
  model -> readMSH(fileMesh);
  model -> buildAdj(1<<(model->getDim()-1));

  FMSpeedConstant speed;
  FastMarch_c fastM(speed);
  
  map<FM::gmshNode,FastMarch_c::FieldPair> initvals;
  set<FM::gmshElement> bndinit;

  InitPt(model,seeds[0],initvals,bndinit);
  fastM.Init(initvals,bndinit);
  fastM.Propagate();

  FMField field;
  field.Import(fastM);
  
  double dist = field(seeds[1]).first;
  double error = (dist -valReal)/valReal;
  
  std::cout << FM::FMModel::Ptr->v_to_ele.size() << " ";
  std::cout << setprecision(numeric_limits<double>::max_digits10);
  std::cout << " " << valReal/lc << " "<< error << std::endl;
  
  return 0;
}
