#ifndef MARS_MHAlpha
#define MARS_MHAlpha

#ifndef MARS_MH
#include "MH.h"
#endif

#ifndef MARS_MTime
#include "MTime.h"
#endif

#ifndef MARS_MAlphaFitter
#include "MAlphaFitter.h"
#endif

#ifndef ROOT_TH3
#include <TH3.h>
#endif

class MParList;
class MParameterD;
class MEnergyEst;
class MHillas;
class MHMatrix;
class MPointingPos;

/*
class MAlphaFitter : public MParContainer
{
private:
    Float_t fSigInt;
    Float_t fSigMax;
    Float_t fBgMin;
    Float_t fBgMax;
    Int_t   fPolynom;

    Double_t fSignificance;
    Double_t fExcessEvents;
    Double_t fChiSqSignal;
    Double_t fChiSqBg;
    Double_t fSigmaGaus;
    Double_t fIntegralMax;

public:
    MAlphaFitter() : fSigInt(10), fSigMax(75), fBgMin(45), fBgMax(85), fPolynom(2)
    {
    }

    MAlphaFitter(const MAlphaFitter &f)
    {
        f.Copy(*this);
    }

    void Copy(TObject &o) const
    {
        MAlphaFitter &f = static_cast<MAlphaFitter&>(o);

        f.fSigInt  = fSigInt;
        f.fSigMax  = fSigMax;
        f.fBgMin   = fBgMin;
        f.fBgMax   = fBgMax;
        f.fPolynom = fPolynom;
    }

    void SetSignalIntegralMax(Float_t s) { fSigInt = s; }
    void SetSignalFitMax(Float_t s)      { fSigMax = s; }
    void SetBackgroundFitMin(Float_t s)  { fBgMin = s; }
    void SetBackgroundFitMax(Float_t s)  { fBgMax = s; }
    void SetNumPolynom(Int_t s)          { fPolynom = s; }

    Double_t GetExcessEvents() const { return fExcessEvents; }
    Double_t GetSignificance() const { return fSignificance; }
    Double_t GetChiSqSignal() const  { return fChiSqSignal; }
    Double_t GetChiSqBg() const      { return fChiSqBg; }
    Double_t GetSigmaGaus() const    { return fSigmaGaus; }

    void PaintResult(Float_t x=0.04, Float_t y=0.94, Float_t size=0.035) const;

    Bool_t Fit(TH1D &h, Bool_t paint=kFALSE);
    ClassDef(MAlphaFitter, 1)
};
*/

class MHAlpha : public MH
{
private:
    const TH3D *fOffData;

    MAlphaFitter fFit;          // SEEMS THAT STREAMER HAS SOME PROBLEMS... MAYBE IF FUNC IS USED AT THE SAME TIME FOR FITS (PAINT)

    TH3D fHAlpha;               // Alpha vs. theta and energy
    TH1D fHEnergy;              // excess events vs energy
    TH1D fHTheta;               // excess events vs theta
    TH1D fHTime;                // excess events vs time;
    TH1D fHAlphaTime;           //! temporary histogram to get alpha vs. time

    MParameterD  *fResult;      //!
    MEnergyEst   *fEnergy;      //!
    MHillas      *fHillas;      //!
    MPointingPos *fPointPos;    //!

    MTime   *fTimeEffOn;        //! Time to steer filling of fHTime
    MTime   *fTime;             //! Event-Time to finalize fHTime
    MTime    fLastTime;         //! Last fTimeEffOn

    //Float_t fEnergyMin;
    //Float_t fEnergyMax;
    //Float_t fSizeMin;
    //Float_t fSizeMax;

    Bool_t fSkipHistTime;
    Bool_t fSkipHistTheta;
    Bool_t fSkipHistEnergy;

    //const TString fNameProjAlpha;  //! This should make sure, that gROOT doen't confuse the projection with something else

    MHMatrix *fMatrix;          //!
    Int_t fMap[5];              //!

    void FitEnergySpec(Bool_t paint=kFALSE);
    void FitEnergyBins(Bool_t paint=kFALSE);
    void FitThetaBins(Bool_t paint=kFALSE);

    void UpdateAlphaTime(Bool_t final=kFALSE);
    void InitAlphaTime(const MTime &t);
    void FinalAlphaTime(MBinning &bins);

    void PaintText(Double_t val, Double_t error) const;

    Int_t DistancetoPrimitive(Int_t px, Int_t py) { return 0; }

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

    Bool_t SetupFill(const MParList *pl);
    Bool_t Fill(const MParContainer *par, const Stat_t w=1);
    Bool_t Finalize();

    const TH3D &GetHist() const { return fHAlpha; }
    const MAlphaFitter &GetAlphaFitter() const { return fFit; }

    void SetOffData(const MHAlpha &h)
    {
        fOffData = &h.fHAlpha;
    }
/*
    void SetSizeCuts(Float_t min, Float_t max)   { fSizeMin=min; fSizeMax=max; }
    void SetSizeMin(Float_t min)                 { fSizeMin=min; }
    void SetSizeMax(Float_t max)                 { fSizeMax=max; }
    void SetEnergyCuts(Float_t min, Float_t max) { fEnergyMin=min; fEnergyMax=max; }
    void SetEnergyMin(Float_t min)               { fEnergyMin=min; }
    void SetEnergyMax(Float_t max)               { fEnergyMax=max; }

    void SetCuts(const MHAlpha &h) {
        fSizeMin = h.fSizeMin; fEnergyMin = h.fEnergyMin;
        fSizeMax = h.fSizeMax; fEnergyMax = h.fEnergyMax;
    }
    */

    void SkipHistTime(Bool_t b=kTRUE)   { fSkipHistTime=b; }
    void SkipHistTheta(Bool_t b=kTRUE)  { fSkipHistTheta=b; }
    void SkipHistEnergy(Bool_t b=kTRUE) { fSkipHistEnergy=b; }

    void Paint(Option_t *opt="");
    void Draw(Option_t *option="");

    void DrawAll(); //*MENU*

    void InitMapping(MHMatrix *mat, Int_t type=0);
    void StopMapping();

    ClassDef(MHAlpha, 1) // Alpha-Plot which is fitted online
};

#endif
