/**
 * \file TrkProcess.cpp
 * \author Elena Vannuccini
 */
#include <TrkProcess.h>
#include <iostream>
using namespace std;
/**
 * Create TrkProcess object, initializing the tracker processing variables at default values
 */
TrkProcess::TrkProcess(){
    
    idrun = 0;
//    dbg_mode.SetNone();
    get1  = 0;
    full1 = 0;
    geth  = 0;
    get2  = 1;
    standalone = false;
    frame2 = "root";
    frame1 = "root";
    frameh = "root";
    outdir =  gSystem->WorkingDirectory(); 
    pfolder = "/TrackerFolder"; 
    if      (!frame2.CompareTo("root", TString::kIgnoreCase))  ifroot2 = true;		
    else if (!frame2.CompareTo("hbook", TString::kIgnoreCase)) ifroot2 = false;
    
    if      (!frame1.CompareTo("root", TString::kIgnoreCase))  ifroot1 = true;		
    else if (!frame1.CompareTo("hbook", TString::kIgnoreCase)) ifroot1 = false;

    if      (!frameh.CompareTo("root", TString::kIgnoreCase))  ifrooth = true;		
    else if (!frameh.CompareTo("hbook", TString::kIgnoreCase)) ifrooth = false;

    file1 = "";
    file2 = "";
    
    ostatus = 0;

    npar = 0;

    nskip = 0;

//     TrkParams::SetTrackingMode();
//     TrkParams::SetPrecisionFactor(); 
//     TrkParams::SetStepMin();   
    TrkParams::SetMiniDefault();
    TrkParams::SetPFA();
};
	
/**
 * Create TrkProcess object, initializing the tracker processing variables according to input parameters.
 * @param run Run ID
 * @param f2 Pointer to output level2 file
 */
TrkProcess::TrkProcess(ULong64_t run, TFile *f2){
	
    idrun = run;
//    DEBUG = false;
//    VERBOSE = false;
//    dbg_mode.SetWarning();
    get1  = 0;
    full1 = 0;
    get2 = 1;
    geth = 0;
    standalone = false;
    frame2 = "root";
    frame1 = "root";
    frameh = "root";
    pfolder = "/TrackerFolder"; 
    file1 = "";
    if(f2->IsOpen()){
	file2  = f2->GetPath();
	outdir = gSystem->DirName(gSystem->DirName(file2));
	// check if the indicated output directory exists
	FileStat_t t;
	if( gSystem->GetPathInfo(outdir.Data(),t) )throw -12;
    }else{ 
	file2 = "";    
	outdir =  gSystem->WorkingDirectory();
    }; 

    if      (!frame2.CompareTo("root", TString::kIgnoreCase))  ifroot2 = true;		
    else if (!frame2.CompareTo("hbook", TString::kIgnoreCase)) ifroot2 =false;
    
    if      (!frame1.CompareTo("root", TString::kIgnoreCase))  ifroot1 = true;		
    else if (!frame1.CompareTo("hbook", TString::kIgnoreCase)) ifroot1 =false;

    if      (!frameh.CompareTo("root", TString::kIgnoreCase))  ifrooth = true;		
    else if (!frameh.CompareTo("hbook", TString::kIgnoreCase)) ifrooth =false;

    ostatus = 0;
    
    npar=0;
	
    nskip = 0;

//     TrkParams::SetTrackingMode();
//     TrkParams::SetPrecisionFactor(); 
//     TrkParams::SetStepMin();   
    TrkParams::SetMiniDefault();
    TrkParams::SetPFA();

};
/**
 * Set processing variables according to input custom parameters
 */	
int TrkProcess::HandleCustomPar(int ncustom, char *vcustom[]){

    for (int i=0; i< ncustom; i++){

	// -----------------------------------------------------//
	if (!strcmp(vcustom[i], "-processFolder")){
	    if (++i >= ncustom) throw -3;
	    pfolder = vcustom[i];
	    continue;
	}  
	// -----------------------------------------------------//    
	if (!strcmp(vcustom[i], "--get1") || !strcmp(vcustom[i], "--get-level1") ){
	    get1  = 1;	
	    full1 = 0;
	    continue;
	}  
	// -----------------------------------------------------//    
	if (!strcmp(vcustom[i], "--get1-full") || !strcmp(vcustom[i], "--get-level1-full") ){
	    get1  = 1;	    
	    full1 = 1;
	    continue;
	}  
	// -----------------------------------------------------//    
	if (!strcmp(vcustom[i], "--geth") || !strcmp(vcustom[i], "--get-hough") ){
	    geth = 1;
	    continue;
	}  
	// -----------------------------------------------------//    
	if (!strcmp(vcustom[i], "--dontget2") ||!strcmp(vcustom[i], "--dontget-level2") ){
	    get2 = 0;
	    continue;
	}  
	// -----------------------------------------------------//    
	if (!strcmp(vcustom[i], "--standalone") || !strcmp(vcustom[i], "-s")){
	    standalone = true;
	    continue;
	}  
	// -----------------------------------------------------//    
	if (!strcmp(vcustom[i], "-processFile1")){
	    if (++i >= ncustom) throw -3;
	    get1 = 1;
	    file1 = vcustom[i];
	    continue;
	}  
	// -----------------------------------------------------//    
	if (!strcmp(vcustom[i], "-frame1")){
	    if (++i >= ncustom)throw -3;
	    get1 = 1;
	    frame1 = vcustom[i];						
	    continue;
	}  
	// -----------------------------------------------------//    
	if (!strcmp(vcustom[i], "-frame2")){
	    if (++i >= ncustom)throw -3;
	    get2 = 1;
	    frame2 = vcustom[i];
	    continue;
	}  
	// -----------------------------------------------------//    
	if (!strcmp(vcustom[i], "-pfa")){
	    if (++i >= ncustom)throw -3;
	    TrkParams::SetPFA(atoi(vcustom[i]));
	    continue;
	}  
	// -----------------------------------------------------//    
	if (!strcmp(vcustom[i], "-skip")){
	    if (++i >= ncustom)throw -3;
	    nskip = atoi(vcustom[i]);
	    continue;
	}  
	// -----------------------------------------------------//    
	if ( atoi(vcustom[i]) < 0){
	    if (++i >= ncustom)throw -3;
	    partype[npar]=-1*atoi(vcustom[i-1]);
	    parpath[npar]=vcustom[i];
	    npar++;
	    continue;
	}  
	// -----------------------------------------------------//    
	if (!strcmp(vcustom[i], "--verbose") || !strcmp(vcustom[i], "-v")){
	    TrkParams::SetVerboseMode();
	    continue;
	}
	// -----------------------------------------------------//    
	if (!strcmp(vcustom[i], "--warning") || !strcmp(vcustom[i], "-w")){
	    TrkParams::SetWarningMode();
	    continue;
	}
	// -----------------------------------------------------//    
	if (!strcmp(vcustom[i], "--help") || !strcmp(vcustom[i], "-h")){
	    PrintHelp();
	    return 1;
	}
	// -----------------------------------------------------//    
	else if (!strcmp(vcustom[i], "--debug") || !strcmp(vcustom[i], "-d")){
	    TrkParams::SetDebugMode();
	    continue;
	};
    }	
        	
    if      (!frame2.CompareTo("root", TString::kIgnoreCase))  ifroot2 = true;		
    else if (!frame2.CompareTo("hbook", TString::kIgnoreCase)) ifroot2 =false;
    else    throw -201;
    
    if      (!frame1.CompareTo("root", TString::kIgnoreCase))  ifroot1 = true;		
    else if (!frame1.CompareTo("hbook", TString::kIgnoreCase)) ifroot1 =false;
    else    throw -201;
   	
    if      (!frameh.CompareTo("root", TString::kIgnoreCase))  ifrooth = true;		
    else if (!frameh.CompareTo("hbook", TString::kIgnoreCase)) ifrooth =false;
    else    throw -201;

    if(get1 && !get2)full1=true;

    ostatus = 0;

    return 0;

};
/**
 * \brief Process Level0 event
 * @param l0_event Pointer to an object of the tracker level0 class
 * Starting from a Level0 object, this routine fills the level0 common, then calls 
 * the fortran routines, which process the event and fill level1 and level2 commons.
 */
void TrkProcess::ProcessEvent(TrkLevel0 *l0_event){

    // fill Level0 common from Level0 object
    l0_event->GetLevel0Struct();
    // process the event Level0->Level1->Level2
    int F77err = 0;
    //
    reductionflight_(&F77err);
    if(F77err < 0)throw F77err;
    //
    if(get2) analysisflight_();
    //
    ostatus = F77err;
    
};
		
void TrkProcess::Dump(){
    cout << endl;
    cout << " |-------------------------------------| "<<endl;
    cout << "   tracker-processing input-parameters   "<< endl;
    cout << " |-------------------------------------| "<<endl;
    cout << "   idRun           " << idrun << endl;
    cout << "                   (skip " << nskip <<" events)"<< endl;    
    cout << "   get level1      " << get1 << endl;
    cout << "   full level1     " << full1 << endl;
    cout << "   get level2      " << get2 << endl;
    cout << "   get hough       " << geth << endl;
//    cout << " frame1          " << frame1 << endl;
//    cout << " frame2          " << frame2 << endl;
//    cout << " frameh          " << frame2 << endl;
//    cout << " file1           " << file1 << endl;
    cout << "   output file     " << file2 << endl;
//    cout << " outdir          " << outdir << endl;
//    cout << " process folder  " << pfolder << endl;
//    cout << " standalone mode " << standalone << endl;
    for(int i=0; i<npar; i++)
	cout << "   force loading parameters of type "<<partype[i]<<" from <--- "<<parpath[i]<<endl;
    cout<<endl;

//     cout << " debug mode      warning " << dbg_mode.warning << endl;
//     cout << " debug mode      verbose " << dbg_mode.verbose << endl;
//     cout << " debug mode      debug   " << dbg_mode.debug << endl << endl;
    
}

void TrkProcess::PrintHelp(){

    printf( "\n\n +TRK [ options ] \n \n");
//    printf( "\n --version          : Print tracker software version and exit ");	
    printf( "Options:");
    printf( "\n --help, -h                     : Print this help and exit ");	
//    printf( "\n -idRun RUN         : ID number of the run to be processed (for reprocessing RUN=0) \n");
//    printf( "\n -outDir OUTDIR     : Path where to put the LEVEL2 output                    [default ./ ] ");
//    printf( "\n -processFolder DIR   : Directory (relative to OUTDIR) for other output files  [default TrackerFolder/ ] ");
//    printf( "\n -processFile FILE  : Name of the LEVEL2 output file                         [default RUN.Level2.root]");
//    printf( "\n -processFile1 FILE   : Name of the LEVEL1 output file                         [default RUN.Level1.rz]");
//    printf( "\n -frame1 FRAME        : type of output for LEVEL1, root/hbook                  [default hbook ] ");
//    printf( "\n -frame2 FRAME        : type of output for LEVEL2, root/hbook                  [default root  ] ");		
    printf( "\n --get1, --get-level1           : get LEVEL1 output (store only cluster associated to tracks) [default (no LEVEL1 output) ]  ");
    printf( "\n --get1-full, --get-level1-full : get LEVEL1 output (store all clusters)                      [default (no LEVEL1 output) ]  ");
    printf( "\n --dontget2, --dontget-level2   : do not get LEVEL2 output                                    [default (get LEVEL2 output)]");
    printf( "\n --geth,, --get-hough           : get Hough-transform output                                  [default (no Hough-t. output) ]  ");
    printf( "\n -pfa PFAID                     : type of output for LEVEL2, root/hbook                       [default 14 (COG4)  ] ");		
    printf( "\n -N PATH                        : load parameter of type N=1,2... from PATH                   [default (from DB)  ] ");   
    printf( "\n --verbose, -v                  : verbose mode ");	
    printf( "\n --debug, -d                    : debug mode ");	
    printf( "\n --warning, -w                  : warning mode ");	
    printf( "\n -skip NEV                      : skip first NEV events from each run ");	
//    printf( "\n --standalone, -s   : standalone mode (without RunInfo) ... but it might not work \n");	
//    printf( "\n -host HOST         : Name for the host                                      [default mysql://localhost/pamelaprod ]");
//    printf( "\n -user USER         : Username for the DB                                    [default anonymous] ");
//    printf( "\n -psw  PSW          : Password for the DB                                    [default (none)]\n \n \n");
    

}
