#ifndef STFEMTODSTMAKER_HFT_HH
#define STFEMTODSTMAKER_HFT_HH

#include "StMaker.h"
#include "StThreeVector.hh"
#include "StThreeVectorF.hh"
#include "StPhysicalHelixD.hh"
#include "StRefMultCorr/StRefMultCorr.h"

#include "StFemtoEvent.h"
#include "StFemtoTrack.h"

#include "StMuDSTMaker/COMMON/StMuDstMaker.h"
#include "StMuDSTMaker/COMMON/StMuDst.h"
#include "StMuDSTMaker/COMMON/StMuEvent.h"
#include "StMuDSTMaker/COMMON/StMuTrack.h"
#include "StMuDSTMaker/COMMON/StMuPrimaryVertex.h"
#include "StMuDSTMaker/COMMON/StMuBTofPidTraits.h"
#include "StMuDSTMaker/COMMON/StMuBTofHit.h"

#include <TString.h>
#include <TFile.h>
#include <TLorentzVector.h>
#include <TTree.h>
#include <TH1.h>
#include <TH2.h>

#include <vector>
#include <iostream>

#ifndef St_NO_NAMESPACES
using namespace std;
#endif

//
// Predefinisions
//
class StFemtoEvent;
class StFemtoTrack;

class StMuDst;
class StMuDstMaker;
class StMuEvent;
class StMuTrack;

//_________________
class StFemtoDstMaker_HFT : public StMaker {

 public:
  StFemtoDstMaker_HFT(StMuDstMaker *muMaker,
                      const Char_t *oFileName);
  ~StFemtoDstMaker_HFT();

  void Clear(Option_t *option = "");
  Int_t Init();
  Int_t Make();
  Int_t Finish();

  void CleanVariables();

  void SetCompressionLevel(Int_t comp)        { mCompression = comp; }

  //
  // Setters
  //
  // global parameters of the maker
  void SetCollisionType(const Bool_t& type)   { mCollisionType = type; }
  void SetMuDstMaker(StMuDstMaker *maker)     { mMuDstMaker = maker; }
  void SetRefmultCorrUtil(StRefMultCorr* rf)  { mRefMultCorrUtil = rf; }
  void SetAuAuZdcCoincidenceEnergy(const Bool_t &correct) { mAuAuCorrectZdc = correct; }

  // event
  void SetTriggerId(const UInt_t& id);
  void SetVtxZCut(const Float_t& lo, const Float_t& hi)   { mPrimVtxZ[0]=lo; mPrimVtxZ[1]=hi; }
  void SetVtxRCut(const Float_t& lo, const Float_t& hi)   { mPrimVtxR[0]=lo; mPrimVtxR[1]=hi; }
  void SetVtxShift(const Float_t& xShift, const Float_t& yShift) { mPrimVtxXShift=xShift; mPrimVtxYShift=yShift; }
  void SetVtxVpdVzDiffCut(const Float_t& lo, const Float_t& hi)  { mPrimVtxVpdVzDiff[0]=lo; mPrimVtxVpdVzDiff[1]=hi;}

  // track
  void SetParticleMomentum(const Float_t& lo, const Float_t& hi) { mTrackMomentum[0]=lo; mTrackMomentum[1]=hi; }
  void SetTrackDcaPerp(const Float_t& lo, const Float_t& hi)  { mTrackDcaPerp[0]=lo; mTrackDcaPerp[1]=hi; }
  void SetTrackDcaZ(const Float_t& lo, const Float_t& hi)  { mTrackDcaZ[0]=lo; mTrackDcaZ[1]=hi; }
  void SetTrackNHits(const Int_t& lo, const Int_t& hi)    { mTrackNHits[0]=lo; mTrackNHits[1]=hi; }
  void SetTrackEta(const Float_t& lo, const Float_t& hi)  { mTrackEta[0]=lo; mTrackEta[1]=hi; }
  void SetTrackFlag(const Short_t& lo, const Short_t& hi) { mTrackFlag[0]=lo; mTrackFlag[1]=hi;}

  //
  // Exclusion cuts
  //
  void SetRemovePions(Bool_t &remove)    { mRemovePions = remove; }
  void SetRemoveKaons(Bool_t &remove)    { mRemoveKaons = remove; }
  void SetRemoveProtons(Bool_t &remove)  { mRemoveProtons = remove; }
  void SetRemoveMomThreshold(Float_t &t) { mPthresh = t; }
  void SetTpcPionNSigma(Float_t &lo, Float_t &hi)    { mTpcPionNSigma[0] = lo; mTpcPionNSigma[1] = hi; }
  void SetTofPionMassSqr(Float_t &lo, Float_t &hi)   { mTofPionMassSqr[0] = lo; mTofPionMassSqr[1] = hi; }
  void SetTpcKaonNSigma(Float_t &lo, Float_t &hi)    { mTpcKaonNSigma[0] = lo; mTpcKaonNSigma[1] = hi; }
  void SetTofKaonMassSqr(Float_t &lo, Float_t &hi)   { mTofKaonMassSqr[0] = lo; mTofKaonMassSqr[1] = hi; }
  void SetTpcProtonNSigma(Float_t &lo, Float_t &hi)  { mTpcProtonNSigma[0] = lo; mTpcProtonNSigma[1] = hi; }
  void SetTofProtonMassSqr(Float_t &lo, Float_t &hi) { mTofProtonMassSqr[0] = lo; mTofProtonMassSqr[1] = hi; }

 private:

  const Char_t *mOutFileName;
  TFile *mOutFile;
  TTree *mTree;
  Int_t mCompression;                  // see ROOT documentation for more info

  Int_t  mNBytes;                      // number of writed bytes to the mTree
  vector<UInt_t> mTriggerIdCollection;
  StThreeVectorF mDca;

  //
  // Global counters
  //
  Bool_t mEventIsGood;
  Int_t  mNEventsIn;
  Int_t  mNEventsPassed;

  Bool_t mIsGoodTrack;
  Bool_t mAuAuCorrectZdc;
  //
  // Event cuts
  //
  Bool_t  mCollisionType;        //0-pp, 1-AuAu
  Float_t mPrimVtxZ[2];
  Float_t mPrimVtxR[2];
  Float_t mPrimVtxVpdVzDiff[2];
  Float_t mPrimVtxXShift;
  Float_t mPrimVtxYShift;
  //
  // Single-particle cuts
  //
  Float_t  mTrackMomentum[2];
  Float_t  mTrackDcaPerp[2];
  Float_t  mTrackDcaZ[2];
  UShort_t mTrackNHits[2];
  Float_t  mTrackEta[2];
  Short_t  mTrackFlag[2];
  //
  //Cuts for exclusion
  //
  Bool_t   mRemovePions;
  Bool_t   mRemoveKaons;
  Bool_t   mRemoveProtons;
  Float_t  mPthresh;
  Float_t  mTpcPionNSigma[2];
  Float_t  mTofPionMassSqr[2];
  Float_t  mTpcKaonNSigma[2];
  Float_t  mTofKaonMassSqr[2];
  Float_t  mTpcProtonNSigma[2];
  Float_t  mTofProtonMassSqr[2];
  //
  // Pointers to classes
  //
  StMuPrimaryVertex *mPrimVertex;
  StMuTrack         *mPrimTrack;
  StMuTrack         *mGlobTrack;
  StMuDstMaker      *mMuDstMaker;
  StMuEvent         *mMuEvent;
  StMuDst           *mMuDst;
  StRefMultCorr     *mRefMultCorrUtil;
  //
  // Trigger
  //
  UInt_t       mCurrentTrigger;
  //
  // Femto event structure
  //
  StFemtoEvent *mFemtoEvent;
  //
  // Internal class methods
  //
  Bool_t     AcceptTrigger(StMuEvent *muEvent);
  Bool_t     AcceptPrimVtx(StThreeVectorF vtxPos, Float_t vpdVz);
  Bool_t     AcceptRunId(Int_t runId);          //For StRefMultCorr (isBadRun)
  Bool_t     AcceptTrack(StMuTrack *primTrk, UShort_t vtxInd);
  Bool_t     AcceptRefMult2(StMuTrack *trk);
  Bool_t     AcceptRefMult(StMuTrack *trk);
  Bool_t     AcceptDcaGlobal(Float_t dcaToPrimVtx);
  Bool_t     IsTofTrack(StMuTrack *globTrack);
  StMuTrack *FindPrimaryTrack(int idGlob, int nPrimTracks);
  //
  // Pion, Kaon and Proton selection
  //
  Bool_t IsTpcPion(StMuTrack *pTrk);
  Bool_t IsTofPion(StMuTrack *gTrk);
  Bool_t IsTpcKaon(StMuTrack *pTrk);
  Bool_t IsTofKaon(StMuTrack *gTrk);
  Bool_t IsTpcProton(StMuTrack *pTrk);
  Bool_t IsTofProton(StMuTrack *gTrk);
  void   CalcDca(const StPhysicalHelixD &helix,   // this method is for DCA calc
                 const StThreeVectorF   &vtxPos); // for more description see
                                                  // source code file


  ClassDef(StFemtoDstMaker_HFT, 1)
};

#endif
