#ifndef MARS_MExtractTimeAndChargeSpline
#define MARS_MExtractTimeAndChargeSpline

#ifndef MARS_MExtractTimeAndCharge
#include "MExtractTimeAndCharge.h"
#endif

class MPedestalPix;
class MExtractTimeAndChargeSpline : public MExtractTimeAndCharge
{

private:
  
  static const Byte_t  fgHiGainFirst;    //! Default for fHiGainFirst  (now set to: 2)
  static const Byte_t  fgHiGainLast;     //! Default for fHiGainLast   (now set to: 14)
  static const Byte_t  fgLoGainFirst;    //! Default for fLOGainFirst  (now set to: 3)
  static const Byte_t  fgLoGainLast;     //! Default for fLoGainLast   (now set to: 14)
  static const Float_t fgResolution;     //! Default for fResolution   (now set to: 0.003)
  static const Float_t fgRiseTime;       //! Default for fRiseTime     (now set to: 1.5)
  static const Float_t fgFallTime;       //! Default for fFallTime     (now set to: 4.5)

  Float_t *fHiGainSignal;                //! Need fast access to the signals in a float way
  Float_t *fLoGainSignal;                //! Store them in separate arrays
  Float_t *fHiGainFirstDeriv;            //!
  Float_t *fLoGainFirstDeriv;            //! 
  Float_t *fHiGainSecondDeriv;           //!
  Float_t *fLoGainSecondDeriv;           //!

  Float_t fResolution;                   // The time resolution in FADC units
  Float_t fRiseTime;                     // The usual rise time of the pulse
  Float_t fFallTime;                     // The usual fall time of the pulse

  Float_t fAbMax;                        // Current maximum of the spline
  Float_t fAbMaxPos;                     // Current position of the maximum of the spline
  Float_t fHalfMax;                      // Current half maximum of the spline

  Byte_t  fTimeFlags;                    // Flag to hold the time extraction type
  Byte_t  fChargeFlags;                  // Flag to hold the charge extraction type
  
  Int_t  PreProcess(MParList *pList);
  Bool_t ReInit    (MParList *pList);
  
  void FindTimeAndChargeHiGain(Byte_t *first, Byte_t *logain, Float_t &sum, Float_t &dsum,
                               Float_t &time, Float_t &dtime,
                               Byte_t &sat, const MPedestalPix &ped, const Bool_t abflag);
  void FindTimeAndChargeLoGain(Byte_t *first, Float_t &sum,  Float_t &dsum,
                               Float_t &time, Float_t &dtime,
                               Byte_t &sat, const MPedestalPix &ped, const Bool_t abflag);

public:

  enum TimeType_t   { kMaximum,   kHalfMaximum };    //! Possible time   extraction types
  enum ChargeType_t { kAmplitude, kIntegral    };    //! Possible charge extraction types

private:

  Bool_t IsTimeType  ( TimeType_t   typ )  { return TESTBIT(fTimeFlags  , typ); }
  Bool_t IsChargeType( ChargeType_t typ )  { return TESTBIT(fChargeFlags, typ); }  
  
public:

  MExtractTimeAndChargeSpline(const char *name=NULL, const char *title=NULL);
  ~MExtractTimeAndChargeSpline();  

  void SetResolution   ( Float_t f=fgResolution  )  { fResolution  = f;  }
  void SetRiseTime     ( Float_t f=fgRiseTime    )  { fRiseTime    = f;  }
  void SetFallTime     ( Float_t f=fgFallTime    )  { fFallTime    = f;  }

  void SetTimeType     ( TimeType_t typ=kMaximum    ) { fTimeFlags = 0;   SETBIT(fTimeFlags,typ);  }
  void SetChargeType   ( ChargeType_t typ=kAmplitude) { fChargeFlags = 0; SETBIT(fChargeFlags,typ);}
  
  ClassDef(MExtractTimeAndChargeSpline, 0)   // Task to Extract Arrival Times and Charges using a Fast Cubic Spline
};

#endif



