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

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

#include "JPhysics/Antares.hh"
#include "JPhysics/KM3NeT.hh"
#include "JPhysics/JDispersion.hh"

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


/**
 * \file
 * Auxiliary program histogram plot absorption and scattering lengths as well as dispersion.
 * \author mdejong
 */
int main(int argc, char **argv)
{
  using namespace std;

  string              outputFile;
  int                 debug;

  try {

    JParser<> zap("Auxiliary program histogram plot absorption and scattering lengths as well as dispersion.");

    zap['o'] = make_field(outputFile)  = "light.root";
    zap['d'] = make_field(debug)       = 1;

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


  using namespace JPP;

  TFile out(outputFile.c_str(), "recreate");

  TH1D h0("abs[Antares]",  NULL, 400, 280.0, 680.0);
  TH1D h1("abs[KM3NeT]",   NULL, 400, 280.0, 680.0);
  TH1D h2("scat[Antares]", NULL, 400, 280.0, 680.0);
  TH1D h3("scat[KM3NeT]",  NULL, 400, 280.0, 680.0);

  TH1D h4("vp[Antares]",   NULL, 400, 280.0, 680.0);
  TH1D h5("vp[KM3NeT]",    NULL, 400, 280.0, 680.0);
  TH1D h6("vg[Antares]",   NULL, 400, 280.0, 680.0);
  TH1D h7("vg[KM3NeT]",    NULL, 400, 280.0, 680.0);

  TH1D h8("Ps[Antares]",   NULL, 5000,  -1.0,  +1.0);
  TH1D h9("Ps[KM3NeT]",    NULL, 5000,  -1.0,  +1.0);
  TH1D ha("f4",            NULL, 5000,  -1.0,  +1.0);
  TH1D hb("p00075",        NULL, 5000,  -1.0,  +1.0);
  TH1D hc("petzhold",      NULL, 5000,  -1.0,  +1.0);

  JDispersion antares(250.0);   // P [bar]
  JDispersion km3net (350.0);   // P [bar]

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

    const double x = h0.GetBinCenter (i);

    h0.SetBinContent(i, ANTARES::getAbsorptionLength(x));
    h1.SetBinContent(i, KM3NET ::getAbsorptionLength(x));
    h2.SetBinContent(i, ANTARES::getScatteringLength(x));
    h3.SetBinContent(i, KM3NET ::getScatteringLength(x));

    h4.SetBinContent(i, antares.getIndexOfRefractionPhase(x));
    h5.SetBinContent(i, km3net .getIndexOfRefractionPhase(x));
    h6.SetBinContent(i, antares.getIndexOfRefractionGroup(x));
    h7.SetBinContent(i, km3net .getIndexOfRefractionGroup(x));
  }
  
  double W[] = { 0.0, 0.0, 0.0 };

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

    const double x  = h8.GetBinCenter (i);
    const double dx = h8.GetBinWidth  (i);

    h8.SetBinContent(i, ANTARES ::getScatteringProbability(x));
    h9.SetBinContent(i, KM3NET  ::getScatteringProbability(x));
    ha.SetBinContent(i, JPHYSICS::f4      (x));
    hb.SetBinContent(i, JPHYSICS::p00075  (x));
    hc.SetBinContent(i, JPHYSICS::petzhold(x));

    W[0] += JPHYSICS::f4      (x) * dx;
    W[1] += JPHYSICS::p00075  (x) * dx;
    W[2] += JPHYSICS::petzhold(x) * dx;
  }

  for (int i = 0; i != sizeof(W)/sizeof(W[0]); ++i) {
    DEBUG("W[" << i << "] = " << W[i] << endl);
  }

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