#ifndef ChkCount_HH
#define ChkCount_HH

#include <iostream>
#include <iomanip>
#include <fstream>

// dual/inc/rcd
#include "RcdHeader.hh"
#include "RcdUserRO.hh"

// dual/inc/sub
#include "SubInserter.hh"

#include "RcdCount.hh"


class ChkCount : public RcdUserRO {

public:
  ChkCount() : RcdUserRO() {
    for(unsigned i(0);i<=RcdHeader::endOfRecordTypeEnum;i++) {
      _resetRecord[i]=false;
    }

    reset();
  }

  ChkCount(unsigned p) : RcdUserRO(p) {
    for(unsigned i(0);i<=RcdHeader::endOfRecordTypeEnum;i++) {
      _resetRecord[i]=false;
    }

    reset();
  }

  virtual ~ChkCount() {
    if(_printRecord[RcdHeader::endOfRecordTypeEnum]) _count.print(std::cout);
  }

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

    // Default to printing in dtor
    _printRecord[RcdHeader::endOfRecordTypeEnum]=true;
  }

  unsigned count(RcdHeader::RecordType rt) const {
    return _count.count(rt);
  }

  bool resetRecord(RcdHeader::RecordType rt=RcdHeader::endOfRecordTypeEnum, bool e=true) {
    if(rt<=RcdHeader::endOfRecordTypeEnum) {
      _resetRecord[rt]=e;
      return true;
    }
    return false;
  }

  bool printRecord(RcdHeader::RecordType rt=RcdHeader::endOfRecordTypeEnum, bool e=true) {
    if(rt<=RcdHeader::endOfRecordTypeEnum) {
      _printRecord[rt]=e;
      return true;
    }
    return false;
  }

  bool record(const RcdRecord &r) {
    _count+=r.recordType();

    unsigned rt(r.recordType());
    if(rt<RcdHeader::endOfRecordTypeEnum) {
      if(doPrint(r.recordType())) {
	std::cout << " Record " << std::setw(10) << _count.count(r.recordType())
		  << " (out of " << std::setw(10) << _count.totalCount()
		  << ") of type " << std::setw(2) << rt << " = " 
		  << RcdHeader::recordTypeName((RcdHeader::RecordType)rt)
		  << std::endl;
      }

      if(_resetRecord[rt]) reset();
      if(_printRecord[rt] || doPrint(r.recordType())) _count.print(std::cout) << std::endl;

    } else {
      std::cout << "Unknown record type = " << rt << std::endl;
      r.RcdHeader::print(std::cout);

      if(doPrint(r.recordType())) _count.print(std::cout) << std::endl;
    }

    return true;
  }

  std::ostream& print(std::ostream& o, std::string s="") const {
    return _count.print(o,s);
  } 

private:
  RcdCount _count;
  bool _resetRecord[RcdHeader::endOfRecordTypeEnum+1];
  bool _printRecord[RcdHeader::endOfRecordTypeEnum+1];
};

#endif
