#ifndef SubInserter_HH
#define SubInserter_HH

#include "RcdRecord.hh"
#include "SubHeader.hh"
#include "SubRecordType.hh"


class SubInserter {

public:
  SubInserter(RcdRecord &r);

  template<class Payload> void insert(const Payload &p);
  template<class Payload> void insert(const Payload *p);
  template<class Payload> Payload* insert(bool pNew=false);

  bool extend(unsigned b);


private:
  RcdRecord &_record;
  SubHeader *_header;
};

template<class Payload> void SubInserter::insert(const Payload &p) {
  _header=(SubHeader*)_record.newData();
  SubHeader h(subRecordType<Payload>(),sizeof(Payload));
  _record.extend(h.header());
  _record.extend((sizeof(Payload)+3)/4,(const unsigned*)&p);
}

template<class Payload> void SubInserter::insert(const Payload *p) {
  _header=(SubHeader*)_record.newData();
  SubHeader h(subRecordType<Payload>(),sizeof(Payload));
  _record.extend(h.header());
  _record.extend((sizeof(Payload)+3)/4,(const unsigned*)p);
}

template<class Payload> Payload* SubInserter::insert(bool pNew) {
  _header=(SubHeader*)_record.newData();
  SubHeader h(subRecordType<Payload>(),sizeof(Payload));
  _record.extend(h.header());
  
  Payload *p(0);
  if(pNew) {
    //std::cout << "SubInserter::insert()  Placement new!!!" << std::endl;
    p=new((Payload*)_record.newData()) Payload;
  } else {
    p=(Payload*)_record.newData();
  }

  _record.extend((sizeof(Payload)+3)/4,0);
  
  return p;
}


#ifdef CALICE_DAQ_ICC

SubInserter::SubInserter(RcdRecord &r) : _record(r), _header(0) {
}

bool SubInserter::extend(unsigned b) {
  if(_header==0) return false;
  _header->numberOfBytes(_header->numberOfBytes()+b);
  _record.extend((b+3)/4,0);
  return true;
}

#endif
#endif
