#ifndef MARS_MCalibrationCam
#define MARS_MCalibrationCam

#ifndef MARS_MParContainer
#include "MParContainer.h"
#endif
#ifndef MARS_MCamEvent
#include "MCamEvent.h"
#endif

class TH1D;
class TH2D;
class TClonesArray;

class MCalibrationPix;
class MCalibrationBlindPix;
class MCalibrationPINDiode;

class MCalibrationCam : public MParContainer, public MCamEvent
{
private:
  
  static const Int_t   gkBlindPixelId;
  static const Int_t   gkPINDiodeId;
  static const Float_t gkTimeSliceWidth;
  

  Int_t fNumPixels;
  TClonesArray *fPixels;                      //-> Array of MCalibrationPix with fit results
  
  MCalibrationBlindPix *fBlindPixel;          //-> Pointer to the Blind Pixel with fit results
  MCalibrationPINDiode *fPINDiode;            //-> Pointer to the PIN Diode with fit results

  TH1D* fOffsets;                             //! 
  TH1D* fSlopes;                              //! 
  
  TH2D* fOffvsSlope;                          //! 

  Float_t fMeanPhotInsidePlexiglass;     //  The mean number of photons in an INNER PIXEL inside the plexiglass
  Float_t fMeanPhotErrInsidePlexiglass;  //  The uncertainty about the number of photons in an INNER PIXEL  
  Float_t fMeanPhotOutsidePlexiglass;    //  The mean number of photons in an INNER PIXEL outside the plexiglass
  Float_t fMeanPhotErrOutsidePlexiglass; //  The uncertainty about the number of photons in an INNER PIXEL  

  UInt_t fNumExcludedPixels;

  Byte_t fFlags;

  enum  { kBlindPixelMethodValid, kPINDiodeMethodValid,
          kNumPhotInsidePlexiglassAvailable, kNumPhotOutsidePlexiglassAvailable  };
  
public:
  
  enum CalibrationColor_t { kECGreen, kECBlue, kECUV, kECCT1 };

private:

  CalibrationColor_t fColor;  
  
public:

  MCalibrationCam(const char *name=NULL, const char *title=NULL);
  ~MCalibrationCam();
  
  void Clear(Option_t *o="");
  void InitSize(const UInt_t i);

  // Setters
  void SetColor(const CalibrationColor_t color)       {  fColor = color; }
  void SetNumPixelsExcluded(const UInt_t n)               {  fNumExcludedPixels = n;    }

  void SetBlindPixelMethodValid(const Bool_t b = kTRUE);
  void SetPINDiodeMethodValid(const Bool_t b = kTRUE);  
  
  // Getters
  Int_t GetSize()                        const;
  UInt_t GetNumPixels()                  const { return fNumPixels; }

  MCalibrationBlindPix *GetBlindPixel()  const { return fBlindPixel;  }
  MCalibrationPINDiode *GetPINDiode()    const { return fPINDiode;    }
  MCalibrationBlindPix *GetBlindPixel()       { return fBlindPixel;  }
  MCalibrationPINDiode *GetPINDiode()         { return fPINDiode;    }

  Bool_t GetConversionFactorFFactor(Int_t ipx, Float_t &mean, Float_t &err, Float_t &sigma);
  Bool_t GetConversionFactorBlindPixel(Int_t ipx, Float_t &mean, Float_t &err, Float_t &sigma);
  Bool_t GetConversionFactorPINDiode(Int_t ipx, Float_t &mean, Float_t &err, Float_t &sigma);
  Bool_t GetConversionFactorCombined(Int_t ipx, Float_t &mean, Float_t &err, Float_t &sigma);

  Bool_t IsPixelUsed(Int_t idx)      const;
  Bool_t IsPixelFitted(Int_t idx)    const;

  Bool_t IsBlindPixelMethodValid()   const;
  Bool_t IsPINDiodeMethodValid()     const;  

  Bool_t IsNumPhotInsidePlexiglassAvailable() const;
  Bool_t IsNumPhotOutsidePlexiglassAvailable() const;

  // Others
  MCalibrationPix &operator[](Int_t i);
  MCalibrationPix &operator[](Int_t i) const;
  
  void CutEdges();
  Bool_t CheckBounds(Int_t i) const;

  // Prints
  void Print(Option_t *o="") const;
  
  // Draws
  void DrawPixelContent(Int_t num) const;    
  void DrawHiLoFits();
  
  // Others
  Bool_t GetPixelContent(Double_t &val, Int_t idx, const MGeomCam &cam, Int_t type=0) const;

  Bool_t CalcNumPhotInsidePlexiglass();
  Bool_t CalcNumPhotOutsidePlexiglass();

  ClassDef(MCalibrationCam, 1)	// Storage Container for all calibration information of the camera
};

#endif

