#ifndef RcdSktRcdUserRW_HH
#define RcdSktRcdUserRW_HH

#include <iostream>
#include <fstream>
#include <string>

#include "RcdUserRW.hh"
#include "RcdIoSkt.hh"


class RcdSktRcdUserRW : public RcdUserRW {

public:
  RcdSktRcdUserRW(RcdUserRW &u, std::string host,
		  unsigned port, unsigned tries) :
    _userRW(u), _serial(false) {

    _socket.open(host,port,tries);

    // Local copy space; SIZE is in bytes
    _data=new unsigned[CALICE_DAQ_SIZE/4];
  }

  virtual ~RcdSktRcdUserRW() {
    _socket.close();
    delete [] _data;
  }

  void serial(bool s) {
    _serial=s;
  }

  virtual bool record(RcdRecord &r) {
    //SubAccessor accessor(r);
    //accessor.print(std::cout,"Orig ");

    assert(_socket.write(r));

    if(_serial) {
      assert(_socket.read(r));
      assert(_userRW.record(r));

    } else {
      const unsigned nw(r.numberOfWords());
      const unsigned *newData(r.newData());

      assert(_userRW.record(r));
      //accessor.print(std::cout,"Usr ");
      const unsigned newWords(r.numberOfWords()-nw);

      if(newWords>(CALICE_DAQ_SIZE/8)) { // Allow to have half the SIZE
	std::cerr << "RcdSktRcdUserRW::record()  ERROR  Socket 1 returns "
		  << newWords << " new words in record" << std::endl;
	r.RcdHeader::print(std::cerr) << std::endl;
      }

      memcpy(_data,newData,4*newWords);

      assert(_socket.read(r));
      //accessor.print(std::cout,"Skt ");
      r.extend(newWords,_data);
      //accessor.print(std::cout,"Total");
    }

    if(r.recordType()==RcdHeader::shutDown) {
      assert(_socket.close());
    }

    return true;
  }

private:
  RcdIoSkt _socket;
  RcdUserRW &_userRW;
  bool _serial;
  unsigned *_data;
};

#endif
