#ifndef HISPROF_SEEN
#define HISPROF_SEEN

#include <stdio.h>
#include "peida.h"
#include "tvector.h"
#include "ppersist.h"
#include "histos.h"

namespace SOPHYA {

class HProf : public Histo {
  friend class ObjFileIO<HProf>;
public:

  // CREATOR / DESTRUCTOR
  HProf();
  HProf(float xMin, float xMax, int nBin=100, float yMin=1., float yMax=-1.);
  HProf(const HProf& H);
  virtual ~HProf();

  // UPDATING or SETTING
  void   Zero();
  void   UpdateHisto() const;
  void   SetErrOpt(bool spread = true);
  void   Add(float x, float y, float w = 1.);
  void   AddBin(int numBin, float y, float w = 1.);
  
  // Acces a l information
  inline Histo GetHisto() {if(!Ok) UpdateHisto(); return (Histo) *this;}
  inline void GetMean(Vector& v) {if(!Ok) UpdateHisto(); Histo::GetValue(v);}
  inline void GetError2(Vector& v) {if(!Ok) UpdateHisto(); Histo::GetError2(v);}
  inline float operator()(int i) const {if(!Ok) UpdateHisto(); return data[i];}
  inline float Error2(int i) const {if(!Ok) UpdateHisto(); return (float) err2[i];}
  inline float Error(int i) const
         {if(!Ok) UpdateHisto(); return err2[i]>0. ? (float) sqrt(err2[i]) : 0.f;}

  // Operators
  HProf& operator = (const HProf& h);
  HProf& operator += (const HProf& a);
  friend HProf operator + (const HProf& a, const HProf& b);

  // Fit
  inline int    Fit(GeneralFit& gfit)
         {if(!Ok) UpdateHisto(); return Histo::Fit(gfit,0);}
  inline Histo  FitResidus(GeneralFit& gfit)
         {if(!Ok) UpdateHisto(); return Histo::FitResidus(gfit);}
  inline Histo  FitFunction(GeneralFit& gfit)
         {if(!Ok) UpdateHisto(); return Histo::FitFunction(gfit);}

  // Print
  inline void Print(int dyn=100,float hmin=1.,float hmax=-1.,int pflag=0,int il=1,int ih=-1)
                           {if(!Ok) UpdateHisto(); Histo::Print(dyn,hmin,hmax,pflag,il,ih);}

protected:
  void Delete();

  double*        SumY;
  double*        SumY2;
  double*        SumW;
  bool           Ok;
  float          YMin;
  float          YMax;
  uint_2         Opt;
};


inline POutPersist& operator << (POutPersist& os, HProf & obj)
{ ObjFileIO<HProf> fio(&obj);  fio.Write(os);  return(os); }
inline PInPersist& operator >> (PInPersist& is, HProf & obj)
{ ObjFileIO<HProf> fio(&obj);  fio.Read(is);  return(is); }
// Classe pour la gestion de persistance
// ObjFileIO<HProf>


} // Fin du namespace

#endif // HISPROF_SEEN
