#ifndef MARS_MPedCalcFromLoGain
#define MARS_MPedCalcFromLoGain

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

#ifndef ROOT_TArrayD
#include <TArrayD.h>
#endif

#ifndef ROOT_TArrayI
#include <TArrayI.h>
#endif

class MGeomCam;
class MPedestalCam;
class MRawEvtData;
class MRawEvtPixelIter;
class MRawRunHeader;

class MPedCalcFromLoGain : public MTask
{
    static const UShort_t fgCheckWinFirst;    // First FADC slice to check for signal (currently set to: 0)
    static const UShort_t fgCheckWinLast;     // Last FADC slice to check for signal  (currently set to: 29)
    static const UShort_t fgExtractWinFirst;  // First FADC slice to use for pedestal calculation (currently set to: 15)
    static const UShort_t fgExtractWinSize;   // number of successive slices used to calculate pedestal (currently set to: 6)
    static const UShort_t fgMaxSignalVar;     // The maximum difference between the highest and lowest slice

    MGeomCam      *fGeom;        //! Camera geometry
    MPedestalCam  *fPedestals;   //! Pedestals of all pixels in the camera
    MRawEvtData   *fRawEvt;      //! Raw event data (time slices)
    MRawRunHeader *fRunHeader;   //! RunHeader information

    UInt_t   fNumEventsDump;     // Number of event after which MPedestalCam gets updated

    UShort_t fMaxSignalVar;
    UShort_t fCheckWinFirst;
    UShort_t fCheckWinLast;
    UShort_t fExtractWinSize;    // Number of slices to calculate the pedestal from
    UShort_t fExtractWinFirst;
    UShort_t fExtractWinLast;

    Bool_t  fPedestalUpdate;

    TString fNamePedestalCam;    // name of the 'MPedestalCam' container

    TArrayI fNumEventsUsed;      // Number of events used for pedestal calc for each pixel
    TArrayI fTotalCounter;       // Counter for dumping values to Pedestal Container
    TArrayD fSumx;               // sum of values
    TArrayD fSumx2;              // sum of squared values
    TArrayD fSumAB0;             // sum of ABFlag=0 slices
    TArrayD fSumAB1;             // sum of ABFlag=1 slices

    // MParContainer
    Int_t  PreProcess (MParList *pList);
    Bool_t ReInit     (MParList *pList);
    Int_t  Process    ();
    Int_t  PostProcess();
    Int_t  ReadEnv(const TEnv &env, TString prefix, Bool_t print);

    // Calculation
    void Calc(ULong_t n, UInt_t idx);

    //Helper function to extract slice values by slice number
    UShort_t GetSlice(MRawEvtPixelIter *pixel, UInt_t slice);
    void ResetArrays();

public:
    MPedCalcFromLoGain(const char *name=NULL, const char *title=NULL);

    // TObject
    void Clear(const Option_t *o="");
    void Print(Option_t *o="") const;

    // Setter
    Bool_t SetCheckRange(UShort_t checkfirst=fgCheckWinFirst, UShort_t checklast=fgCheckWinLast);
    Bool_t SetExtractWindow(UShort_t extractfirst=fgExtractWinFirst, UShort_t windowsize=fgExtractWinSize);

    void SetMaxSignalVar(UShort_t maxvar=40)       { fMaxSignalVar = maxvar;    }
    void SetNumEventsDump(UInt_t dumpevents = 500) { fNumEventsDump = dumpevents;}
    void SetPedestalUpdate(Bool_t pedupdate)  {fPedestalUpdate = pedupdate;}

    void SetNamePedestalCam(const char *name) { fNamePedestalCam = name; }

    // Getter
    TArrayI *GetNumEventsUsed() { return &fNumEventsUsed; }

    ClassDef(MPedCalcFromLoGain, 0)   // Task to calculate pedestals from pedestal runs raw data
};

#endif
