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

using namespace std;



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



void FemtoDstMaker_mesons_pp510_y2011_PicoDst(const Char_t* inFileList = defaultInFile,
                                              const Char_t* outFileName = defaultOutFile)
{
  cout << "*******************************************************" << endl
       << "*  FemtoDstMaker for p+p 510 GeV year 2011 (PicoDst)  *" << 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.15, 1.65};
  Float_t cTrackDcaGlobal[2] = {-0.01, 3.};
  Int_t   cTrackNHitsFit[2] = {5, 50};
  Float_t cTrackEta[2] = {-1., 1.};
  Int_t   cTrackFlag[2] = {0, 1000};

  Float_t cPionTpcNSigmaElectron[2] = {-2., 2.};
  Float_t cPionTpcNSigmaPion[2] = {-3., 3.};
  Float_t cPionTpcNSigmaKaon[2] = {-2., 2.};
  Float_t cPionTpcNSigmaProton[2] = {-3., 3.};

  Float_t cKaonTpcNSigmaElectron[2] = {-3., 3.};
  Float_t cKaonTpcNSigmaPion[2] = {-2., 2.};
  Float_t cKaonTpcNSigmaKaon[2] = {-3., 3.};
  Float_t cKaonTpcNSigmaProton[2] = {-3., 3.};
  //
  // Load libraries
  //
  std::cout << "Loading libraries..." << std::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");
  std::cout << "Libraries have been successfully loaded" << std::endl;
  //
  // Create chain
  //
  StChain *mChain = new StChain("StChain");
  mChain->SetDebug(0);

  //
  // Create PicoDst reader
  //
  int nMaxFileToRead = 1e9;
  std::cout << Form("Try to read file: %s", inFileList) << std::endl;
  StPicoDstMaker *picoMaker = new StPicoDstMaker(0, inFileList);
  //
  // StFemtoDstPicoRun11Maker initialization
  //
  femtoDstPicoMaker = new StFemtoDstPicoRun11Maker(picoMaker, outFileName);

  //
  // Event cuts
  //
  femtoDstPicoMaker->SetVtxZCut(cVtxZ[0], cVtxZ[1]);
  femtoDstPicoMaker->SetVtxRCut(cVtxR[0], cVtxR[1]);
  femtoDstPicoMaker->SetVtxShift(cVtxXShift, cVtxYShift);
  femtoDstPicoMaker->SetVtxVpdVzDiffCut(cVtxVpdVzDiff[0], cVtxVpdVzDiff[1]);
  //
  // Track cuts
  //
  femtoDstPicoMaker->SetParticleMomentum(cParticleMom[0], cParticleMom[1]);
  femtoDstPicoMaker->SetTrackDcaGlobal(cTrackDcaGlobal[0], cTrackDcaGlobal[1]);
  femtoDstPicoMaker->SetTrackNHitsFit(cTrackNHitsFit[0], cTrackNHitsFit[1]);
  femtoDstPicoMaker->SetTrackEta(cTrackEta[0], cTrackEta[1]);

  //Chain initialization and loop over events
  mChain->Init();
  TChain *mCurrentTree = picoMaker->chain();
  Long64_t mNEvents = mCurrentTree->GetEntries();
  std::cout << Form("Number of events in TTree: %d", mNEvents) << std::endl;

  Int_t iReturn = 0;
  Int_t mNEventsProcessed = 0;
  Float_t mPercentStep = 0.05;
  Float_t mPercentCounter = mPercentStep;
  Float_t mProgress = 0.;

  time_t mStartTime, mStopTime, mDiffTime;   // time
  float mFrac;                               // time
  mStartTime = time(0);                      // time

  for (int iEvent=0; iEvent<mNEvents; iEvent++)
  {
    mProgress = (Float_t)iEvent/(Float_t)mNEvents;
    mNEventsProcessed++;

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

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

  mChain->Finish();
  delete femtoDstPicoMaker;
  delete mChain;
}
