#ifndef UtlPrintHex_HH
#define UtlPrintHex_HH

#include <string>

std::string printHex(unsigned n, bool b=true);
std::string printHex(int n, bool b=true);
std::string printHex(unsigned short n, bool b=true);
std::string printHex(short n, bool b=true);
std::string printHex(unsigned char n, bool b=true);
std::string printHex(char n, bool b=true);


#ifdef CALICE_DAQ_ICC

#include <sstream>
#include <iomanip>


std::string printHex(unsigned n, bool b) {
  std::ostringstream o;

  o << std::setw(11) << n << " = 0x" 
    << std::setfill('0') << std::setw(8) << std::hex << n << std::dec;

  if(b) {
    o << " = 0b";
    for(unsigned i(0);i<32;i++) {
      if(i>0 && (i%8)==0) o << " ";
      if((n&(1<<(31-i)))==0) o << "0";
      else                   o << "1";
    }
  }

  return o.str();
}

std::string printHex(int n, bool b) {
  std::ostringstream o;

  o << std::setw(11) << n << " = 0x" 
    << std::setfill('0') << std::setw(8) << std::hex << n << std::dec;

  if(b) {
    o << " = 0b";
    for(unsigned i(0);i<32;i++) {
      if(i>0 && (i%8)==0) o << " ";
      if((n&(1<<(31-i)))==0) o << "0";
      else                   o << "1";
    }
  }

  return o.str();
}

std::string printHex(unsigned short n, bool b) {
  std::ostringstream o;

  o << std::setw(6) << n << " = 0x" 
    << std::setfill('0') << std::setw(4) << std::hex << n << std::dec;

  if(b) {
    o << " = 0b";
    for(unsigned i(0);i<16;i++) {
      if(i>0 && (i%8)==0) o << " ";
      if((n&(1<<(15-i)))==0) o << "0";
      else                   o << "1";
    }
  }

  return o.str();
}

std::string printHex(short n, bool b) {
  std::ostringstream o;

  o << std::setw(6) << n << " = 0x" 
    << std::setfill('0') << std::setw(4) << std::hex << n << std::dec;

  if(b) {
    o << " = 0b";
    for(unsigned i(0);i<16;i++) {
      if(i>0 && (i%8)==0) o << " ";
      if((n&(1<<(15-i)))==0) o << "0";
      else                   o << "1";
    }
  }

  return o.str();
}

std::string printHex(unsigned char n, bool b) {
  std::ostringstream o;

  o << std::setw(4) << (unsigned)n << " = 0x" 
    << std::setfill('0') << std::setw(2) << std::hex << (unsigned)n << std::dec;

  if(b) {
    o << " = 0b";
    for(unsigned i(0);i<8;i++) {
      if((n&(1<<(7-i)))==0) o << "0";
      else                  o << "1";
    }
  }

  return o.str();
}

std::string printHex(char n, bool b) {
  std::ostringstream o;

  o << std::setw(4) << (int)n << " = 0x" 
    << std::setfill('0') << std::setw(2) << std::hex << (int)n << std::dec;

  if(b) {
    o << " = 0b";
    for(unsigned i(0);i<8;i++) {
      if((n&(1<<(7-i)))==0) o << "0";
      else                  o << "1";
    }
  }

  return o.str();
}

#endif
#endif
