#ifndef MARS_MCalibrateData
#define MARS_MCalibrateData

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
// MCalibrateData                                                          //
//                                                                         //
// Integrates the desired ADC time slices of one pixel and apply           //
// calibration constants                                                   //
//                                                                         //
// Differences between MCalibrateData and MCalibrate :                     //
// in MCalibrateData                                                       //
// - in ReInit the MPedPhot container is filled using                      //
//      - the pedstals/slice from MPedestalCam                             //
//      - the number of used FADC slices from MExtractedSignalCam          //
//      - the photon/ADC conversion factor from MCalibrationCam            //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
#ifndef MARS_MTask
#include "MTask.h"
#endif

class MGeomCam;
class MBadPixelsCam;
class MPedestalCam;
class MCalibrationChargeCam;
class MCalibrationQECam;
class MExtractedSignalCam;

class MPedPhotCam;
class MCerPhotEvt;

class MCalibrateData : public MTask
{
private:
  static const TString fgNamePedestalCam;    //! "MPedestalCam"
  static const TString fgNamePedPhotCam;     //! "MPedPhotCam"
  
  MGeomCam              *fGeomCam;          //! Camera geometry container
  MPedestalCam          *fPedestalMean;     //! Pedestals/slice [ADC counts]
  MPedestalCam          *fPedestalRms;      //! Pedestals/slice [ADC counts]
  MBadPixelsCam         *fBadPixels;        //! Bad Pixels information
  MCalibrationChargeCam *fCalibrations;     //! Calibration constants
  MCalibrationQECam     *fQEs;              //! Quantum efficiencies
  MExtractedSignalCam   *fSignals;          //! Integrated charge in FADCs counts
  
  MPedPhotCam           *fPedPhot;          //! Pedestals/(used slices) [photons]
  MCerPhotEvt           *fCerPhotEvt;       //! Cerenkov Photon Event used for calculation
  
  UShort_t fCalibrationMode;                // Flag defining the calibration mode (CalibrationMode_t)
  Byte_t   fPedestalFlag;                   // Flags defining to calibrate the pedestal each event or each run
  
  TString  fNamePedestalCam;            // name of fPedestal
  TString  fNamePedPhotCam;           // name of fPedPhot

  Int_t Calibrate(Bool_t data, Bool_t pedestal) const;
  
  Bool_t GetConversionFactor(UInt_t, Float_t &, Float_t &, Float_t &, Float_t &, Float_t &) const;
  
  Int_t  PreProcess(MParList *pList);
  Bool_t ReInit(MParList *pList);
  Int_t  Process();
  Int_t  ReadEnv(const TEnv &env, TString prefix, Bool_t print);
  void   StreamPrimitive(ofstream &out) const;
  
public:

    enum CalibrationMode_t
    {
        kSkip       =  0,
        kNone       =  1,
        kFlatCharge =  2,
        kBlindPixel =  3,
        kFfactor    =  4,
        kPinDiode   =  5,
        kCombined   =  6,
        kDummy      =  7
    };

  static const CalibrationMode_t kDefault = kFfactor;
  
  enum PedestalType_t
  {
      kNo    = BIT(0),
      kRun   = BIT(1),
      kEvent = BIT(2)
  };
  
  MCalibrateData(CalibrationMode_t calmode=kDefault,
                 const char *name=NULL, const char *title=NULL);
  
  void   EnablePedestalType(PedestalType_t i)     { fPedestalFlag |=  i;      }
  void   SetPedestalFlag(PedestalType_t i=kRun)   { fPedestalFlag  =  i;      }
  Bool_t TestPedestalFlag(PedestalType_t i) const { return fPedestalFlag&i ? kTRUE : kFALSE; }
  
  void   SetCalibrationMode ( CalibrationMode_t calmode=kDefault ) { fCalibrationMode=calmode; }
  
  void   SetNamePedestalCam(const char *name=fgNamePedestalCam.Data())
  {
      fNamePedestalCam  = name;
  }
  void SetPedestalCamMean(MPedestalCam *cam) { fPedestalMean = cam; }
  void SetPedestalCamRms(MPedestalCam *cam)  { fPedestalRms  = cam; }

  void   SetNamePedPhotCam(const char *name=fgNamePedPhotCam.Data())
  {
      fNamePedPhotCam   = name;
  }
  
  ClassDef(MCalibrateData, 0)   // Task to calibrate FADC counts into Cherenkov photons 
};

#endif   /* MCalibrateData */






