#ifndef EmcStageReadout_HH
#define EmcStageReadout_HH

#include <iostream>
#include <fstream>

// dual/inc/utl
#include "UtlPack.hh"

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

// dual/inc/emc
#include "EmcStageRunData.hh"

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

// dual/inc/skt
#include "DuplexSocket.hh"


class EmcStageReadout : public RcdUserRW {

public:
  EmcStageReadout(std::string ipAddress="134.158.90.89",
		  unsigned port=1200, unsigned tries=10) :
    RcdUserRW(), _socket(ipAddress.c_str(),port,tries) {

    std::cout << "EmcStageReadout::ctor()  Socket established" << std::endl;
    
    // Construct "magic numbers" to send
    _sendData[0]=0x4c554150; // "PAUL" endian-swapped
    _sendData[1]=0x30313030; // "0010" endian-swapped = length of 10 words
    _sendLength=8;
  }

  virtual ~EmcStageReadout() {
  }

  void bad() {
    _sendData[0]=0x12345678;
    _sendData[1]=0x87654321;
  }

  void good() {
    _sendData[0]=0x4c554150; // "PAUL" endian-swapped
    _sendData[1]=0x30313030; // "0010" endian-swapped = length of 10 words
  }


  bool record(RcdRecord &r) {
    if(doPrint(r.recordType())) {
      std::cout << "EmcStageReadout::record()" << std::endl;
      r.RcdHeader::print(std::cout," ") << std::endl;
    }
     
    // Check record type
    if(r.recordType()==RcdHeader::startUp  ||
       r.recordType()==RcdHeader::runStart ||
       r.recordType()==RcdHeader::runEnd   ||
       r.recordType()==RcdHeader::runStop) {
      
      if(!_socket.send((const char*)_sendData,_sendLength)) {
	std::cerr << "EmcStageReadout::record()  Error writing to socket;"
		  << " number of bytes written < 8" << std::endl;
	perror(0);
	return false;
      }

      SubInserter inserter(r);
      EmcStageRunData *d(inserter.insert<EmcStageRunData>());
	
      int n(-1);
      n=_socket.recv((char*)d,4);
      if(n!=4) {
	std::cerr << "Error reading from socket; number of bytes written = "
		  << n << " < 4" << std::endl;
	perror(0);
	return false;
      }

      if(d->headerError()) {
	std::cerr << "Error in header from socket" << std::endl;
	return false;
      }

      n=_socket.recv(((char*)d)+4,sizeof(EmcStageRunData)-4);
      if(n!=sizeof(EmcStageRunData)-4) {
	std::cerr << "Error reading from socket; number of bytes written = "
		  << n << " < " << sizeof(EmcStageRunData)-4
		  << std::endl;
	perror(0);
	return false;
      }
      
      if(doPrint(r.recordType(),1)) 
	d->print(std::cout," ") << std::endl;

      // TEMP; print for check
      std::cout << r.recordTime() << " ECAL STAGE X POSITION " << d->xStandPosition() << std::endl;
    }

    return true;
  }
    
private:
  DuplexSocket _socket;
  unsigned _sendLength;
  unsigned _sendData[2];
};

#endif
