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

const Char_t* defaultInFile = "test.list";
const Char_t *defaultOutFile = "oFemtoDst_pp200_2015.root";

using namespace std;

class StFemtoDstMaker_HFT;
StFemtoDstMaker_HFT *femtoMaker = NULL;

//_________________
void FemtoDstMaker_pp200_y2015(const Char_t* inFileList = defaultInFile,
                               const Char_t* outFileName = defaultOutFile)
{
  cout << "***************************************************" << endl
       << "*  FemtoDstMaker for p+p 200 GeV year 2015 (HFT)  *" << endl
       << "*                        Start                    *" << endl
       << "***************************************************" << endl
       << endl;

  //Constants, cut and initial parameters
  Float_t cVtxZ[2] = {-70., 70.};
  Float_t cVtxR[2] = {0., 3.};
  Float_t cVtxXShift = 0.;
  Float_t cVtxYShift = 0.;
  Float_t cVtxVpdVzDiff[2] = {-7., 7.};
  Float_t cParticleMom[2] = {0.05, 1.9};
  Float_t cTrackDcaZ[2] = {-3., 3.};
  Float_t cTrackDcaPerp[2] = {0., 2.};
  Int_t   cTrackNHits[2] = {10, 50};
  Float_t cTrackEta[2] = {-1., 1.};
  Int_t   cTrackFlag[2] = {0, 1000};
  Bool_t  cZdcRefmultCorrection = true;   //Should be false for low energies

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

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

  //Create MuDst reader
  int nMaxFileToRead = 1e9;
  cout << Form("Try to read file: %s", inFileList) << 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);
  muDstMaker->SetStatus("BTofHit*",1);
  TChain *mCurrentTree = muDstMaker->chain();
  Long64_t mNEvents = mCurrentTree->GetEntries();
  cout << Form("Number of events in TTree: %d", mNEvents) << endl;

  //StFemtoDstMaker initialization
  femtoMaker = new StFemtoDstMaker_HFT(muDstMaker, outFileName);
  femtoMaker->SetTriggerId(480006); // trigger selection for pp200 y2015 P16id VPDMB
  femtoMaker->SetTriggerId(470001);
  femtoMaker->SetTriggerId(470004);
  femtoMaker->SetTriggerId(470007);
  femtoMaker->SetTriggerId(470014);
  femtoMaker->SetTriggerId(470017);
  femtoMaker->SetTriggerId(470904);
  femtoMaker->SetTriggerId(470914);
  femtoMaker->SetTriggerId(490004);
  femtoMaker->SetTriggerId(490007);
  femtoMaker->SetTriggerId(490904);
  femtoMaker->SetTriggerId(470401); // JP2
  femtoMaker->SetTriggerId(470402); // JP2-bsmd
  femtoMaker->SetTriggerId(470404); // JP1
  femtoMaker->SetTriggerId(470201); // BHT0*VPDMB-30
  femtoMaker->SetTriggerId(470202); // BHT1*VPDMB-30
  femtoMaker->SetTriggerId(470206); // BHT1*VPDMB-30-nobsmd
  femtoMaker->SetTriggerId(470211); // BHT0*VPDMB-5
  femtoMaker->SetTriggerId(480004); // VPDMB-novtx
  femtoMaker->SetTriggerId(480007); // VPDMB-5-trgonly
  femtoMaker->SetTriggerId(480904); // VPDMB-30
  femtoMaker->SetTriggerId(480401); // JP2
  femtoMaker->SetTriggerId(480404); // JP1
  femtoMaker->SetTriggerId(480411); // JP2
  femtoMaker->SetTriggerId(480414); // JP1
  femtoMaker->SetTriggerId(480201); // BHT0*VPDMB-5
  femtoMaker->SetTriggerId(480202); // BHT1*VPDMB-30
//  femtoMaker->SetTriggerId(480203); // BHT0*BBCMB
//  femtoMaker->SetTriggerId(480204); // BHT1*BBCMB
//  femtoMaker->SetTriggerId(480205); // BHT2*BBCMB
//  femtoMaker->SetTriggerId(480206); // BHT1*VPDMB-30-nobsmd
//  femtoMaker->SetTriggerId(490401); // JP2
//  femtoMaker->SetTriggerId(490402); // JP2-bsmd
//  femtoMaker->SetTriggerId(490404); // JP1
//  femtoMaker->SetTriggerId(470213); // BHT2*BBCMB
//  femtoMaker->SetTriggerId(470214); // BHT1*BBCMB
//  femtoMaker->SetTriggerId(470205); // BHT2*BBCMB

  femtoMaker->SetVtxZCut(cVtxZ[0], cVtxZ[1]);
  femtoMaker->SetVtxRCut(cVtxR[0], cVtxR[1]);
  femtoMaker->SetVtxShift(cVtxXShift, cVtxYShift);
  femtoMaker->SetVtxVpdVzDiffCut(cVtxVpdVzDiff[0], cVtxVpdVzDiff[1]);
  femtoMaker->SetParticleMomentum(cParticleMom[0], cParticleMom[1]);

  femtoMaker->SetVtxZCut(cVtxZ[0], cVtxZ[1]);
  femtoMaker->SetVtxRCut(cVtxR[0], cVtxR[1]);
  femtoMaker->SetVtxShift(cVtxXShift, cVtxYShift);
  femtoMaker->SetVtxVpdVzDiffCut(cVtxVpdVzDiff[0], cVtxVpdVzDiff[1]);
  femtoMaker->SetParticleMomentum(cParticleMom[0], cParticleMom[1]);
  femtoMaker->SetTrackDcaZ(cTrackDcaZ[0], cTrackDcaZ[1]);
  femtoMaker->SetTrackDcaPerp(cTrackDcaPerp[0], cTrackDcaPerp[1]);
  femtoMaker->SetTrackNHits(cTrackNHits[0], cTrackNHits[1]);
  femtoMaker->SetTrackEta(cTrackEta[0], cTrackEta[1]);
  femtoMaker->SetTrackFlag(cTrackFlag[0], cTrackFlag[1]);
  femtoMaker->SetCollisionType(false);
  femtoMaker->SetAuAuZdcCoincidenceEnergy(cZdcRefmultCorrection);
  femtoMaker->SetMuDstMaker(muDstMaker);

  //Chain initialization and loop over events
  mChain->Init();
  Int_t iReturn = 0;
  Int_t mNEventsProcessed = 0;
  Float_t mPerConst = 0.05;
  Float_t mPercentCounter = 0.0;
  Float_t mProgress = 0.;

  unsigned int mSubCounter = 1;              // time
  time_t mStartTime, mStopTime, mDiffTime;   // time
  float mFrac;                               // time
  mStartTime = time(0);                      // time

  for(Int_t iEvent=0; iEvent<mNEvents; iEvent++) {

    mProgress = (Float_t)iEvent / (Float_t)mNEvents;
    mNEventsProcessed++;

    if(mProgress >= mPercentCounter) {
      mPercentCounter += mPerConst;
      mStopTime = time(0);
      mDiffTime = difftime(mStopTime, mStartTime);
      mFrac = (float)mDiffTime*(float)(mNEvents - iEvent)/(float)iEvent;
      mSubCounter++;
      cout << Form("Processing progress: %4.2f%%. Time left: %.1 sec", mProgress*100., mFrac)
           << endl;
    }

    mChain->Clear();
    iReturn = mChain->Make(iEvent);
    if(iReturn != 0) {
      cout << "Error has been occured. Event processing has been stopped"
          << endl;
      break;
    }
  } //for(Int_t iEvent=0; iEvent<mNEvents; iEvent++)

  mChain->Finish();

  delete femtoMaker;
  delete mChain;
  cout << "***************************************************" << endl
       << "*  FemtoDstMaker for p+p 200 GeV year 2015 (HFT)  *" << endl
       << "*                        End                      *" << endl
       << "***************************************************" << endl
       << endl;
}
