#include "TROOT.h"
#include "TSystem.h"
#include "TChain.h"
#include "TFile.h"
#include "TString.h"
#include <iostream>

const Char_t *defaultInFile = "/star/data01/pwg/pusheax/dataset/st_physics_12130084_raw_5020002.MuDst.root";
const Char_t *defaultOutFile = "oFemtoDstInclusiveSelectorTest.root";

class StFemtoDstInclusiveSelector;
StFemtoDstInclusiveSelector *femtoDstIncSel;



void FemtoDstInclusiveSelectorTest(const Char_t *inFileList = defaultInFile,
				   const Char_t *outFileName = defaultOutFile,
				   const Bool_t  isAuAu = true) {
  std::cout << "************************************" << std::endl
            << "*  FemtoDstInclusiveSelectorTest   *" << std::endl
            << "*               Start              *" << std::endl
            << "************************************" << std::endl;
  Float_t vtxZ[2] = {-70., 70.};
  Float_t vtxR[2] = {0., 3.};
  Float_t vtxVpdVz[2] = {-7.,7.};
  Float_t vtxShift[2] = {0., 0.};
  Float_t particleMom[2] = {0.1, 2.1};
  Float_t trackDcaGlobal[2] = {-0.01, 5.};
  Float_t tpcKaonNSigma[2] = {-3., 3.};
  Float_t tpcKaonMom[2] = {0.1, 0.65};
  Int_t   trackNHits[2] = {14, 50};
  Int_t   trackNHitsFit[2] = {14, 50};
  Float_t trackEta[2] = {-1.1, 1.1};
  Float_t tofKaonMSqr[2] = {0.15, 0.40};
  Float_t tofKaonMom[2] = {0.1, 1.75};
  Bool_t  zdcRefmultCorrection = true;
  Float_t vtxRCenter[2] = {0., 0.};  //Center collision center (for low AuAu)

  //
  // Load libraries
  //
  std::cout << "Loading libraries..." << std::endl;
  gROOT->LoadMacro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C");
  loadSharedLibraries();
  gSystem->Load("libMinuit");
  gSystem->Load("StMuDSTMaker");
  gSystem->Load("StChain");
  gSystem->Load("StRefMultCorr");
  gSystem->Load("StFlowMaker");
  gSystem->Load("StFlowAnalysisMaker");
  gSystem->Load("StHbtMaker");
  gSystem->Load("StarClassLibrary");
  gSystem->Load("StFemtoDstMaker");
  std::cout << "Libraries have been successfully loaded" << std::endl;

  //
  // Create chain
  //
  StChain *chain = new StChain("StChain");
  chain->SetDebug(0);
  StMuDebug::setLevel(0);

  //
  // Create MuDst reader
  //
  int nMaxFileToRead = 1e9;
  std::cout << Form("Try to read file: %s", inFileList) << std::endl;
  StMuDstMaker *muDstMaker = new StMuDstMaker(0, 0, "", inFileList, "MuDst", nMaxFileToRead);
  muDstMaker->SetStatus("*",0);
  muDstMaker->SetStatus("Event*",1);
  muDstMaker->SetStatus("MuEvent*",1);
  muDstMaker->SetStatus("PrimaryVertices*",1);
  muDstMaker->SetStatus("PrimaryTracks*",1);
  muDstMaker->SetStatus("GlobalTracks*",1);
  muDstMaker->SetStatus("BTofHeader*",1);
  TChain *currentTree = muDstMaker->chain();
  Long64_t nEvents = currentTree->GetEntries();
  std::cout << Form("Number of events in TTree: %d", nEvents) << std::endl;

  //
  // Create StRefMultCorr and StFemtoDstInclusiveSelector
  //
  StRefMultCorr *refMult = new StRefMultCorr("refmult");
  
  femtoDstIncSel = new StFemtoDstInclusiveSelector(muDstMaker, outFileName);
  //
  // Global
  //
  femtoDstIncSel->SetCollisionTypeAuAu(isAuAu);
  femtoDstIncSel->SetRefmultCorrUtil(refMult);
  femtoDstIncSel->SetAuAuZdcCoincidenceEnergy(zdcRefmultCorrection);
  //
  // Event
  //
  //  femtoDstIncSel->SetTriggerId();
  femtoDstIncSel->SetVtxZCut(vtxZ[0], vtxZ[1]);
  femtoDstIncSel->SetVtxRCut(vtxR[0], vtxR[1]);
  femtoDstIncSel->SetVtxVpdVzDiffCut(vtxVpdVz[0], vtxVpdVz[1]);
  femtoDstIncSel->SetVtxShift(vtxShift[0], vtxShift[1]);
  femtoDstIncSel->AddTriggerId(350003); // mb-protected
  femtoDstIncSel->AddTriggerId(350013); // mb-protected
  femtoDstIncSel->AddTriggerId(350023); // mb-protected
  femtoDstIncSel->AddTriggerId(350033); // mb-protected
  femtoDstIncSel->AddTriggerId(350043); // mb-protected
  //
  // Track
  //
  femtoDstIncSel->SetParticleMomentum(particleMom[0], particleMom[1]);
  femtoDstIncSel->SetTrackDcaGlobal(trackDcaGlobal[0], trackDcaGlobal[1]);
  femtoDstIncSel->SetTrackNHits(trackNHits[0], trackNHits[1]);
  femtoDstIncSel->SetTrackNHitsFit(trackNHitsFit[0], trackNHitsFit[1]);
  femtoDstIncSel->SetTrackEta(trackEta[0], trackEta[1]);
  //
  // Other things I left default, just for test purpose
  //
  femtoDstIncSel->SetSelectPions(true);
  femtoDstIncSel->SetSelectKaons(true);
  femtoDstIncSel->SetSelectProtons(true);

  chain->Init();
  Int_t iReturn = 0;
  Int_t nEventsProcessed = 0;
  Float_t percentCounter = 0.01;
  Float_t progress = 0.;

  for (Int_t iEvent = 0; iEvent < nEvents; iEvent++) {
    progress = (Float_t)iEvent/(Float_t)nEvents;
    nEventsProcessed++;
    
    if(progress >= percentCounter) {
      percentCounter += 0.01;
      std::cout << Form("Processing progress: %4.2f%%", percentCounter*100.)
                << std::endl;
    }

    chain->Clear();
    iReturn = chain->Make(iEvent);
    if (iReturn != 0) {
      std::cout << "Error has been occured. Event processing has been stopped"
                << std::endl;
      break;
    }
  }

  chain->Finish();

  delete chain;

   std::cout << "**************************" << std::endl
            << "*    KaonFemtoDstMaker   *" << std::endl
            << "*          Finish        *" << std::endl
            << "**************************" << std::endl << endl;
}

