#ifndef HMDCCALIBRATER1_H
#define HMDCCALIBRATER1_H
#include "hreconstructor.h"
#include "hlocation.h"
#include "TRandom.h"
#include "hstartdef.h"
class HCategory;
class HIterator;
class HMdcCalParRaw;
class HMdcLookupGeom;
class HMdcTimeCut;
class HMdcCutStat;
class HMdcWireStat;
class HMdcRaw;
class HMdcCal1;
class HMdcCalParTdc;
class HMdcCalibrater1 : public HReconstructor {
protected:
  HCategory* rawCat;       
  HCategory* calCat;       
  HCategory* startHitCat;  
  HMdcRaw* raw;            
  HMdcCal1* cal;           
  Bool_t StartandCal;      
  Bool_t NoStartandNoCal;  
  Bool_t NoStartandCal;    
  Bool_t setTimeCut;       
  Bool_t hasPrinted;       
  Int_t  embedding;        
  HLocation loc;           
  HIterator* iter;         
  HIterator* iterstart;    
  HMdcCalParRaw* calparraw;
  HMdcLookupGeom* lookup;  
  HMdcTimeCut* timecut;    
  HMdcCutStat* cutStat;    
  HMdcWireStat* wireStat;  
  static Float_t globalOffset[4]; 
  static Float_t globalSecOffset[6][4]; 
  static Float_t globalSlope;     
  static Int_t countNrWiresPerMod[6][4];    
  static Int_t countNrWiresPerModCal[6][4]; 
  static Int_t countNrFlashWiresPerMod[6][4];  
  static Int_t countNDeltaElWiresPerMod[6][4]; 
  Int_t cuts[5];          
  Int_t cutthreshold;     
  Bool_t useMultCut;      
  Bool_t useMultCutTot;   
  Bool_t doSkipMultCut;   
  Bool_t doprint;         
  Bool_t skipCal;         
  static Bool_t useWireStat;  
  Int_t ctEvent;              
  Int_t ctEventSkip;          
  
  Float_t flashTotCut;        
  Float_t flashT1Cut[4];      
  Int_t   flashMultCut;       
  Bool_t  skipFlashEvent;     
  Float_t timeT1Cut;          
  Int_t   deltaElMultCut;     
  Bool_t  skipDeltaElEvt;     
  void initParameters(void);
  void initCounters()
  {
      for(Int_t i=0;i<6;i++)
      {
	  for(Int_t j=0;j<4;j++)
	  {
           countNrWiresPerMod[i][j]       = 0;
           countNrFlashWiresPerMod[i][j]  = 0;
           countNDeltaElWiresPerMod[i][j] = 0;
	  }
      }
  };
  void initCountersCal()
  {
      for(Int_t i=0;i<6;i++)
      {
	  for(Int_t j=0;j<4;j++)
	  {
           countNrWiresPerModCal[i][j]=0;
	  }
      }
  };
  Bool_t doMultCut()
  {
      for(Int_t i=0;i<6;i++)
      {
	  for(Int_t j=0;j<4;j++)
	  {
	      if(countNrWiresPerModCal[i][j]>cutthreshold) return kTRUE;
	  }
      }
      return kFALSE;
  }
  Bool_t doFlashCut()
  {
      for(Int_t i=0;i<6;i++)
      {
	  if(countNrFlashWiresPerMod[i][0]+countNrFlashWiresPerMod[i][1] > flashMultCut) return kTRUE;
          if(countNrFlashWiresPerMod[i][2]+countNrFlashWiresPerMod[i][3] > flashMultCut) return kTRUE;
      }
      return kFALSE;
  }
  Bool_t doDeltaElCut()
  {
      for(Int_t i=0;i<6;i++)
      {
	  if(countNDeltaElWiresPerMod[i][0]+countNDeltaElWiresPerMod[i][1] > deltaElMultCut) return kTRUE;
          if(countNDeltaElWiresPerMod[i][2]+countNDeltaElWiresPerMod[i][3] > deltaElMultCut) return kTRUE;
      }
      return kFALSE;
  }
  void setParContainers(void);
  Float_t getstarttime();
  Bool_t testTimeCuts(Float_t,Float_t);
  Bool_t translateAddress(Int_t*,Int_t*);
  void calcTimes(Float_t*,Float_t*,Float_t,Int_t,HMdcCalParTdc*);
  void fillCal1(Float_t ,Float_t ,Int_t );
  void countWiresPerMod();
  void printWires();
public:
  HMdcCalibrater1(void);
  HMdcCalibrater1(const Text_t* name,const Text_t* title,Int_t vers=1,Int_t cut=1,Int_t domerge=0);
  ~HMdcCalibrater1(void);
  Bool_t init(void);
  void setDoPrint(Bool_t dopr)       {doprint=dopr;}
  void setSkipCal(Bool_t skip=kTRUE) {skipCal=skip;}
  void setUseMultCut(Int_t thresh,Bool_t use=kTRUE,Bool_t tot=kTRUE,Bool_t skip=kTRUE)  {cutthreshold=thresh;useMultCut=use; useMultCutTot=tot; doSkipMultCut=skip;}
  void setSkipFlashEvent(Int_t threshold)
  {
    flashMultCut   = threshold;
    skipFlashEvent = flashMultCut > 10;    
  }
  void setFlashWiresCut(Float_t tot=30.,Float_t t1m1=-5.,Float_t t1m2=-5.,Float_t t1m3=-5.,Float_t t1m4=-5.)
  {
    flashTotCut    = tot;
    flashT1Cut[0]  = t1m1;
    flashT1Cut[1]  = t1m2;
    flashT1Cut[2]  = t1m3;
    flashT1Cut[3]  = t1m4;
  }
  void setDeltaElectCut(Int_t thresh,Float_t t1c=-10.)
  {
    timeT1Cut      = t1c;
    deltaElMultCut = thresh;
    skipDeltaElEvt = deltaElMultCut > 10;    
  }
  static Int_t getFlashWiresMod(Int_t s,Int_t m)  { return countNrFlashWiresPerMod[s][m]; }
  static Int_t getFlashWiresSeg(Int_t s,Int_t g)  { return countNrFlashWiresPerMod[s][g*2]+countNrFlashWiresPerMod[s][g*2+1]; }
  static Int_t getMaxNrFlashWiresPerSeg (void)       
  {
      Int_t maxn = 0;
      for(Int_t s=0;s<6;s++) for(Int_t g=0;g<2;g++) {
          Int_t n = getFlashWiresSeg(s,g);
          if(n > maxn) maxn = n;
      } 
      return maxn;
  }
  
  static Int_t getDeltaElWiresMod(Int_t s,Int_t m)  { return countNDeltaElWiresPerMod[s][m]; }
  static Int_t getDeltaElWiresSeg(Int_t s,Int_t g)  { return countNDeltaElWiresPerMod[s][g*2]+countNDeltaElWiresPerMod[s][g*2+1]; }
  static Int_t getMaxNrDeltaElWiresPerSeg (void)       
  {
      Int_t maxn = 0;
      for(Int_t s=0;s<6;s++) for(Int_t g=0;g<2;g++) {
          Int_t n = getDeltaElWiresSeg(s,g);
          if(n > maxn) maxn = n;
      } 
      return maxn;
  }
  
  static void setUseWireStat(Bool_t doit) { useWireStat=doit; }
  void switchArguments(Int_t,Int_t,Int_t);
  void setGlobalOffset(Float_t o0,Float_t o1,Float_t o2,Float_t o3)
  {
    for(Int_t s=0;s<6;s++) {
      globalSecOffset[s][0]=o0;
      globalSecOffset[s][1]=o1;
      globalSecOffset[s][2]=o2;
      globalSecOffset[s][3]=o3;
    }
  }
  void setSecGlobalOffset(Int_t s,Float_t o0,Float_t o1,Float_t o2,Float_t o3)
  {
      if(s<0 || s>5) return;
      globalSecOffset[s][0]=o0;
      globalSecOffset[s][1]=o1;
      globalSecOffset[s][2]=o2;
      globalSecOffset[s][3]=o3;
  }
  void setGlobalSlope(Float_t s){globalSlope=s;}
  Bool_t finalize(void) {return kTRUE;}
  void printStatus();
  Int_t execute(void);
  ClassDef(HMdcCalibrater1,0) 
};
#endif /* !HMDCCALIBRATER1_H */