/*******************************************************************************
 * \file Make a simple cut on generated photon paths
*******************************************************************************/

// C++ standard library
#include<iostream>
#include<sstream>
#include<iomanip>
#include<vector>
#include<cmath>
#include<cstdlib>

// ROOT
#include "TRandom3.h"
#include "TFile.h"
#include "TPolyLine3D.h"
#include "TPolyMarker3D.h"
#include "TAxis3D.h"
#include "TView.h"
#include "TView3D.h"
#include "TCanvas.h"
#include "TPad.h"

// JPP
#include "Jeep/JParser.hh"
#include "JMarkov/JPhotonPath.hh"
#include "JMarkov/JPhotonPathReader.hh"
#include "JMarkov/JPhotonPathWriter.hh"
using namespace std ;

// this little line removes the make_field macro defined in JParser.hh
// so that we can call the
// JPARSER::make_field(T,string) function ourselves
#undef make_field
using namespace JPP;

int main( int argc, char** argv ) {
  cout << "JMarkovPathSelecter" << endl 
       << "Written by Martijn Jongen" << endl 
       << endl ; 
  cout << "Type '" << argv[0] << " -h!' to display the command-line options." << endl ;
  cout << endl ;

  string ifname = "" ;
  string ofname = "" ;
  // parameters to simulate shadowing
  // (remove all paths intersecting a sphere of radius r centered at (x,y,z)
  bool shadow = false ;
  double x ;
  double y ;
  double z ;
  double r ;

  try {
    JParser<string> zap ; // this argument parser can handle strings    
    zap["f"] = make_field(ifname,"input file name (binary file containing JPhotonPaths)") ;
    zap["o"] = make_field(ofname,"output file name (binary file containing a selection of the JPhotonPaths)") ;
    zap["shadow"] = make_field(shadow,"flag to turn on shadowing") ;
    zap["x"] = make_field(x,"x coordinate for shadowing") = 0 ;
    zap["y"] = make_field(y,"y coordinate for shadowing") = 0 ;
    zap["z"] = make_field(z,"z coordinate for shadowing") = 0.5*37 ;
    zap["r"] = make_field(r,"radius for shadowing") = 0.2159 ;

    if (zap.read(argc, argv) != 0) {
      return 1 ;
    }
  }
  catch(const exception &error) {
    // do not ignore exceptions
    cerr << error.what() ;
    exit(1) ;
  }

  // print settings
  cout << "SELECTION CRITERIA:" << endl ;
  if( shadow ) {
    cout << "Will exclude all paths intersecting a sphere of radius " << r << " m"
	 << ", centered at (" << x << ", " << y << ", " << z << ")" << endl ;
  }
  cout << endl ;

  // read the paths from the file
  JMARKOV::JPhotonPathReader reader ;
  reader.open(ifname.c_str()) ;
  if( !reader.is_open() ) {
    cerr << "FATAL ERROR: unable to open input file '" << ifname << "'." << endl ;
    exit(1) ;
  }

  int nread = 0 ;
  JMARKOV::JPhotonPath* p = NULL ;
  cout << "Reading file" << endl ;
  vector<JMARKOV::JPhotonPath> paths ;
  while( reader.hasNext() ) {
    p = reader.next() ;
    paths.push_back(*p) ;
    ++nread ;
  }

  if( nread == 0 ) {
    cerr << "FATAL ERROR: could not read any JPhotonPaths from the input file '" << ifname << "'." << endl ;
    exit(1) ;
  }
  cout << "Done reading file. Read " << nread << " paths from it." << endl ;
  cout << endl ;

  JGEOMETRY3D::JPosition3D DOMpos(x,y,z) ;

  // apply selection and write the selected paths to output
  int nselected = 0 ;
  cout << "Writing selected paths to '" << ofname << "'." << endl ;
  JMARKOV::JPhotonPathWriter writer ;
  writer.open(ofname.c_str()) ;
  for( vector<JMARKOV::JPhotonPath>::iterator it=paths.begin() ; it!=paths.end() ; ++it ) {
    if( shadow && it->hitsSphere(DOMpos,r) ) continue ;

    ++nselected ;
    writer.put( *it ) ;
  }
  writer.close() ;
  cout << endl ;

  cout << "Selected " << nselected << " / " << nread 
       << " photon paths." << endl
       << "Output written to '" << ofname << "'." << endl ;
}