#ifndef TrgSpillPollData_HH
#define TrgSpillPollData_HH

#include <string>
#include <iostream>

#include "UtlPack.hh"
#include "UtlTime.hh"


class TrgSpillPollData {

public:
  enum {
    versionNumber=0
  };

  TrgSpillPollData();


  UtlTimeDifference maximumSpillTime() const;
  void              maximumSpillTime(UtlTimeDifference t);

  UtlTimeDifference maximumPollTime() const;
  void              maximumPollTime(UtlTimeDifference t);

  unsigned maximumNumberOfEvents() const;
  void     maximumNumberOfEvents(unsigned n);


  UtlTime startSpillTime() const;
  UtlTime   endSpillTime() const;

  UtlTimeDifference actualSpillTime() const;

  void updateStartSpillTime();
  void updateEndSpillTime();

  UtlTime startPollTime() const;
  UtlTime   endPollTime() const;

  UtlTimeDifference actualPollTime() const;

  void updateStartPollTime();
  void updateEndPollTime();

  unsigned actualNumberOfEvents() const;
  void     actualNumberOfEvents(unsigned n);

  bool spillTimeout() const;

  bool  pollTimeout() const;

  bool maximumEvents() const;

  unsigned numberOfPolls() const;
  void     numberOfPolls(unsigned n);

  std::ostream& print(std::ostream &o, std::string s="") const;


private:
  UtlTimeDifference _maximumSpillTime;
  UtlTimeDifference _maximumPollTime;
  unsigned _maximumNumberOfEvents;

  UtlTime _startSpillTime;
  UtlTime _endSpillTime;
  UtlTime _startPollTime;
  UtlTime _endPollTime;
  unsigned _actualNumberOfEvents;

  unsigned _numberOfPolls;
};


#ifdef CALICE_DAQ_ICC

#include <cstring>

#include "UtlPrintHex.hh"

TrgSpillPollData::TrgSpillPollData() {
  memset(this,0,sizeof(TrgSpillPollData));
}

UtlTimeDifference TrgSpillPollData::maximumSpillTime() const {
  return _maximumSpillTime;
}

void TrgSpillPollData::maximumSpillTime(UtlTimeDifference t) {
  _maximumSpillTime=t;
}

UtlTimeDifference TrgSpillPollData::maximumPollTime() const {
  return _maximumPollTime;
}

void TrgSpillPollData::maximumPollTime(UtlTimeDifference t) {
  _maximumPollTime=t;
}

unsigned TrgSpillPollData::maximumNumberOfEvents() const {
  return _maximumNumberOfEvents;
}

void TrgSpillPollData::maximumNumberOfEvents(unsigned n) {
  _maximumNumberOfEvents=n;
}

UtlTime TrgSpillPollData::startSpillTime() const {
  return _startSpillTime;
}

UtlTime TrgSpillPollData::endSpillTime() const {
  return _endSpillTime;
}

UtlTimeDifference TrgSpillPollData::actualSpillTime() const {
  return _endSpillTime-_startSpillTime;
}

void TrgSpillPollData::updateStartSpillTime() {
  _startSpillTime.update();
}

void TrgSpillPollData::updateEndSpillTime() {
  _endSpillTime.update();
}

UtlTime TrgSpillPollData::startPollTime() const {
  return _startPollTime;
}

UtlTime TrgSpillPollData::endPollTime() const {
  return _endPollTime;
}

UtlTimeDifference TrgSpillPollData::actualPollTime() const {
  return _endPollTime-_startPollTime;
}

void TrgSpillPollData::updateStartPollTime() {
  _startPollTime.update();
}

void TrgSpillPollData::updateEndPollTime() {
  _endPollTime.update();
}

unsigned TrgSpillPollData::actualNumberOfEvents() const {
  return _actualNumberOfEvents;
}

void TrgSpillPollData::actualNumberOfEvents(unsigned n) {
  _actualNumberOfEvents=n;
}

bool TrgSpillPollData::spillTimeout() const {
  return (actualSpillTime()>_maximumSpillTime);
}

bool TrgSpillPollData::pollTimeout() const {
  return (actualPollTime()>_maximumPollTime);
}

bool TrgSpillPollData::maximumEvents() const {
  return (_actualNumberOfEvents>=_maximumNumberOfEvents);
}

unsigned TrgSpillPollData::numberOfPolls() const {
  return _numberOfPolls;
}

void TrgSpillPollData::numberOfPolls(unsigned n) {
  _numberOfPolls=n;
}

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

  o << s << " Maximum spill time = " << _maximumSpillTime
    << " secs" << std::endl;
  o << s << " Maximum poll time  = " << _maximumPollTime
    << " secs" << std::endl;
  o << s << " Maximum number of events = " << _maximumNumberOfEvents
    << std::endl;

  o << s << " Spill start time   = " << _startSpillTime << std::endl;
  o << s << " Spill end time     = " << _endSpillTime << std::endl;
  o << s << " Spill actual time  = " << actualSpillTime() << " secs";
  if(spillTimeout()) o << " = timeout";
  o << std::endl;

  o << s << " Poll start time    = " << _startPollTime << std::endl;
  o << s << " Poll end time      = " << _endPollTime << std::endl;
  o << s << " Poll actual time   = " << actualPollTime() << " secs";
  if(pollTimeout()) o << " = timeout";
  o << std::endl;

  o << s << " Actual number of events = " << _actualNumberOfEvents;
  if(actualPollTime().deltaTime()!=0.0) {
    o << " = " << _actualNumberOfEvents/actualPollTime().deltaTime() << " events/sec";
  }
  if(maximumEvents()) o << " = maximum";
  o << std::endl;

  o << s << " Number of polls = " << _numberOfPolls;
  if(actualPollTime().deltaTime()!=0.0) {
    o << " = " << _numberOfPolls/actualPollTime().deltaTime() << " polls/sec";
  }
  o << std::endl;


  return o;
}

#endif
#endif
