#ifndef MARS_MExtractor
#define MARS_MExtractor

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
// MExtractor                                                              //
//                                                                         //
// Base class for the signal extractors                                    //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////

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

class MRawEvtData;
class MRawRunHeader;

class MPedestalCam;
class MExtractedSignalCam;

class MExtractor : public MTask
{
protected:
    static const Byte_t fgSaturationLimit;

    MPedestalCam        *fPedestals;    // Pedestals of all pixels in the camera
    MExtractedSignalCam *fSignals;      // Extracted signal of all pixels in the camera

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

    Byte_t   fHiGainFirst;
    Byte_t   fLoGainFirst;

    Byte_t   fHiGainLast;
    Byte_t   fLoGainLast;

    Byte_t   fHiLoLast;
    
    Float_t  fNumHiGainSamples;
    Float_t  fNumLoGainSamples;

    Float_t  fSqrtHiGainSamples;
    Float_t  fSqrtLoGainSamples;

    Byte_t  fSaturationLimit;

    virtual void FindSignalHiGain(Byte_t *firstused, Byte_t *lowgain, Float_t &sum, Byte_t &sat) const { }
    virtual void FindSignalLoGain(Byte_t *firstused, Float_t &sum, Byte_t &sat) const { }

    Int_t  PreProcess(MParList *pList);
    Bool_t ReInit(MParList *pList);
    Int_t  Process();
    void   StreamPrimitive(ofstream &out) const;
    Bool_t ReadEnv(const TEnv &env, TString prefix, Bool_t print);

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

    Byte_t  GetHiGainFirst()      const { return fHiGainFirst;      }
    Byte_t  GetHiGainLast ()      const { return fHiGainLast ;      }
    Byte_t  GetLoGainFirst()      const { return fLoGainFirst;      }
    Byte_t  GetLoGainLast ()      const { return fLoGainLast ;      }
    Float_t GetNumHiGainSamples() const { return fNumHiGainSamples; }
    Float_t GetNumLoGainSamples() const { return fNumLoGainSamples; }
    
    virtual void SetRange  (Byte_t hifirst=0, Byte_t hilast=0, Byte_t lofirst=0, Byte_t lolast=0);
    void SetSaturationLimit(Byte_t lim=fgSaturationLimit) { fSaturationLimit = lim; }

    ClassDef(MExtractor, 0) // Signal Extractor Base Class
};

#endif
