#ifndef RcdCount_HH
#define RcdCount_HH

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

#include "RcdHeader.hh"
#include "RcdRecord.hh"


class RcdCount {

public:
  RcdCount() {
    reset();
  }

  void reset() {
    _totalCount=0;
    for(unsigned i(0);i<=RcdHeader::endOfRecordTypeEnum;i++) _count[i]=0;
  }

  unsigned count(RcdHeader::RecordType rt) const {
    if(rt<RcdHeader::endOfRecordTypeEnum) return _count[rt];
    return 0;
  }

  unsigned totalCount() const {
    return _totalCount;
  }

  void operator+=(RcdHeader::RecordType rt) {
    _totalCount++;
    if(rt<RcdHeader::endOfRecordTypeEnum) _count[rt]++;
    else _count[RcdHeader::endOfRecordTypeEnum]++;
  }

  void operator+=(const RcdRecord &r) {
    operator+=(r.recordType());
  }

  std::ostream& print(std::ostream& o, std::string s="") const {
    o << s << "RcdCount::print()  Total number of records = " 
      << std::setw(10) << _totalCount << std::endl;

    unsigned order[RcdHeader::endOfRecordTypeEnum]=
      //{0,15,1,2,25,3,8,4,21,9,22,23,5,24,6,7,17,10,11,12,13,16,14,18,20,19,26};
      {RcdHeader::startUp,
       RcdHeader::sequenceStart,
       RcdHeader::runStart,
       RcdHeader::configurationStart,
       RcdHeader::bunchTrain,
       RcdHeader::acquisitionStart,
       RcdHeader::spillStart,
       RcdHeader::spill,
       RcdHeader::trigger,
       RcdHeader::triggerBurst,
       RcdHeader::spillEnd,
       RcdHeader::transferStart,
       RcdHeader::event,
       RcdHeader::transferEnd,
       RcdHeader::acquisitionStop,
       RcdHeader::acquisitionEnd,
       RcdHeader::slowReadout,
       RcdHeader::configurationStop,
       RcdHeader::configurationEnd,
       RcdHeader::runStop,
       RcdHeader::runEnd,
       RcdHeader::sequenceEnd,
       RcdHeader::fileContinuation,
       RcdHeader::doNothing,
       RcdHeader::shutDown,
       RcdHeader::slowEnd,
       RcdHeader::postEvent};
    
    for(unsigned i(0);i<RcdHeader::endOfRecordTypeEnum;i++) {
      unsigned j(order[i]);
      if(_count[j]>0) {
	o << s << " Number of records of type " << std::setw(2) << j << " = " 
	  << RcdHeader::recordTypeName((RcdHeader::RecordType)j) << " = "
	  << std::setw(10) << _count[j] << std::endl;
      }
    }

    if(_count[RcdHeader::endOfRecordTypeEnum]>0)
      o << s << " Number of records of unknown type                 = " 
	<< std::setw(10) << _count[RcdHeader::endOfRecordTypeEnum]
	<< std::endl;

    return o;
  }


private:
  unsigned _totalCount;
  unsigned _count[RcdHeader::endOfRecordTypeEnum+1];
};

#endif
