#ifndef MpsLocation_HH
#define MpsLocation_HH

#include <string>
#include <iostream>

#include "UtlPack.hh"


class MpsLocation {

public:
  enum Site {
    test,
    birmingham,
    imperial,
    ralmeg,
    ralppd,
    desy
  };


  MpsLocation();  
  MpsLocation(unsigned char c, unsigned char s, unsigned char f);  
  MpsLocation(unsigned char c, unsigned char s, unsigned char f, unsigned char l);
  
  unsigned char siteNumber() const;  
  void          siteNumber(unsigned char n);
  
  unsigned char usbDaqNumber() const;
  void          usbDaqNumber(unsigned char n);
  bool          usbDaqBroadcast() const;  
  void          usbDaqBroadcast(bool e);
  
  unsigned char componentNumber() const;  
  void          componentNumber(unsigned char n);
  
  unsigned char label() const;
  void          label(unsigned char n);

  bool          write() const;
  void          write(bool w);

  bool          ignore() const;

  bool operator==(const MpsLocation &d) const;
  bool operator!=(const MpsLocation &d) const;
  
  std::ostream& print(std::ostream &o=std::cout, std::string s="") const;


private:
  UtlPack _location;
};


#ifdef CALICE_DAQ_ICC

MpsLocation::MpsLocation() : _location(0) {
}

MpsLocation::MpsLocation(unsigned char c, unsigned char s, unsigned char f) : _location(0) {
  siteNumber(c);
  usbDaqNumber(s);
  componentNumber(f);
}
  
MpsLocation::MpsLocation(unsigned char c, unsigned char s, unsigned char f, unsigned char l) {
  siteNumber(c);
  usbDaqNumber(s);
  componentNumber(f);
  label(l);
}
  
unsigned char MpsLocation::siteNumber() const {
  return _location.byte(3);
}

void MpsLocation::siteNumber(unsigned char n) {
  _location.byte(3,n);
}

unsigned char MpsLocation::usbDaqNumber() const {
  return _location.byte(2);
}

void MpsLocation::usbDaqNumber(unsigned char n) {
  _location.byte(2,n);
}

bool MpsLocation::usbDaqBroadcast() const {
  return _location.byte(2)==0xff;
}

void MpsLocation::usbDaqBroadcast(bool e) {
  if(e) _location.byte(2,0xff);
  else  _location.byte(2,0x00);
}

unsigned char MpsLocation::componentNumber() const {
  return _location.byte(1);
}

void MpsLocation::componentNumber(unsigned char n) {
  _location.byte(1,n);
}

unsigned char MpsLocation::label() const {
  return _location.byte(0);
}

void MpsLocation::label(unsigned char n) {
  _location.byte(0,n);
}

bool MpsLocation::write() const {
  return _location.bit(0);
}

void MpsLocation::write(bool w) {
  _location.bit(0,w);
}

bool MpsLocation::ignore() const {
  return _location.bit(2);
}

bool MpsLocation::operator==(const MpsLocation &d) const {
  return _location==d._location;
}

bool MpsLocation::operator!=(const MpsLocation &d) const {
  return _location!=d._location;
}

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

  o << s << " Site number      = "
    << printHex(siteNumber(),false) << std::endl;

  o << s << " UsbDaq number    = " << std::setw(4)
    << (unsigned)usbDaqNumber();
  if(usbDaqBroadcast()) o << " = USB_DAQ broadcast";
  o << std::endl;

  o << s << " Component number = " << std::setw(4)
    << (unsigned)componentNumber() << std::endl;

  o << s << " Label            = " << printHex(label());
  if(write()) o << " = write";
  else        o << " = read";
  if(ignore()) o << ", ignore";
  o << std::endl;

  return o;
}

#endif

#endif
