#ifndef RunWriter_HH
#define RunWriter_HH

#include <cassert>

#include "DaqRunStart.hh"

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

#include "SubAccessor.hh"


class RunWriter : public RcdUserRO {

public:
  RunWriter() : RcdUserRO(), _dWriter(0), _startUp(0), _slowRecords(true) {
  }

  virtual ~RunWriter() {
    if(_dWriter!=0) delete _dWriter;
    if(_startUp!=0) delete _startUp;
  }

  bool record(const RcdRecord &r) {
    if(r.recordType()==RcdHeader::startUp) {
      _startUp=new RcdArena(r);
      return true;
    }

    if(r.recordType()==RcdHeader::runStart) {

      // Close last slow file if not first run
      if(_startUp==0) assert(_sWriter.close());

      // Open new slow file
      std::ostringstream sout;
      sout << "data/slw/Slw" << r.recordTime().seconds();
      assert(_sWriter.open(sout.str()));

      // If previous startUp record is stored, write out
      if(_startUp!=0) {
	assert(_sWriter.write(*_startUp));
	delete _startUp;
	_startUp=0;
      }

      // Close last data file
      if(_dWriter!=0) {
	assert(_dWriter->close());
	delete _dWriter;
	_dWriter=0;
      }

      // Access the DaqRunStart
      SubAccessor accessor(r);
      std::vector<const DaqRunStart*> v(accessor.extract<DaqRunStart>());
      assert(v.size()==1);
 
      DaqRunType rt(v[0]->runType());
      if(rt.writeRun()) {
	if(rt.ascWriteRun()) _dWriter=new RcdWriterAsc;
	else                 _dWriter=new RcdWriterBin;
      } else {
	_dWriter=new RcdWriterDmy;
      }

      // Open data output file
      std::ostringstream dout;
      dout << "data/dat/Run" << v[0]->runNumber();
      assert(_dWriter->open(dout.str()));
    }

    // Everything below acquisition doesn't get written to slow file
    if(r.recordType()==RcdHeader::acquisitionStart) {
      _slowRecords=false;
    }

    // Write out records
    if(_slowRecords) assert(_sWriter.write(r));
    if(r.recordType()!=RcdHeader::shutDown) {
      assert(_dWriter->write(r));

      // Check for file size
      if(_dWriter->numberOfBytes()>1800000) {
      std::cerr << "NUMBER OF BYTES WRITTEN = " << _dWriter->numberOfBytes() << std::endl;
	kill(getpid(),SIGUSR1);
      }
    }

    // Turn back on records to slow file
    if(r.recordType()==RcdHeader::acquisitionEnd) {
      _slowRecords=true;
    }
    
    if(r.recordType()==RcdHeader::runEnd) {
      if(_dWriter!=0) {
	assert(_dWriter->close());
	delete _dWriter;
	_dWriter=0;
      }
    }
    
    if(r.recordType()==RcdHeader::shutDown) {
      assert(_sWriter.close());
    }

    return true;
  }

  /*
  unsigned numberOfBytes() const {
    return _writer->numberOfBytes();
  }
  */

private:
  RcdWriterBin _sWriter;
  RcdWriter *_dWriter;
  RcdArena *_startUp;
  bool _slowRecords;
};

#endif
