#include <string>
#include <iostream>
#include <iomanip>

#include "TROOT.h"
#include "TFile.h"
#include "TH1D.h"
#include "TRandom3.h"

#include "JDetector/JPMTTransitTimeProbability.hh"
#include "JDetector/JPMTParameters.hh"
#include "JDetector/JPMTAnalogueSignalProcessor.hh"

#include "Jeep/JParser.hh"
#include "Jeep/JMessage.hh"


/**
 * \file
 *
 * Example program to histogram PMT transit time distribution.
 * \author mdejong
 */
int main(int argc, char **argv)
{
  using namespace std;
  using namespace JPP;

  string         outputFile;
  JPMTParameters parameters;
  int            numberOfEvents;
  int            option;
  int            debug;

  try {

    JProperties properties = parameters.getProperties();

    JParser<> zap("Example program to histogram PMT transit time distribution.");

    zap['o'] = make_field(outputFile)       = "histogram.root";
    zap['P'] = make_field(properties)       = JPARSER::initialised();
    zap['n'] = make_field(numberOfEvents)   = 0;
    zap['O'] = make_field(option)           = 0;
    zap['d'] = make_field(debug)            = 0;

    zap(argc, argv);
  }
  catch(const exception &error) {
    FATAL(error.what() << endl);
  }

  if (debug >= JEEP::debug_t) {
    cout << "PMT parameters:" << endl;
    cout << parameters.getProperties(JEquationParameters("=", "\n", "", "")) << endl;
  }

  parameters.TTS_ns = -option;

  const JPMTAnalogueSignalProcessor cpu(parameters);

  TFile out(outputFile.c_str(), "recreate");
  
  TH1D h1("tts", NULL, 1300, -30.0, +100.0);
  TH1D h2("pmt", NULL,  130, -30.0, +100.0);

  double W = 0.0;

  for (int i = 1; i <= h1.GetNbinsX(); ++i) {

    const double t1 = h1.GetBinCenter(i);
    const double y  = getTransitionTimeProbability(t1, option);
    const double z  = h1.GetBinWidth (i);

    h1.SetBinContent(i, y);

    W += y * z;
  }

  h1.Scale(1.0 / W, "nosw2");

  if (numberOfEvents > 0) {

    for (int i = 0; i != numberOfEvents; ++i) {

      const double t0 = 0.0;
      const double t1 = cpu.getRandomTime(t0);
	
      h2.Fill(t1);
    }

    h2.Scale(1.0 / numberOfEvents);
  }

  out.Write();
  out.Close();
}