#ifndef HstLalHodoscopeMap_HH
#define HstLalHodoscopeMap_HH

#include <cassert>

//#include "TROOT.h"
#include "TMapFile.h"
#include "TH1F.h"
#include "TH2F.h"
#include "TProfile.h"
#include "TRandom.h"

#include "DaqRunStart.hh"

#include "RcdUserRO.hh"
#include "RcdWriterDmy.hh"
#include "RcdWriterAsc.hh"
#include "RcdWriterBin.hh"

#include "UtlRollingAverage.hh"
#include "SubAccessor.hh"


class HstLalHodoscopeMap : public RcdUserRO {

public:
  HstLalHodoscopeMap() {
    _stitle="LC1176 Number of words";
    _size=new TH1F("HstLalHodoscopeSize",_stitle.c_str(),256,0,256);

    for(unsigned i(0);i<16;i++) {
      std::ostringstream label,title;
      
      label << "HstLalHodoscopeCh";
      if(i<10) label << "0";
      label << i;
      
      title << "LC1176 Channel " << std::setw(2) << i;
      
      for(unsigned j(0);j<3;j++) {
	std::string lab(label.str());
	if(j==0) lab+="Numb";
	if(j==1) lab+="Lead";
	if(j==2) lab+="Fall";
	
	_title[i][j]=title.str();
	if(j==0) _title[i][j]+=", Number of hits";
	if(j==1) _title[i][j]+=", Leading edge times";
	if(j==2) _title[i][j]+=", Falling edge times";
	
	if(j==0) _hits[i][j]=new TH1F(lab.c_str(),_title[i][j].c_str(),32,0,32);
	else     _hits[i][j]=new TH1F(lab.c_str(),_title[i][j].c_str(),500,0,10000);
      }
    }
  }

  virtual ~HstLalHodoscopeMap() {
    for(unsigned i(0);i<16;i++) {
      for(unsigned j(0);j<3;j++) {
	delete _hits[i][j];
      }
    }
  }

  bool record(const RcdRecord &r) {
    if(doPrint(r.recordType())) {
      std::cout << "HstLalHodoscopeMap::record()" << std::endl;
      r.RcdHeader::print(std::cout," ") <<std::endl;
    }

    if(r.recordType()==RcdHeader::runStart) {

      SubAccessor accessor(r);

      std::vector<const DaqRunStart* >
	w(accessor.access<DaqRunStart>());

      if(w.size()>0) w[0]->print(std::cout);
      if(w.size()>0) _runNumber=w[0]->runNumber();
      if(_runNumber==0) _runNumber=999999;

      std::ostringstream sout;
      sout << std::setw(6) << _runNumber;

      _size->Reset();
      _size->SetTitle((_stitle+", Run "+sout.str()).c_str());

      for(unsigned i(0);i<16;i++) {
	for(unsigned j(0);j<3;j++) {
	  _hits[i][j]->Reset();
	  _hits[i][j]->SetTitle((_title[i][j]+", Run "+sout.str()).c_str());
	}
      }      

      return true;
    }


    if(r.recordType()==RcdHeader::event) {
      SubAccessor accessor(r);
      std::vector<const BmlLalHodoscopeEventData*> 
	v(accessor.access< BmlLalHodoscopeEventData >());

      unsigned n[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

      if(v.size()>0) {
	_size->Fill(v[0]->numberOfWords());

      	const UtlPack *p((const UtlPack*)v[0]->data());
	for(unsigned i(0);i<v[0]->numberOfWords();i++) {
	  unsigned chn((p[i].word()>>17)&0xf);   // Channel
	  unsigned time(p[i].halfWord(0));       // TDC time
	  //cout << " channel " << chn << " time " << time << endl;

	  n[chn]++;	  
	  if(p[i].bit(16)) {  
	    _hits[chn][1]->Fill(time);//  leading edge
	  } else {
	    _hits[chn][2]->Fill(time);//falling edge
	  }  
	}

      // Catch case of missing event data
      } else {
	_size->Fill(0);
      }

      for(unsigned i(0);i<16;i++) _hits[i][0]->Fill(n[i]);

      return true;
    }

    return true;
  }

private:
  unsigned _runNumber;
  std::string _stitle;
  TH1F *_size;
  std::string _title[16][3];
  TH1F *_hits[16][3];
};

#endif
