#ifndef BmlFnalSlowRunData_HH
#define BmlFnalSlowRunData_HH

#include <vector>
#include <string>
#include <iostream>


class BmlFnalSlowRunData {

public:
  enum {
    versionNumber=0
  };

  BmlFnalSlowRunData();

  bool parse(std::string r);
  
  time_t slowTimeStamp() const;
  void   slowTimeStamp(time_t t);

  time_t fnalTimeStamp() const;
  void   fnalTimeStamp(time_t t);

  std::vector<double> beamFluxes() const;
  std::vector<double> magnetCurrents() const;
  std::vector<double> targetAndCollimators() const;
  std::vector<double> pinholeCollimators() const;
  std::vector<unsigned> scalers() const;

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


private:
  time_t _timeStamp[2];

  double _beamFlux[4];
  double _magnetCurrent[12];
  double _targetAndCollimator[9];
  double _pinholeCollimator[4];
  unsigned _scaler[11];
};


#ifdef CALICE_DAQ_ICC

#include <time.h>
#include <cstring>


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

bool BmlFnalSlowRunData::parse(std::string r) {
  std::istringstream sin(r);

  // Store timestamps
  sin >> _timeStamp[0] >> _timeStamp[1];
  if(!sin) return false;
  
  // Store data; first the doubles
  for(unsigned i(0);i<(4+12+9+4) && sin;i++) {
    sin >> _beamFlux[i];
    if(!sin) return false;
  }

  // Store data; now the scalers
  double n;
  for(unsigned i(0);i<11 && sin;i++) {
    sin >> n;
    if(n<0.0) _scaler[i]=(unsigned)(n-0.5);
    else      _scaler[i]=(unsigned)(n+0.5);
    if(!sin) return false;
  }

  return sin;
}

time_t BmlFnalSlowRunData::slowTimeStamp() const {
  return _timeStamp[0];
}

void BmlFnalSlowRunData::slowTimeStamp(time_t t) {
  _timeStamp[0]=t;
}

time_t BmlFnalSlowRunData::fnalTimeStamp() const {
  return _timeStamp[1];
}

void BmlFnalSlowRunData::fnalTimeStamp(time_t t) {
  _timeStamp[1]=t;
}

std::vector<double> BmlFnalSlowRunData::beamFluxes() const {
  std::vector<double> v(4);
  for(unsigned i(0);i<4;i++) v[i]=_beamFlux[i];
  return v;
}

std::vector<double> BmlFnalSlowRunData::magnetCurrents() const {
  std::vector<double> v(12);
  for(unsigned i(0);i<12;i++) v[i]=_magnetCurrent[i];
  return v;
}

std::vector<double> BmlFnalSlowRunData::targetAndCollimators() const {
  std::vector<double> v(9);
  for(unsigned i(0);i<9;i++) v[i]=_targetAndCollimator[i];
  return v;
}

std::vector<double> BmlFnalSlowRunData::pinholeCollimators() const {
  std::vector<double> v(4);
  for(unsigned i(0);i<4;i++) v[i]=_pinholeCollimator[i];
  return v;
}

std::vector<unsigned> BmlFnalSlowRunData::scalers() const {
  std::vector<unsigned> v(11);
  for(unsigned i(0);i<11;i++) v[i]=_scaler[i];
  return v;
}

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

  o << s << " Slow controls timestamp = " << _timeStamp[0] << " = " << ctime(_timeStamp  );
  o << s << " FNAL database timestamp = " << _timeStamp[1] << " = " << ctime(_timeStamp+1);

  o << s << " Main injector beam flux     = " << _beamFlux[0] << " p" << std::endl;
  o << s << " Switchyard beam flux        = " << _beamFlux[1] << " p" << std::endl;
  o << s << " West split beam flux        = " << _beamFlux[2] << " p" << std::endl;
  o << s << " Downstream target beam flux = " << _beamFlux[3] << " p" << std::endl;

  o << s << " Magnet main west bend         = " << _magnetCurrent[ 0] << " A" << std::endl;
  o << s << " Magnet target bend            = " << _magnetCurrent[ 1] << " A" << std::endl;
  o << s << " Magnet target low limit       = " << _magnetCurrent[ 2] << " A" << std::endl;
  o << s << " Magnet last east bend         = " << _magnetCurrent[ 3] << " A" << std::endl;
  o << s << " Magnet last east low limit    = " << _magnetCurrent[ 4] << " A" << std::endl;
  o << s << " Magnet quadrupole 1           = " << _magnetCurrent[ 5] << " A" << std::endl;
  o << s << " Magnet quadrupole 1 low limit = " << _magnetCurrent[ 6] << " A" << std::endl;
  o << s << " Magnet quadrupole 2           = " << _magnetCurrent[ 7] << " A" << std::endl;
  o << s << " Magnet quadrupole 2 low limit = " << _magnetCurrent[ 8] << " A" << std::endl;
  o << s << " Magnet vertical trim 1        = " << _magnetCurrent[ 9] << " A" << std::endl;
  o << s << " Magnet vertical trim 2        = " << _magnetCurrent[10] << " A" << std::endl;
  o << s << " Magnet horizontal trim        = " << _magnetCurrent[11] << " A" << std::endl;

  o << s << " Target upstream              = " << _targetAndCollimator[0] << " mm" << std::endl;
  o << s << " Target downstream            = " << _targetAndCollimator[1] << " mm" << std::endl;
  o << s << " Collimator first vertical    = " << _targetAndCollimator[2] << " mm" << std::endl;
  o << s << " Collimator first horizontal  = " << _targetAndCollimator[3] << " mm" << std::endl;
  o << s << " Lead sheet                   = " << _targetAndCollimator[4] << " mm" << std::endl;
  o << s << " Collimator second horizontal = " << _targetAndCollimator[5] << " mm" << std::endl;
  o << s << " Collimator second vertical   = " << _targetAndCollimator[6] << " mm" << std::endl;
  o << s << " Muon absorber half 1         = " << _targetAndCollimator[7] << " mm" << std::endl;
  o << s << " Muon absorber half 2         = " << _targetAndCollimator[8] << " mm" << std::endl;

  o << s << " Pinhole collimator upstream horizontal   = " << _pinholeCollimator[0] << " mm" << std::endl;
  o << s << " Pinhole collimator downstream horizontal = " << _pinholeCollimator[1] << " mm" << std::endl;
  o << s << " Pinhole collimator upstream vertical     = " << _pinholeCollimator[2] << " mm" << std::endl;
  o << s << " Pinhole collimator downstream vertical   = " << _pinholeCollimator[3] << " mm" << std::endl;

  o << s << " First TOF scaler  = " << _scaler[0] << std::endl;
  o << s << " Second TOF scaler = " << _scaler[1] << std::endl;
  for(unsigned i(0);i<8;i++) {
    o << s << " User scaler " << i << "     = " << _scaler[2+i] << std::endl;
  }
  o << s << " Cherenkov scaler  = " << _scaler[10] << std::endl;

  return o;
}

#endif
#endif
