#ifndef DaqSlwControl_HH
#define DaqSlwControl_HH

#include <sys/types.h>
#include <unistd.h>

#include <string>

#include "RcdCount.hh"
#include "DaqControl.hh"


class DaqSlwControl : public DaqControl {

public:
  enum {
    shmKey=0x76543212
  };

  enum State {
    dead,
    waiting,
    initialising,
    running,
    endOfStateEnum
  };

  DaqSlwControl() {
    for(unsigned i(0);i<maxCommand;i++) command(i,endOfStateEnum,false);
  }

  State status() const {
    return (State)DaqControl::status();
  }

  void status(State s, bool wake=true) {
    if(s>=endOfStateEnum) s=running;
    if(_command[2]>=s) _command[2]=running;
    if(_command[3]>=s) _command[3]=running;
    DaqControl::status(s,wake);
  }

  State command() const {
    return (State)DaqControl::command();
  }

  void command(unsigned n, State s, bool wake=true) {
    if(s>=endOfStateEnum) s=running;
    DaqControl::command(n,s,wake);
  }

  void count(const RcdHeader &r, bool wake=true) {
    _count+=r;
    _transition=r;
    if(wake) statusSignal();
  }

  void resetCount(bool wake=true) {
    _count.reset();
    if(wake) statusSignal();
  }

  RcdHeader transition() const {
    return _transition;
  }

  void transition(const RcdHeader &t, bool wake=true) {
    _transition=t;
    if(wake) statusSignal();
  }

  std::string statusName() const {
    return stateName(status());
  }

  std::string commandName() const {
    return stateName(command());
  }

  std::string stateName(State s) const {
    if(s<endOfStateEnum) return _stateName[s];
    else                 return "unknown";
  }

  std::ostream& print(std::ostream& o, std::string s="") const {
    o << s << "DaqSlwControl::print()" << std::endl;

    DaqControl::print(o,s+" ");

    o << s<< " Last header ";
    _transition.print(o,s+" ");

    o << s << " Command = " << command() << " = " << commandName() << std::endl;
    o << s << " Status  = " << status() << " = " << statusName() << std::endl;
    
    _count.print(o,s+" ");

    return o;
  }

private:
  RcdCount _count;
  RcdHeader _transition;

  static const std::string _stateName[endOfStateEnum];
};

const std::string DaqSlwControl::_stateName[]={
  "dead        ",
  "waiting     ",
  "initialising",
  "running     "
};

#endif
