// This may look like C code, but it is really -*- C++ -*-
// Classes d'emballage (wrapper) d'histos SOPHYA/HiStats
// pour trace par PIHisto 
//       C. Magneville / R. Ansari             2007
// (C)     CEA-DAPNIA            LAL-IN2P3/CNRS

#ifndef SOHISWRAP_H
#define SOHISWRAP_H

#include "histos.h"
#include "hisprof.h"
#include "histerr.h"

#include "histos2.h"
#include "hist2err.h"

#include "pexceptions.h"

#include "phistwrapper.h"

namespace SOPHYA {
 
//! Wrapper class for SOPHYA::Histo  , SOPHYA::HProf , for use by PIHisto 
class HistoWrapper : public P1DHistoWrapper
{
public:
  HistoWrapper(Histo* h, bool ad=true) 
    : P1DHistoWrapper(h->NBins())
  {
    if (h == NULL) throw NullPtrError("HistoWrapper(Histo* h = NULL)");
    mHis = h;
    mHpr = dynamic_cast<HProf*>(h);
    mAD = ad;
    DefineXCoordinate(h->XMin(), h->BinWidth()); // Pour P1DArrayAdapter
  }
  ~HistoWrapper() { if (mAD) delete mHis; }

  virtual int_4 NBins() { return mHis->NBins(); }
  virtual r_8 XMin() { return mHis->XMin() ; } 
  virtual r_8 XMax() { return mHis->XMax() ; } 
  virtual r_8 BinWidth() { return mHis->BinWidth() ; } 

  virtual r_8 BinLowEdge(int_4 i) { return mHis->BinLowEdge(i) ; }
  virtual r_8 BinCenter(int_4 i) { return mHis->BinCenter(i) ; }
  virtual r_8 BinHighEdge(int_4 i) { return mHis->BinHighEdge(i) ; }

  virtual r_8 Content(int_4 i) { return (*mHis)(i) ; }
  virtual r_8 Error(int_4 i) { return mHis->Error(i) ; }
  virtual r_8 NbEntries(int_4 i) { if(mHpr) return mHpr->SumW(i); else return 0.; }

  virtual void Update() { mHis->UpdateHisto(); }

  // ajoute des lignes de texte avec les infos statistiques 
  virtual int GetStatInfoAsText(vector<string> & text) 
  {
    char label[64];
    string s;
    sprintf(label, "N= %-g",mHis->NData());
    s = label;   text.push_back(s);
    sprintf(label, "m= %-g",mHis->Mean());
    s = label;   text.push_back(s);
    sprintf(label, "s= %-g",mHis->Sigma());
    s = label;   text.push_back(s);
    return 3;
  }

  // pointeur sur l'objet histo
  inline Histo* getHisto() { return mHis; }

protected:
  Histo* mHis;
  HProf* mHpr;
  bool mAD;
};


//! Wrapper class for SOPHYA::HistoErr  for use by PIHisto 
class HistoErrWrapper : public P1DHistoWrapper 
{
public:
  HistoErrWrapper(HistoErr* h, bool ad=false) 
    : P1DHistoWrapper(h->NBins())
  {
    if (h == NULL) throw NullPtrError("HistoErrWrapper(HistoErr* h = NULL)");
    mHis = h;  mAD = ad;
    DefineXCoordinate(h->XMin(), h->BinWidth()); // Pour P1DArrayAdapter
  }
  ~HistoErrWrapper() { if (mAD) delete mHis; }

  virtual int_4 NBins() { return mHis->NBins(); }
  virtual r_8 XMin() { return mHis->XMin() ; } 
  virtual r_8 XMax() { return mHis->XMax() ; } 
  virtual r_8 BinWidth() { return mHis->BinWidth() ; } 

  virtual r_8 BinLowEdge(int_4 i) { return mHis->BinLowEdge(i) ; }
  virtual r_8 BinCenter(int_4 i) { return mHis->BinCenter(i) ; }
  virtual r_8 BinHighEdge(int_4 i) { return mHis->BinHighEdge(i) ; }

  virtual r_8 Content(int_4 i) { return (*mHis)(i) ; }
  virtual r_8 Error(int_4 i) { return mHis->Error(i) ; }
  virtual r_8 NbEntries(int_4 i) { return mHis->NEntBin(i) ; }

  // ajoute des lignes de texte avec les infos statistiques 
  virtual int GetStatInfoAsText(vector<string> & text) 
  {
    char label[64]; string s;

    sprintf(label, "NMean= %d",mHis->NMean());
    s = label; text.push_back(s);

    return 1;
  }

  // pointeur sur l'objet histo
  inline HistoErr* getHistoErr() { return mHis; }

protected:
  HistoErr* mHis;
  bool mAD;
};


//! Wrapper class for SOPHYA::Histo2D   for use by PIHisto2D 
class Histo2DWrapper : public P2DHistoWrapper
{
public:
  Histo2DWrapper(Histo2D* h, bool ad=true) 
    : P2DHistoWrapper(h->NBinX(), h->NBinY())
  {
    if (h == NULL) throw NullPtrError("Histo2DWrapper(Histo2D* h = NULL)");
    mHis = h;  mAD = ad;
    DefineXYCoordinates(h->XMin(), h->YMin(), h->WBinX(), h->WBinY() ); // pour P2DArrayAdapter
  }

  virtual ~Histo2DWrapper() { if (mAD) delete mHis; }

  virtual int_4 NBinX() { return mHis->NBinX(); }
  virtual int_4 NBinY() { return mHis->NBinY(); }
  virtual r_8 XMin() { return mHis->XMin() ; } 
  virtual r_8 XMax() { return mHis->XMax() ; } 
  virtual r_8 YMin() { return mHis->YMin() ; } 
  virtual r_8 YMax() { return mHis->YMax() ; } 
  virtual r_8 WBinX() { return mHis->WBinX() ; } 
  virtual r_8 WBinY() { return mHis->WBinY() ; } 

  virtual void BinLowEdge(int_4 i, int_4 j, r_8& xr, r_8& yr) 
    { mHis->BinLowEdge(i, j, xr, yr); return; }
  virtual void BinCenter(int_4 i, int_4 j, r_8& xr, r_8& yr)
    { mHis->BinCenter(i, j, xr, yr); return; }
  virtual void BinHighEdge(int_4 i, int_4 j, r_8& xr, r_8& yr) 
    { mHis->BinHighEdge(i, j, xr, yr); return; }

  // Renvoie contenu du bin i
  virtual r_8 Content(int_4 i, int_4 j) { return (*mHis)(i,j) ; }
  virtual r_8 Error(int_4 i, int_4 j) { return mHis->Error(i,j) ; }
  virtual r_8 NbEntries(int_4 i, int_4 j) { return 0.; }

  // ajoute des lignes de texte avec les infos statistiques (dans text)
  // renvoie le nombre de lignes ajoutees - avec implementation par defaut
  virtual int GetStatInfoAsText(vector<string> &  text )
  {
    char label[64];
    string s;
    sprintf(label,"N= %-g", mHis->NData());
    s = label;   text.push_back(s);
    return 1;
  }

  inline Histo2D* getHisto2D() { return mHis; }

protected:
  Histo2D* mHis;
  bool mAD;
};



//! Wrapper class for SOPHYA::Histo2DErr   for use by PIHisto2D 
class Histo2DErrWrapper : public P2DHistoWrapper
{
public:
  Histo2DErrWrapper(Histo2DErr* h, bool ad=true) 
    : P2DHistoWrapper(h->NBinX(), h->NBinY())
  {
    if (h == NULL) throw NullPtrError("Histo2DErrWrapper(Histo2DErr* h = NULL)");
    mHis = h;    mAD = ad;
    DefineXYCoordinates(h->XMin(), h->YMin(), h->WBinX(), h->WBinY() ); // pour P2DArrayAdapter
  }

  virtual ~Histo2DErrWrapper() { if (mAD) delete mHis; }

  virtual int_4 NBinX() { return mHis->NBinX(); }
  virtual int_4 NBinY() { return mHis->NBinY(); }
  virtual r_8 XMin() { return mHis->XMin() ; } 
  virtual r_8 XMax() { return mHis->XMax() ; } 
  virtual r_8 YMin() { return mHis->YMin() ; } 
  virtual r_8 YMax() { return mHis->YMax() ; } 
  virtual r_8 WBinX() { return mHis->WBinX() ; } 
  virtual r_8 WBinY() { return mHis->WBinY() ; } 

  virtual void BinLowEdge(int_4 i, int_4 j, r_8& xr, r_8& yr) 
    { mHis->BinLowEdge(i, j, xr, yr); return; }
  virtual void BinCenter(int_4 i, int_4 j, r_8& xr, r_8& yr)
    { mHis->BinCenter(i, j, xr, yr); return; }
  virtual void BinHighEdge(int_4 i, int_4 j, r_8& xr, r_8& yr) 
    { mHis->BinHighEdge(i, j, xr, yr); return; }

  // Renvoie contenu du bin i
  virtual r_8 Content(int_4 i, int_4 j) { return (*mHis)(i,j) ; }
  virtual r_8 Error(int_4 i, int_4 j) { return mHis->Error(i,j) ; }
  virtual r_8 NbEntries(int_4 i, int_4 j) { return mHis->NEntBin(i,j) ; }

  // ajoute des lignes de texte avec les infos statistiques (dans text)
  // renvoie le nombre de lignes ajoutees - avec implementation par defaut
  virtual int GetStatInfoAsText(vector<string> &  text )
  {
    char label[64];
    string s;
    sprintf(label,"NMean= %d", mHis->NMean());
    text.push_back(label);
    return 1;
  }

  inline Histo2DErr* getHisto2DErr() { return mHis; }

protected:
  Histo2DErr* mHis;
  bool mAD;
};

} // Fin du namespace

#endif
