#ifndef SKZPCALCULATOR
#define SKZPCALCULATOR
#include <vector>

#include "MCReweight/MCReweight.h"

#include "SkzpWeight.h"
#include "Smooth.h"

// This is a singleton class that handles the interface between
// the fitter and the fitting algorithms it can
//
// - Getting the Neugen weights via the MCReweight singleton
// - Getting the Skzp weights.  
// - Smoothing for histogram filling
// - Returning a paramter list from the Skzp weights for the SkzpFitter
//
class FitData;
class MCEventInfo;
class TH1;
class SkzpCalculator
{
 public:

  static SkzpCalculator& Instance();
  ~SkzpCalculator();
  
  void   AddSkzpWeight(const std::string &weight);
  void   AddSkzpWeight(SkzpWeightPtr weight);
  vector<SkzpWeightPtr>  GetSkzpWeights() {return fSkzpWeights;}
  void   ClearSkzpWeights();
  double GetSkzpWeight(FitData &data);
  double GetSkzpPT();

  void   SetMCReweight(MCReweight *mcr) {fMCReweight=mcr;}
  double GetNeugenWeight(MCEventInfo *event);

  void   SetMCSmooth(Smooth *sm){fSmooth=sm;}
  void   FillSmooth(TH1* &hist,const double &center,const double &width,
		    const double &weight=1);
  void   FillAllSmooth(TH1* &hist,const double &center,const double &width,
		    const double &weight=1);

  void   FillExactSmooth(TH1* &hist,const double &center,const double &width,
		    const double &weight=1);
  void   FillExactSmooth(TH2D* &hist,const double &center,const double &y,
			 const double &width,
			 const double &weight=1);
  void   FillExactSmooth2(TH2D* &hist,const double &center,const double &y,
			 const double &widthx,const double &widthy,
			 const double &weight=1);

  void   GetParameters(std::vector<FitPar> &par);
  void   SetParameters(const std::vector<double> &par);

  void   Write();

 protected:
  SkzpCalculator();  



 private:



  // This section sets up the singleton machinery.
  // Cleaner struct used to clean up singleton at end of job
  struct Cleaner {
    void UseMe() { }                  // Dummy method to quiet compiler
    ~Cleaner() {
      if (SkzpCalculator::fgInstance != 0) {
	delete SkzpCalculator::fgInstance;
	SkzpCalculator::fgInstance = 0;
      } }
  };
  friend struct Cleaner; 
  static SkzpCalculator *fgInstance;  // Unique Calibrator object
  
  std::vector<SkzpWeightPtr>   fSkzpWeights;  
  MCReweight *fMCReweight;
  Smooth *fSmooth;
  
 std::vector<double> fPar;
  
  
};



#endif
