#ifndef HstCosmicCheck_HH
#define HstCosmicCheck_HH

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

#include "TROOT.h"
#include "TApplication.h"
#include "TCanvas.h"
#include "TH1D.h"
#include "TH2D.h"
#include "TPostScript.h"

#include "UtlAverage.hh"
#include "RcdRecord.hh"
#include "EmcCercFeEventData.hh"
#include "HodData.hh"
#include "HodTrack.hh"
#include "DaqEvent.hh"
#include "SubExtracter.hh"


class HstCosmicCheck {

public:
  TH1D* hist1(std::string t, unsigned n, double l, double h) {
    unsigned num(_hist1Vector.size());
    ostringstream oss;
    oss << num;

    _canvas1Vector.push_back(new TCanvas((std::string("Canvas1[")+oss.str()+std::string("]")).c_str(),
					 (t+" canvas").c_str(),10+10*num,10+10*num,600,400));
    _hist1Vector.push_back(new TH1D((std::string("TH1D[")+oss.str()+std::string("]")).c_str(),
				    t.c_str(),n,l,h));
    return _hist1Vector[num];
  }

  TH2D* hist2(std::string t, unsigned nx, double lx, double hx, unsigned ny, double ly, double hy) {
    unsigned num(_hist2Vector.size());
    ostringstream oss;
    oss << num;

    _canvas2Vector.push_back(new TCanvas((std::string("Canvas2[")+oss.str()+std::string("]")).c_str(),
					 (t+" canvas").c_str(),500+10*num,10+10*num,600,400));
    _hist2Vector.push_back(new TH2D((std::string("TH2D[")+oss.str()+std::string("]")).c_str(),
				    t.c_str(),nx,lx,hx,ny,ly,hy));
    return _hist2Vector[num];
  }

  void update() {
    for(unsigned i(0);i<_canvas1Vector.size();i++) {
      _canvas1Vector[i]->cd();
      _hist1Vector[i]->Draw();
      _canvas1Vector[i]->Update();
    }
    for(unsigned i(0);i<_canvas2Vector.size();i++) {
      _canvas2Vector[i]->cd();
      _hist2Vector[i]->Draw("box");
      _canvas2Vector[i]->Update();
    }
  }

  void postscript(std::string file) {
    TPostScript ps(file.c_str(),112);
    update();
    ps.Close();
  }

  HstCosmicCheck()
    : _application("Histogram Application",0,0)
  {

    gROOT->Reset();
    gROOT->SetStyle("Plain");

    TH1D *p(0);
    //p=hist1("Hodoscope occupancy",80,0.0,80.0);
    //p=hist1("Channel occupancy for high ADC values",216,0.0,216.0);

    TH2D *q(0);
    q=hist2("Record types vs record words",100,0.0,400.0,20,0.0,20.0);
    //q=hist2("Hodoscope interpolation",50,0.0,20.0,50,0.0,20.0);
    //q=hist2("Hodoscope interpolation for high ADC values",50,0.0,20.0,50,0.0,20.0);
    //q=hist2("Channel ADC values",216,0.0,216.0,70,-100.0,600.0);
    //q=hist2("Channel ADC values above pedestal",216,0.0,216.0,100,-50.0,150.0);

    update();
    _nAdc=0;
  }

  virtual ~HstCosmicCheck() {
  }

  void event(RcdRecord &r) {
    _hist2Vector[0]->Fill(r.numberOfWords(),r.recordType());

    SubExtracter extracter(r);

    if(r.recordType()==SubHeader::runStop || 
       r.recordType()==SubHeader::runEnd) {
      std::vector<const DaqRunEnd*> d(extracter.extract<DaqRunEnd>());
      assert(d.size()==1);
      ostringstream oss;
      oss << "Run" << d[0]->runNumber() << ".ps";
      postscript(oss.str());
    }

    if(r.recordType()!=SubHeader::event) return;

    std::vector<const DaqEvent*> z(extracter.extract<DaqEvent>());
    assert(z.size()==1);
    //if(z[0]->eventNumberInRun()>13600) std::cout << "Event " << z[0]->eventNumberInRun() << std::endl;
    //if(z[0]->eventNumberInRun()>13626) r.print(std::cout);

    bool goodTrack(false);

    bool goodHit(false);
    std::vector<const EmcCercFeEventData*> v(extracter.extract<EmcCercFeEventData>());

    for(unsigned i(0);i<v.size();i++) {
      if(v[i]->feNumber()==0 && v[i]->numberOfSamples()==18) {
	for(unsigned chan(0);chan<18;chan++) {
	  for(unsigned chip(0);chip<12;chip++) {
	    int xx=v[i]->adcEventData(chan)->adc(chip);
	    if(xx>0x7fff) xx-=0x10000;
	    //_hist2Vector[3]->Fill(18*chip+chan,xx);
	    if(_nAdc>100) {
	      //_hist2Vector[4]->Fill(18*chip+chan,xx-_ped[chip][chan]);
	      if(xx-_ped[chip][chan]>40.0) {
		goodHit=true;
		//_hist1Vector[1]->Fill(18*chip+chan);
	      }
	    }

	    _adc[chip][chan][_nAdc%100]=xx;
	    _ped[chip][chan]=0.0;
	    for(unsigned j(0);j<100;j++) _ped[chip][chan]+=xx;
	    _ped[chip][chan]*=0.01;
	  }
	}
	_nAdc++;
      }
    }

    if((z[0]->eventNumberInRun()%100)==0) update();
  }

private:
  TApplication _application;

  std::vector<TCanvas*> _canvas1Vector;
  std::vector<TCanvas*> _canvas2Vector;
  std::vector<TPad*> _pad1Vector;
  std::vector<TH1D*> _hist1Vector;
  std::vector<TH2D*> _hist2Vector;

  unsigned _nAdc;
  int _adc[12][18][100];
  double _ped[12][18];

  UtlAverage _average[216];
};

#endif
