#ifndef MARS_MExtractTimeAndChargeDigitalFilter
#define MARS_MExtractTimeAndChargeDigitalFilter

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

#ifndef MARS_MArrayF
#include "MArrayF.h"
#endif

#ifndef MARS_MArrayI
#include "MArrayI.h"
#endif

class TH1F;
class TH2F;
class MPedestalPix;
class MCalibrationPattern;

class MExtractTimeAndChargeDigitalFilter : public MExtractTimeAndCharge
{
private:
    static const Byte_t fgHiGainFirst;             //! Default for fHiGainFirst       (now set to: 0)
    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 Int_t  fgWindowSizeHiGain;        //! Default for fWindowSizeHiGain  (now set to: 6)
//    static const Int_t  fgWindowSizeLoGain;        //! Default for fWindowSizeLoGain  (now set to: 6)
    static const Int_t  fgBinningResolutionHiGain; //! Default for fBinningResolutionHiGain (now set to: 10)
    static const Int_t  fgBinningResolutionLoGain; //! Default for fBinningResolutionLoGain (now set to: 10)
    static const Int_t  fgSignalStartBinHiGain;    //! Default for fSignalStartBinHiGain (now set to: 4)
    static const Int_t  fgSignalStartBinLoGain;    //! Default for fSignalStartBinLoGain (now set to: 4)
    static const TString fgNameWeightsFile;        //! "cosmics_weights.dat"
    static const Float_t fgOffsetLoGain;           //! Default for fOffsetLoGain (now set to 1.7)
//    static const Float_t fgLoGainStartShift;       //! Default for fLoGainStartShift (now set to -1.8)

    MCalibrationPattern  *fCalibPattern;          //! Calibration DM pattern

//    MArrayF fHiGainSignal;                        //! Need fast access to the signals in a float way
//    MArrayF fLoGainSignal;                        //! Store them in separate arrays

//    Int_t   fSignalStartBinHiGain;                //! Start bin from when on to apply weights
//    Int_t   fSignalStartBinLoGain;                //! Start bin from when on to apply weights

    Int_t   fBinningResolutionHiGain;             //  Number of weights per bin High-Gain
    Int_t   fBinningResolutionLoGain;             //  Number of weights per bin Low-Gain

    MArrayF fAmpWeightsHiGain;                    //! Amplitude weights High-Gain (from weights file)
    MArrayF fTimeWeightsHiGain;                   //! Time weights High-Gain (from weights file)
    MArrayF fAmpWeightsLoGain;                    //! Amplitude weights Low-Gain (from weights file)
    MArrayF fTimeWeightsLoGain;                   //! Time weights Low-Gain (from weights file)

    MArrayF fPulseHiGain;                    //! 
    MArrayF fPulseLoGain;                    //! 

    TString fNameWeightsFile;                     // Name of the weights file
    Bool_t  fAutomaticWeights;                    // Flag whether weight should be determined automatically
    TString fNameWeightsFileSet;                  //! Flag if weights have alreayd been set
    Int_t   fRandomIter;                          //! Counter used to randomize weights for noise calculation

    // MExtractTimeAndChargeDigitalFilter
    void    CalcBinningResArrays();
    Int_t   GetAutomaticWeights();
    Bool_t  GetWeights();
    Int_t   ReadWeightsFile(TString filename, TString path="");
    TString CompileWeightFileName(TString path, const TString &name) const;


    // MExtractTimeAndCharge
    Bool_t InitArrays();

    // MTask
    Int_t PreProcess(MParList *pList);
    Int_t Process();

protected:
    // MParContainer
    Int_t ReadEnv(const TEnv &env, TString prefix, Bool_t print);

public:
    MExtractTimeAndChargeDigitalFilter(const char *name=NULL, const char *title=NULL);
    ~MExtractTimeAndChargeDigitalFilter() { }
/*
    Bool_t WriteWeightsFile(TString filename,
                            TH1F *shapehi, TH2F *autocorrhi,
                            TH1F *shapelo=NULL, TH2F *autocorrlo=NULL );

  */
    void SetNameWeightsFile(TString s="")
    {
        s.ReplaceAll("\015", ""); // This is a fix for TEnv files edited with windows editors
        fNameWeightsFile = s;
        fNameWeightsFileSet="";
    }

    void EnableAutomaticWeights(Bool_t b=kTRUE) { fAutomaticWeights = b; }

    void SetBinningResolution(const Int_t rh=fgBinningResolutionHiGain, const Int_t rl=fgBinningResolutionLoGain)
    {
        fBinningResolutionHiGain = rh & ~1;
        fBinningResolutionLoGain = rl & ~1;
    }
/*
    void SetSignalStartBin( const Int_t sh=fgSignalStartBinHiGain, const Int_t sl=fgSignalStartBinLoGain)
    {
        fSignalStartBinHiGain = sh;
        fSignalStartBinLoGain = sl;
    }

 */
    void SetWindowSize( Int_t windowh, Int_t windowl);
    const char* GetNameWeightsFile() const  { return fNameWeightsFile.Data(); }

    void Print(Option_t *o="") const; //*MENU*
/*
    void FindTimeAndChargeHiGain(Byte_t *firstused, 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 *firstused, Float_t &sum,  Float_t &dsum,
                                 Float_t &time, Float_t &dtime,
                                 Byte_t &sat, const MPedestalPix &ped, const Bool_t abflag);
 */
    void FindTimeAndChargeHiGain2(const Float_t *firstused, Int_t num, Float_t &sum, Float_t &dsum,
                                  Float_t &time, Float_t &dtime,
                                  Byte_t sat, Int_t maxpos);

    void FindTimeAndChargeLoGain2(const Float_t *firstused, Int_t num, Float_t &sum,  Float_t &dsum,
                                  Float_t &time, Float_t &dtime,
                                  Byte_t sat, Int_t maxpos);

    ClassDef(MExtractTimeAndChargeDigitalFilter, 2)   // Hendrik's digital filter
};

#endif
