#ifndef HstLc1176Shm_HH
#define HstLc1176Shm_HH

#include <cassert>

#include "TH1F.h"

#include "DaqRunStart.hh"

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

#include "UtlAverage.hh"
#include "SubAccessor.hh"

#include "HstLc1176Store.hh"
#include "ShmObject.hh"


class HstLc1176Shm : public RcdUserRO {

public:
  HstLc1176Shm() :
    _shmHstLc1176Store(HstLc1176Store::shmKey), _pShm(_shmHstLc1176Store.payload()) {
    assert(_pShm!=0);
  }

  virtual ~HstLc1176Shm() {
  }

  bool record(const RcdRecord &r) {

    // Check for user-requested reset
    if(_pShm->_resetNow) {
      _pShm->reset();
      _pShm->_resetNow=false;
    }

    _pShm->fill(r);

    switch (r.recordType()) {
  
    case RcdHeader::runStart: {
      if(_pShm->_resetLevel==HstFlags::run) _pShm->reset();
      break;
    }
  
    case RcdHeader::configurationStart: {
      if(_pShm->_resetLevel==HstFlags::configuration) _pShm->reset();
      break;
    }
  
    case RcdHeader::acquisitionStart: {
      if(_pShm->_resetLevel==HstFlags::acquisition) _pShm->reset();
      break;
    }
  
    case RcdHeader::event: {
      if(_pShm->_resetLevel==HstFlags::event) _pShm->reset();

      SubAccessor accessor(r);

      std::vector<const BmlLc1176EventData*>
        v(accessor.access< BmlLc1176EventData >());

      if(v.size()<9) _pShm->_size[v.size()]++;
      else           _pShm->_size[       9]++;
      
      unsigned n[16][2];
      memset(n,0,16*2*sizeof(unsigned));
 
      if(v.size()>0) {
	if(v[0]->numberOfWords()<259) _pShm->_numberOfWords[v[0]->numberOfWords()]++;
	else                          _pShm->_numberOfWords[                  259]++;
	_pShm->_bufferNumber[v[0]->bufferNumber()]++;

	
	//const BmlLc1176EventDatum *p(v[0]->datum());
	const BmlLc1176EventDatum *p((const BmlLc1176EventDatum*)(v[0]->data()));
	
        for(unsigned i(0);i<v[0]->numberOfWords();i++) {
	  //p[i].print(std::cout);

          unsigned chn(p[i].channelNumber());
	  if(chn>15) chn=15;

	  unsigned time(p[i].time());
	  //if(time>9999) time=9999; // Don't store overflows
	  
	  if(p[i].leadingEdge()) {
	    n[chn][0]++;
	    if(time<10000) _pShm->_tdc[chn][0][time]++;// leading edge
          } else {
	    n[chn][1]++;
            if(time<10000) _pShm->_tdc[chn][1][time]++;// falling edge
          }
	}
 
	// Catch case of missing event data
      } else {
	_pShm->_numberOfWords[0]++;
      }
      
      for(unsigned i(0);i<16;i++) {
	_pShm->_numberOfWordsPerChannel[i][0][n[i][0]]++;
	_pShm->_numberOfWordsPerChannel[i][1][n[i][1]]++;
      }
      	
      _pShm->_validEvent=true;
      break;
    }
  
    default: {
      break;
    }
    };
 
    return true;
  }

private:
  ShmObject<HstLc1176Store> _shmHstLc1176Store;
  HstLc1176Store *_pShm;
};

#endif
