#ifndef SlwSource_HH
#define SlwSource_HH

#include <vector>
#include <fstream>
#include <iostream>

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

// dual/inc/daq
#include "DaqSlwControl.hh"
#include "ShmObject.hh"




class SlwSource : public RcdUserRW {

public:
  SlwSource() : RcdUserRW(), _shmSlwControl(DaqSlwControl::shmKey), _pDsc(0) {
    _pDsc=_shmSlwControl.payload();
    assert(_pDsc!=0);
  
    // Catch previous shutdown command when restarting
    if(_pDsc->command()==DaqSlwControl::dead)
      _pDsc->command(0,DaqSlwControl::running);

    _pDsc->commandRegister();
  }

  virtual ~SlwSource() {
    _pDsc->unregister();
  }

  bool record(RcdRecord &r) {

    // Check record type
    switch (_pDsc->status()) {

    case DaqSlwControl::dead: {
      while(_pDsc->command()<DaqSlwControl::running) sleep(10);
      r.initialise(RcdHeader::startUp);
      break;
    }

    case DaqSlwControl::waiting: {
      DaqSlwControl::State c;
      while((c=_pDsc->command())==DaqSlwControl::waiting) sleep(10);

      if(c>DaqSlwControl::waiting) {
	r.initialise(RcdHeader::slowStart);
      } else {
	r.initialise(RcdHeader::shutdown);
      }
      break;
    }

    case DaqSlwControl::initialising: {
      DaqSlwControl::State c;
      while((c=_pDsc->command())==DaqSlwControl::initialising) sleep(10);

      if(c>DaqSlwControl::initialising) {
	r.initialise(RcdHeader::slowControl);
      } else {
	r.initialise(RcdHeader::slowEnd);
      }
      break;
    }

    case DaqSlwControl::running: {
      if(_pDsc->command()>=DaqSlwControl::running) {
	r.initialise(RcdHeader::slowReadout);
      } else {
	r.initialise(RcdHeader::slowEnd);
      }
      break;
    }

    default: {
      assert(true);
      break;
    }
    };

    _pDsc->transition(r);
    
    return true;
  }
  
private:
  ShmObject<DaqSlwControl> _shmSlwControl;
  DaqSlwControl *_pDsc;
};

#endif
