#ifndef MARS_MCalibrationChargeCalc
#define MARS_MCalibrationChargeCalc

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

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

#include "TString.h"

class MRawEvtData;
class MRawRunHeader;
class MPedestalCam;
class MCalibrationChargePINDiode;
class MCalibrationChargeCam;
class MGeomCam;
class MExtractedSignalCam;
class MExtractedSignalBlindPixel;
class MTime;
class MCalibrationChargeCalc : public MTask
{

private:

  static const UInt_t fgBlindPixelIdx;                    // ID of the blind pixel
  static const UInt_t fgPINDiodeIdx;                      // ID of the PIN Diode
  static const UInt_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
  MCalibrationChargeCam      *fCam;                       // 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

  MExtractedSignalCam        *fSignals;                   // Extracted signal of all pixels in the camera
  MExtractedSignalBlindPixel *fBlindPixel;                // Extracted signal of the blind pixel  
  MCalibrationChargePINDiode *fPINDiode;                  // Calibration events of all pixels in the camera


  UInt_t  fBlindPixelIdx;  
  UInt_t  fPINDiodeIdx;      
  
  Byte_t  fNumHiGainSamples; 
  Byte_t  fNumLoGainSamples; 
  Float_t fSqrtHiGainSamples; 
  
  UInt_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, 
          kUseQualityChecks,
          kHiLoGainCalibration,
          kHiGainOverFlow, 
          kLoGainOverFlow  };
  
  Bool_t ReInit(MParList *pList); 
  Int_t PreProcess(MParList *pList);
  Int_t Process();
  Int_t PostProcess();
  
public:

  MCalibrationChargeCalc(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 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 SetConversionHiLo         ( const Float_t       conv )       { fConversionHiLo = conv;  }
  void SetBlindPixelSinglePheCut ( const Int_t         cut=fgBlindPixelSinglePheCut)    
                                                                    { fBlindPixelSinglePheCut = cut; }

  void SetPINDiodeIdx(   const UInt_t idx=fgPINDiodeIdx   ) {   fPINDiodeIdx   = idx; }
  void SetBlindPixelIdx( const UInt_t idx=fgBlindPixelIdx ) {   fBlindPixelIdx = idx; }

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

#endif
