#ifndef DaqConfigurationStartV2_HH
#define DaqConfigurationStartV2_HH

#include <string>
#include <iostream>

#include "UtlPack.hh"

class DaqConfigurationStartV0;
class DaqConfigurationStartV1;


class DaqConfigurationStartV2 {

public:
  enum {
    versionNumber=2
  };

  DaqConfigurationStartV2();
  DaqConfigurationStartV2(const DaqConfigurationStartV0 &d);
  DaqConfigurationStartV2(const DaqConfigurationStartV1 &d);

  void reset();

  unsigned configurationNumberInRun() const;
  void     configurationNumberInRun(unsigned n);

  // Limits configuration

  unsigned maximumNumberOfAcquisitionsInConfiguration() const;
  void     maximumNumberOfAcquisitionsInConfiguration(unsigned m);

  unsigned maximumNumberOfEventsInConfiguration() const;
  void     maximumNumberOfEventsInConfiguration(unsigned m);

  UtlTimeDifference maximumTimeOfConfiguration() const;
  void              maximumTimeOfConfiguration(UtlTimeDifference n);

  // Limits acquisition

  unsigned maximumNumberOfEventsInAcquisition() const;
  void     maximumNumberOfEventsInAcquisition(unsigned m);
 
  UtlTimeDifference maximumTimeOfAcquisition() const;
  void              maximumTimeOfAcquisition(UtlTimeDifference n);

  // Limits spill

  unsigned maximumNumberOfEventsInSpill() const;
  void     maximumNumberOfEventsInSpill(unsigned m);
 
  UtlTimeDifference maximumTimeOfSpill() const;
  void              maximumTimeOfSpill(UtlTimeDifference n);

  // Limits event

  UtlTimeDifference maximumTimeOfEvent() const;
  void              maximumTimeOfEvent(UtlTimeDifference n);

  // Limits slow readout
  UtlTimeDifference minimumTimeBeforeSlowReadout() const;
  void              minimumTimeBeforeSlowReadout(UtlTimeDifference n);

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

protected:
  unsigned _configurationNumberInRun;

  unsigned _maximumNumberOfAcquisitionsInConfiguration;
  unsigned _maximumNumberOfEventsInConfiguration;
  UtlTimeDifference _maximumTimeOfConfiguration;

  unsigned _maximumNumberOfEventsInAcquisition;
  UtlTimeDifference _maximumTimeOfAcquisition;

  unsigned _maximumNumberOfEventsInSpill;
  UtlTimeDifference _maximumTimeOfSpill;

  UtlTimeDifference _maximumTimeOfEvent;

  UtlTimeDifference _minimumTimeBeforeSlowReadout;
};


#ifdef CALICE_DAQ_ICC

#include "DaqConfigurationStartV0.hh"
#include "DaqConfigurationStartV1.hh"


DaqConfigurationStartV2::DaqConfigurationStartV2() {
  reset();
}

DaqConfigurationStartV2::DaqConfigurationStartV2(const DaqConfigurationStartV0 &d) {
  reset();
  _configurationNumberInRun=d.configurationNumberInRun();
  _maximumNumberOfAcquisitionsInConfiguration=d.maximumNumberOfAcquisitionsInConfiguration();
  _maximumNumberOfEventsInConfiguration=d.maximumNumberOfEventsInConfiguration();
}

DaqConfigurationStartV2::DaqConfigurationStartV2(const DaqConfigurationStartV1 &d) {
  _configurationNumberInRun=d.configurationNumberInRun();
  _maximumNumberOfAcquisitionsInConfiguration=d.maximumNumberOfAcquisitionsInConfiguration();
  _maximumNumberOfEventsInConfiguration=d.maximumNumberOfEventsInConfiguration();
  _maximumTimeOfConfiguration=d.maximumTimeOfConfiguration();
  _maximumNumberOfEventsInAcquisition=d.maximumNumberOfEventsInAcquisition();
  _maximumTimeOfAcquisition=d.maximumTimeOfAcquisition();
  _maximumNumberOfEventsInSpill=d.maximumNumberOfEventsInAcquisition(); // Defined to be equal for V1
  _maximumTimeOfSpill=d.maximumTimeOfSpill();
  _maximumTimeOfEvent=d.maximumTimeOfEvent();
  _minimumTimeBeforeSlowReadout=d.minimumTimeBeforeSlowReadout();
}

void DaqConfigurationStartV2::reset() {
  _configurationNumberInRun=0;

  _maximumNumberOfAcquisitionsInConfiguration=0xffffffff;
  _maximumNumberOfEventsInConfiguration=0xffffffff;
  _maximumTimeOfConfiguration=UtlTimeDifference(0x7fffffff,999999);

  _maximumNumberOfEventsInAcquisition=0xffffffff;
  _maximumTimeOfAcquisition=UtlTimeDifference(0x7fffffff,999999);

  _maximumNumberOfEventsInSpill=0xffffffff;
  _maximumTimeOfSpill=UtlTimeDifference(0x7fffffff,999999);

  _maximumTimeOfEvent=UtlTimeDifference(0x7fffffff,999999);

  _minimumTimeBeforeSlowReadout=UtlTimeDifference(60,0);
}

unsigned DaqConfigurationStartV2::configurationNumberInRun() const {
  return _configurationNumberInRun;
}

void DaqConfigurationStartV2::configurationNumberInRun(unsigned n) {
  _configurationNumberInRun=n;
}

unsigned DaqConfigurationStartV2::maximumNumberOfAcquisitionsInConfiguration() const {
  return _maximumNumberOfAcquisitionsInConfiguration;
}

void DaqConfigurationStartV2::maximumNumberOfAcquisitionsInConfiguration(unsigned m) {
  _maximumNumberOfAcquisitionsInConfiguration=m;
}

unsigned DaqConfigurationStartV2::maximumNumberOfEventsInConfiguration() const {
  return _maximumNumberOfEventsInConfiguration;
}

void DaqConfigurationStartV2::maximumNumberOfEventsInConfiguration(unsigned m) {
  _maximumNumberOfEventsInConfiguration=m;
}

UtlTimeDifference DaqConfigurationStartV2::maximumTimeOfConfiguration() const {
  return _maximumTimeOfConfiguration;
}
 
void DaqConfigurationStartV2::maximumTimeOfConfiguration(UtlTimeDifference n) {
  _maximumTimeOfConfiguration=n;
}

unsigned DaqConfigurationStartV2::maximumNumberOfEventsInAcquisition() const {
  return _maximumNumberOfEventsInAcquisition;
}
 
void DaqConfigurationStartV2::maximumNumberOfEventsInAcquisition(unsigned m) {
  _maximumNumberOfEventsInAcquisition=m;
}
 
UtlTimeDifference DaqConfigurationStartV2::maximumTimeOfAcquisition() const {
  return _maximumTimeOfAcquisition;
}
                                                                               
void DaqConfigurationStartV2::maximumTimeOfAcquisition(UtlTimeDifference n) {
  _maximumTimeOfAcquisition=n;
}

unsigned DaqConfigurationStartV2::maximumNumberOfEventsInSpill() const {
  return _maximumNumberOfEventsInSpill;
}
 
void DaqConfigurationStartV2::maximumNumberOfEventsInSpill(unsigned m) {
  _maximumNumberOfEventsInSpill=m;
}
 
UtlTimeDifference DaqConfigurationStartV2::maximumTimeOfSpill() const {
  return _maximumTimeOfSpill;
}

void DaqConfigurationStartV2::maximumTimeOfSpill(UtlTimeDifference n) {
  _maximumTimeOfSpill=n;
}
 
UtlTimeDifference DaqConfigurationStartV2::maximumTimeOfEvent() const {
  return _maximumTimeOfEvent;
}

void DaqConfigurationStartV2::maximumTimeOfEvent(UtlTimeDifference n) {
  _maximumTimeOfEvent=n;
}
 
UtlTimeDifference DaqConfigurationStartV2::minimumTimeBeforeSlowReadout() const {
  return _minimumTimeBeforeSlowReadout;
}

void DaqConfigurationStartV2::minimumTimeBeforeSlowReadout(UtlTimeDifference n) {
  _minimumTimeBeforeSlowReadout=n;
}
 
std::ostream& DaqConfigurationStartV2::print(std::ostream &o, std::string s) const {
  o << s << "DaqConfigurationStartV2::print()" << std::endl;
  o << s << " Configuration number            = "
    << std::setw(11) << _configurationNumberInRun << std::endl;
  o << s << " Maximum numbers of acquisitions = " 
    << std::setw(11) << _maximumNumberOfAcquisitionsInConfiguration << std::endl;
  o << s << " Maximum numbers of events       = " 
    << std::setw(11) << _maximumNumberOfEventsInConfiguration << ", "
    << std::setw(11) << _maximumNumberOfEventsInAcquisition << ", "
    << std::setw(11) << _maximumNumberOfEventsInSpill << std::endl;
  o << s << " Maximum time of configuration   = " << std::setw(11)
    //<< (unsigned)(_maximumTimeOfConfiguration.deltaTime()) << " secs" << std::endl;
    << _maximumTimeOfConfiguration << " secs" << std::endl;
  o << s << " Maximum time of acquisition     = " << std::setw(11)
    //<< (unsigned)(_maximumTimeOfAcquisition.deltaTime()) << " secs" << std::endl;
    << _maximumTimeOfAcquisition << " secs" << std::endl;
  o << s << " Maximum time of spill           = " << std::setw(11)
    //<< (unsigned)(_maximumTimeOfSpill.deltaTime()) << " secs" << std::endl;
    << _maximumTimeOfSpill << " secs" << std::endl;
  o << s << " Maximum time of event           = " << std::setw(11)
    //<< (unsigned)(_maximumTimeOfEvent.deltaTime()) << " secs" << std::endl;
    << _maximumTimeOfEvent << " secs" << std::endl;
  o << s << " Minimum time of slow readout    = " << std::setw(11)
    //<< (unsigned)(_minimumTimeBeforeSlowReadout.deltaTime()) << " secs" << std::endl;
    << _minimumTimeBeforeSlowReadout << " secs" << std::endl;
  return o;
}

#endif
#endif
