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

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

#include "JDAQ/JDAQTimesliceIO.hh"
#include "km3net-dataformat/online/JDAQPMTIdentifier.hh"

#include "JSupport/JMultipleFileScanner.hh"
#include "JSupport/JSupport.hh"

#include "JROOT/JROOTClassSelector.hh"
#include "JLang/JTypeSelector.hh"
#include "JLang/JObjectMultiplexer.hh"
#include "JLang/JPipe.hh"
#include "JLang/JObjectOutput.hh"

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


using namespace std;
using namespace JPP;
using namespace KM3NETDAQ;


/**
 * Command line options.
 */
JDAQPMTIdentifier  PMT;
int                debug;
string             outputFile;


/**
 * Example class for data analysis.
 */
struct JAnalysis :
  public JObjectOutput<JDAQTimeslice>
{
  /**
   * Constructor.
   */
  JAnalysis() :
    //
    // Book histograms
    //
    h0("h0", NULL, numeric_limits<JDAQHit::JPMT_t>::max(), -0.5, numeric_limits<JDAQHit::JPMT_t>::max() - 0.5),
    h1("h1", NULL, numeric_limits<JDAQHit::JTOT_t>::max(), -0.5, numeric_limits<JDAQHit::JTOT_t>::max() - 0.5),
    h2("h2", NULL, 100,                                    -0.5, getFrameTime() + 0.5),
    //
    counter(0)
  {}

  
  /**
   * Destructior.
   */
  ~JAnalysis()
  {
    STATUS(endl);

    // save histograms
    
    TFile out(outputFile.c_str(), "recreate");

    out << h0 << h1 << h2;

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

  
  /**
   * Process data.
   *
   * \param  timeslice  timeslice
   * \return            true
   */
  virtual bool put(const JDAQTimeslice& timeslice)
  {
    STATUS("event: " << setw(10) << ++counter << '\r'); DEBUG(endl);
    
    for (JDAQTimeslice::const_iterator frame = timeslice.begin(); frame != timeslice.end(); ++frame) {
      for (JDAQSuperFrame::const_iterator hit = frame->begin(); hit != frame->end(); ++hit) {
	
	if (JDAQPMTIdentifier::compare(PMT, JDAQPMTIdentifier(frame->getModuleID(), hit->getPMT()))) {
	  h0.Fill(hit->getPMT());
	  h1.Fill(hit->getToT());
	  h2.Fill(hit->getT());
	}
      }
    }
    
    return true;
  }
  
  TH1D h0;
  TH1D h1;
  TH1D h2;

  counter_type counter;
};


/**
 * \file
 *
 * Example program to histogram KM3NETDAQ::JDAQTimeslice.
 * \author mdejong
 */
int main(int argc, char **argv)
{
  using namespace std;
  using namespace JPP;
  using namespace KM3NETDAQ;

  JMultipleFileScanner<JDAQTimesliceTypes_t> inputFile;
  JLimit_t&          numberOfEvents = inputFile.getLimit();
  JROOTClassSelector selector;

  try { 

    JParser<> zap("Example program to histogram timeslice data.");
    
    zap['f'] = make_field(inputFile);
    zap['o'] = make_field(outputFile)          = "timeslice.root";
    zap['n'] = make_field(numberOfEvents)      = JLimit::max();
    zap['P'] = make_field(PMT)                 = JDAQPMTIdentifier(-1, -1);
    zap['C'] = make_field(selector)            = getROOTClassSelection<JDAQTimesliceTypes_t>();
    zap['d'] = make_field(debug)               = 1;
    
    zap(argc, argv);
  }
  catch(const exception& error) {
    FATAL(error.what() << endl);
  }


  JAnalysis analysis;
  
  inputFile | JValve<JDAQTimesliceTypes_t>(selector) | JType<JDAQTimeslice>() | analysis;
}