/// ValueRepresentations.cpp
/**
*/

#include "ValueRepresentations.h"

using namespace jcs;

///
/** Depends upon input stream providing a string. Perhaps
    this should be explicitly defined.
    DICOM delimits sub-strings with a backslash.
    \param in An input stream, should be a stringstream.
*/
void
DicomValue::GetStrings(std::istream &in)
{
//  char in_buff[100];
  std::string tmp;
  while (!std::getline(in, tmp, '\\').fail()) {
     //(char)0x5C);
    values.push_back(wxString(tmp.c_str(), wxConvUTF8));
  }
}


wxString
DicomValue::first()
{
  return values.front();
}


wxInt16
DicomValue::EndianSwapInt16(wxInt16 value)
{
  if (transferSyntaxCode == BEE_CODE) {
    wxINT16_SWAP_ON_LE(value);
  }
  else {
    wxINT16_SWAP_ON_BE(value);
  }
  return value;
}


wxInt32
DicomValue::EndianSwapInt32(wxInt32 value)
{
  if (transferSyntaxCode == BEE_CODE) {
    wxINT32_SWAP_ON_LE(value);
  }
  else {
    wxINT32_SWAP_ON_BE(value);
  }
  return value;
}


wxUint16
DicomValue::EndianSwapUint16(wxUint16 value)
{
  if (transferSyntaxCode == BEE_CODE) {
    wxUINT16_SWAP_ON_LE(value);
  }
  else {
    wxUINT16_SWAP_ON_BE(value);
  }
  return value;
}


wxUint32
DicomValue::EndianSwapUint32(wxUint32 value)
{
  if (transferSyntaxCode == BEE_CODE) {
    wxUINT32_SWAP_ON_LE(value);
  }
  else {
    wxUINT32_SWAP_ON_BE(value);
  }
  return value;
}


wxUint64
DicomValue::EndianSwapUint64(wxUint64 value)
{
  if (transferSyntaxCode == BEE_CODE) {
    wxUINT64_SWAP_ON_LE(value);
  }
  else {
    wxUINT64_SWAP_ON_BE(value);
  }
  return value;
}


///
/**
    \return True if all values in rhs are the same as all values
            in this. False otherwise.
*/
bool
DicomValue::operator== (DicomValue &rhs)
{
  bool retval = false;
  if (values.size() == rhs.values.size()) {
    std::vector<wxString>::iterator it = values.begin();
    std::vector<wxString>::iterator it_end = values.end();
    std::vector<wxString>::iterator it_rhs = rhs.values.begin();
    std::vector<wxString>::iterator it_rhs_end = rhs.values.end();
    for (; it < it_end; ++it, ++it_rhs) {
      if (it->Cmp(*it_rhs) == 0) {
        retval = true;
      }
      else {
        retval = false;
        break;
      }
    }
  }
  return retval;
}


std::ostream &
jcs::operator<<(std::ostream &out, DicomValue &ve)
{
  std::vector<wxString>::iterator it = ve.values.begin();
  std::vector<wxString>::iterator it_end = ve.values.end();
  for (; it < it_end; ++it) {
    out << static_cast<const char*>(it->mb_str()) << " / ";
  }
  return out;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_AE &ae)
{
  ae.GetStrings(in);
  return in;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_AS &as)
{
  as.GetStrings(in);
  return in;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_AT &at)
{
  wxUint32 n_read = 0;
  while (n_read < at.value_length) {
    at.val.transferSyntaxCode = at.transferSyntaxCode;
    in >> at.val;
    at.values.push_back(at.val);
    n_read += in.gcount();
  }
  return in;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_CS &cs)
{
  cs.GetStrings(in);
  return in;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_DA &da)
{
  da.GetStrings(in);
  return in;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_DS &ds)
{
  ds.GetStrings(in);
  return in;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_DT &dt)
{
  dt.GetStrings(in);
  return in;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_FL &fl)
{
  wxUint32 tmp;
  wxUint32 n_read = 0;
  while (n_read < fl.value_length) {
    in.read((char *)&(tmp), sizeof(tmp));
    tmp = fl.EndianSwapUint32(tmp);
    fl.values.push_back((float)tmp);
    n_read += in.gcount();
  }
  return in;
}


///
/**
*/
std::ostream &
jcs::operator<< (std::ostream &out, VR_FL &fl)
{
  std::vector<float>::iterator it = fl.values.begin();
  std::vector<float>::iterator it_end = fl.values.end();
  for (; it < it_end; ++it) {
    out << *it << " / ";
  }
  return out;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_FD &fd)
{
  wxUint64 tmp;
  wxUint32 n_read = 0;
  while (n_read < fd.value_length) {
    in.read((char *)&(tmp), sizeof(tmp));
    tmp = fd.EndianSwapUint64(tmp);
    fd.values.push_back((double)tmp);
    n_read += in.gcount();
  }
  return in;
}


///
/**
*/
std::ostream &
jcs::operator<< (std::ostream &out, VR_FD &fd)
{
  std::vector<double>::iterator it = fd.values.begin();
  std::vector<double>::iterator it_end = fd.values.end();
  for (; it < it_end; ++it) {
    out << *it << " / ";
  }
  return out;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_IS &is)
{
  is.GetStrings(in);
  return in;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_LO &lo)
{
  lo.GetStrings(in);
  return in;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_LT &lt)
{
  lt.GetStrings(in);
  return in;
}


///
/**
    Value multiplicity is always 1.
*/
std::istream &
jcs::operator>> (std::istream &in, VR_OB &ob)
{
  ob.GetStrings(in);
  return in;
}


///
/**
    Value multiplicity is always 1.
*/
std::istream &
jcs::operator>> (std::istream &in, VR_OF &of)
{
  wxUint32 tmp;
  wxUint32 n_read = 0;
  while (n_read < of.value_length) {
    in.read((char *)&(tmp), sizeof(tmp));
    tmp = of.EndianSwapUint32(tmp);
    of.values.push_back((float)tmp);
    n_read += in.gcount();
  }
  return in;
}


///
/**
*/
std::ostream &
jcs::operator<< (std::ostream &out, VR_OF &of)
{
  std::vector<float>::iterator it = of.values.begin();
  std::vector<float>::iterator it_end = of.values.end();
  for (; it < it_end; ++it) {
    out << *it << " / ";
  }
  return out;
}


///
/**
    Value multiplicity is always 1.
*/
std::istream &
jcs::operator>> (std::istream &in, VR_OW &ow)
{
  wxUint16 tmp;
  wxUint32 n_read = 0;
  while (n_read < ow.value_length) {
    in.read((char *)&(tmp), sizeof(tmp));
    tmp = ow.EndianSwapUint16(tmp);
    ow.values.push_back((wxUint16)tmp);
    n_read += in.gcount();
  }
  return in;
}


///
/**
*/
std::ostream &
jcs::operator<< (std::ostream &out, VR_OW &ow)
{
  std::vector<wxUint16>::iterator it = ow.values.begin();
  std::vector<wxUint16>::iterator it_end = ow.values.end();
  for (; it < it_end; ++it) {
    out << *it << " / ";
  }
  return out;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_PN &pn)
{
  pn.GetStrings(in);
  return in;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_SH &sh)
{
  sh.GetStrings(in);
  return in;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_SL &sl)
{
  wxInt32 tmp;
  wxUint32 n_read = 0;
  while (n_read < sl.value_length) {
    in.read((char *)&(tmp), sizeof(tmp));
    tmp = sl.EndianSwapInt32(tmp);
    sl.values.push_back(tmp);
    n_read += in.gcount();
  }
  return in;
}


///
/**
*/
std::ostream &
jcs::operator<< (std::ostream &out, VR_SL &sl)
{
  std::vector<wxInt32>::iterator it = sl.values.begin();
  std::vector<wxInt32>::iterator it_end = sl.values.end();
  for (; it < it_end; ++it) {
    out << *it << " / ";
  }
  return out;
}


///
/**
    Value multiplicity is always 1.
*/
std::istream &
jcs::operator>> (std::istream &in, VR_SQ &sq)
{
  return in;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_SS &ss)
{
  wxInt16 tmp;
  wxUint32 n_read = 0;
  while (n_read < ss.value_length) {
    in.read((char *)&(tmp), sizeof(tmp));
    tmp = ss.EndianSwapInt16(tmp);
    ss.values.push_back(tmp);
    n_read += in.gcount();
  }
  return in;
}


///
/**
*/
std::ostream &
jcs::operator<< (std::ostream &out, VR_SS &ss)
{
  std::vector<wxInt16>::iterator it = ss.values.begin();
  std::vector<wxInt16>::iterator it_end = ss.values.end();
  for (; it < it_end; ++it) {
    out << *it << " / ";
  }
  return out;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_ST &st)
{
  st.GetStrings(in);
  return in;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_TM &tm)
{
  tm.GetStrings(in);
  return in;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_UI &ui)
{
  ui.GetStrings(in);
  return in;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_UL &ul)
{
  wxUint32 tmp;
  wxUint32 n_read = 0;
  while (n_read < ul.value_length) {
    in.read((char *)&(tmp), sizeof(tmp));
    tmp = ul.EndianSwapUint32(tmp);
    ul.values.push_back(tmp);
    n_read += in.gcount();
  }
  return in;
}


///
/**
*/
std::ostream &
jcs::operator<< (std::ostream &out, VR_UL &ul)
{
  std::vector<wxUint32>::iterator it = ul.values.begin();
  std::vector<wxUint32>::iterator it_end = ul.values.end();
  for (; it < it_end; ++it) {
    out << *it << " / ";
  }
  return out;
}


///
/**
    Value multiplicity is always 1.
*/
std::istream &
jcs::operator>> (std::istream &in, VR_UN &un)
{
  un.GetStrings(in);
  return in;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_US &us)
{
  wxUint16 tmp;
  wxUint32 n_read = 0;
  while (n_read < us.value_length) {
    in.read((char *)&(tmp), sizeof(tmp));
    tmp = us.EndianSwapUint16(tmp);
    us.values.push_back(tmp);
    n_read += in.gcount();
  }
  return in;
}


///
/**

*/
std::ostream &
jcs::operator<< (std::ostream &out, VR_US &us)
{
  std::vector<wxUint16>::iterator it = us.values.begin();
  std::vector<wxUint16>::iterator it_end = us.values.end();
  for (; it < it_end; ++it) {
    out << *it << " / ";
  }
  return out;
}


///
/**
*/
std::istream &
jcs::operator>> (std::istream &in, VR_UT &ut)
{
  ut.GetStrings(in);
  return in;
}
