#ifndef MARS_MCalibrationCalc
#define MARS_MCalibrationCalc

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
// MCalibrationCalc                                                   //
//                                                                         //
// Integrates the time slices of the all pixels of a calibration event     //
// and substract the pedestal value                                        //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////

#ifndef MARS_MTask
#include "MTask.h"
#endif

#ifndef ROOT_TArrayI
#include "TArrayI.h"
#endif

#ifndef MARS_MCalibrationCam
#include "MCalibrationCam.h"
#endif

#include "TString.h"

class MRawEvtData;
class MRawRunHeader;

class MPedestalCam;
class MCalibrationCam;
class MExtractedSignalCam;

class MTime;

class MCalibrationCalc : public MTask
{
private:

  static const UInt_t fBlindPixelId;            // ID of the blind pixel
  static const UInt_t fPINDiodeId;              // ID of the PIN Diode
  static const Byte_t fgSaturationLimit;        // Saturation of Hi Gain
  static const Int_t  fgBlindPixelFirst;        // First FADC slice blind pixel
  static const Int_t  fgBlindPixelLast;         // Last FADC slice blind pixel
  static const Int_t  fgBlindPixelSinglePheCut; // FADC sum from which on an event is considered as a S.ph. one.
  
  MPedestalCam             *fPedestals;         // Pedestals of all pixels in the camera
  MCalibrationCam          *fCalibrations;      // Calibration events of all pixels in the camera
  MExtractedSignalCam      *fSignals;           // Calibration events of all pixels in the camera

  MRawEvtData              *fRawEvt;            // raw event data (time slices)
  MRawRunHeader            *fRunHeader;         // RunHeader information

  MTime                    *fEvtTime;           // Time of the event

  Byte_t  fNumHiGainSamples; 
  Byte_t  fNumLoGainSamples; 
  Float_t fSqrtHiGainSamples; 
  
  Int_t   fBlindPixelFirst;
  Int_t   fBlindPixelLast;
  Int_t   fBlindPixelSinglePheCut;

  Int_t   fNumBlindPixelSinglePhe;
  Int_t   fNumBlindPixelPedestal;  
  
  Float_t fConversionHiLo;
  Int_t   fFlags;                                // Flag for the fits used

  TString fExcludedPixelsFile;
  UInt_t  fNumExcludedPixels;

  enum  { kUseBlindPixelFit, 
          kUsePinDiodeFit,
          kUseQualityChecks,
          kHiLoGainCalibration,
          kHiGainOverFlow, 
          kLoGainOverFlow  };
  
public:
  
  enum PulserColor_t  { kEGreen, kEBlue, kEUV, kECT1 };

private:

  PulserColor_t  fColor;
  
  Bool_t ReInit(MParList *pList); 
  Int_t PreProcess(MParList *pList);
  Int_t Process();
  Int_t PostProcess();

  Bool_t CalcSignalBlindPixel(Byte_t *ptr, Float_t &signal) const;  
  
public:

  MCalibrationCalc(const char *name=NULL, const char *title=NULL);

  void Clear(const Option_t *o="");
  
  void SkipBlindPixelFit(Bool_t b=kTRUE)
      {b ? CLRBIT(fFlags, kUseBlindPixelFit)    : SETBIT(fFlags, kUseBlindPixelFit);}
  void SkipPinDiodeFit(Bool_t b=kTRUE)
      {b ? CLRBIT(fFlags, kUsePinDiodeFit)      : SETBIT(fFlags, kUsePinDiodeFit);}
  void SkipQualityChecks(Bool_t b=kTRUE)
      {b ? CLRBIT(fFlags, kUseQualityChecks)    : SETBIT(fFlags, kUseQualityChecks);}
  void SkipHiLoGainCalibration(Bool_t b=kTRUE)
      {b ? CLRBIT(fFlags, kHiLoGainCalibration) : SETBIT(fFlags, kHiLoGainCalibration);}


  // Setters 
  void SetPulserColor(PulserColor_t color)     { fColor          = color; }
  void SetConversionHiLo(Float_t conv)         { fConversionHiLo = conv; }

  void SetBlindPixelRange(Int_t first=fgBlindPixelFirst, Int_t last=fgBlindPixelLast);
  void SetBlindPixelSinglePheCut(Int_t cut=fgBlindPixelSinglePheCut)    
                                               { fBlindPixelSinglePheCut = cut;  }
  
  // Getters
  MCalibrationBlindPix *GetBlindPixel() const;
  MCalibrationPINDiode *GetPINDiode()   const;

  // Exclude pixels from configuration file
  void ExcludePixelsFromAsciiFile(const char *file) { fExcludedPixelsFile = file;  }
  
  ClassDef(MCalibrationCalc, 1)   // Task to fill the Calibration Containers from raw data
};

#endif
