#ifndef RunCount_HH
#define RunCount_HH

#include <sys/types.h>
#include <unistd.h>
#include <time.h>

#include "RcdCount.hh"


class RunCount {

public:
  enum {
    shmKey=0x76543213
  };

  RunCount() {
  }

  void increment(const RcdRecord &r) {

    // Count everything
    if(r.recordType()==RcdHeader::startUp) {
      _header[0]=(RcdHeader)r;
      _count[0].reset();
    }
    _count[0]+=r;

    // Count the current run
    if(r.recordType()==RcdHeader::startUp ||
       r.recordType()==RcdHeader::runStart) {
      _count[1].reset();
       if(r.recordType()==RcdHeader::runStart) _header[1]=(RcdHeader)r;
    }

    if(r.recordType()!=RcdHeader::startUp && 
       r.recordType()!=RcdHeader::shutDown) _count[1]+=r;

    // Count the current configuration
    if(r.recordType()==RcdHeader::startUp  ||
       r.recordType()==RcdHeader::runStart ||
       r.recordType()==RcdHeader::configurationStart) {
      _count[2].reset();
      if(r.recordType()==RcdHeader::configurationStart) _header[2]=(RcdHeader)r;
    }

    if(r.recordType()!=RcdHeader::startUp  && 
       r.recordType()!=RcdHeader::runStart &&
       r.recordType()!=RcdHeader::runEnd   &&
       r.recordType()!=RcdHeader::shutDown) _count[2]+=r;

    // Count the current acquisition
    if(r.recordType()==RcdHeader::startUp  ||
       r.recordType()==RcdHeader::runStart ||
       r.recordType()==RcdHeader::configurationStart ||
       r.recordType()==RcdHeader::acquisitionStart) {
      _count[3].reset();
      if(r.recordType()==RcdHeader::acquisitionStart) _header[3]=(RcdHeader)r;
    }

    if(r.recordType()!=RcdHeader::startUp            && 
       r.recordType()!=RcdHeader::runStart           &&
       r.recordType()!=RcdHeader::configurationStart &&
       r.recordType()!=RcdHeader::configurationEnd   &&
       r.recordType()!=RcdHeader::runEnd             &&
       r.recordType()!=RcdHeader::slowReadout        &&
       r.recordType()!=RcdHeader::shutDown) _count[3]+=r;

    // Last header
    _header[4]=(RcdHeader)r;
  }

  unsigned count(RcdHeader::RecordType t=RcdHeader::event, unsigned j=0) const {
    assert(j<4);
    return _count[j].count(t);
  }

  std::ostream& print(std::ostream& o, std::string s="") const {
    o << s << "RunCount::print()" << std::endl;

    _header[0].print(o,s+" Job  ");
    _count[0].print(o,s+" Job  ") << std::endl;

    _header[1].print(o,s+" Run  ");
    _count[1].print(o,s+" Run  ") << std::endl;

    _header[2].print(o,s+" Cfgn ");
    _count[2].print(o,s+" Cfgn ") << std::endl;

    _header[3].print(o,s+" Acqn ");
    _count[3].print(o,s+" Acqn ") << std::endl;

    _header[4].print(o,s+" Last ");

    return o;
  }

private:
  RcdHeader _header[5];
  RcdCount _count[4];
};

#endif
