/// BvFiles.cpp
/**
 */

#include <wx/log.h>

#include <iostream>
#include <string>

#include "BvFiles.h"
#include "StringConvert.h"

using namespace jcs;

BvStc::~BvStc()
{
  if (mFile.is_open()) {
    mCloseFile();
  }
}


///
/**
 */
int
BvStc::WriteStc(wxUint16 rows, wxUint16 cols,
                std::vector <unsigned short>& v)
{
  if (!mOpenFile(std::ios::out|std::ios::binary)) {
    return 0;
  }
  mFile.write(reinterpret_cast<char*> (&rows), sizeof(rows));
  mFile.write(reinterpret_cast<char*> (&cols), sizeof(cols));
  mFile.write(reinterpret_cast<char*> (&v.front()), 2 * v.size());
  mCloseFile();
  if (verbose && !quiet) {
    std::cout << "Wrote " << mFileName << std::endl;
  }
  return 1;
}


///
/**
 */
int
BvStc::mOpenFile(std::ios::openmode mode)
{
  if (mFileName.empty()) {
    return 0;
  }
  if (mFile.is_open()) {
    mFile.close();
  }
  mFile.clear();
  std::string filename = mFileName;
  filename.append(".stc");
  mFile.open(filename.c_str(), mode);
  return mFile.good();
}


///
/**
 */
BvVmr::~BvVmr()
{
  if (mFile.is_open()) {
    mCloseFile();
  }
}


///
/**
    \param dim A vector of wxUint16
    \param data A vector of wxUint8
    \return 1
 */
int
BvVmr::WriteVmr(std::vector <wxUint16>& dim, std::vector <wxUint8>& data)
{
  if (!mOpenFile(std::ios::out|std::ios::binary, ".vmr")) {
    return 0;
  }
  mFile.write(reinterpret_cast<char*> (&dim.front()), 2 * dim.size());
  mFile.write(reinterpret_cast<char*> (&data.front()), data.size());

  mCloseFile();

  if (verbose && !quiet) {
    std::cout << "Wrote " << mFileName << std::endl;
  }

  return 1;
}


///
/**
    \param dim A vector of wxUint16
    \param data A vector of wxUint16
    \return 0 or 1
 */
int
BvVmr::WriteV16(std::vector <wxUint16>& dim, std::vector <wxInt16>& data)
{
  if (!mOpenFile(std::ios::out | std::ios::binary, ".v16")) {
    return 0;
  }
  mFile.write(reinterpret_cast<char*> (&dim.front()), 2 * dim.size());
  mFile.write(reinterpret_cast<char*> (&data.front()), 2 * data.size());

  mCloseFile();

  if (verbose && !quiet) {
    std::cout << "Wrote " << mFileName << std::endl;
  }
  return 1;
}


///
/**
 */
// Suffix = ".vmr" or ".v16"
int
BvVmr::mOpenFile(std::ios::openmode mode, const char* suffix)
{
  if (mFileName.empty()) {
    return 0;
  }
  if (mFile.is_open()) {
    mFile.close();
  }
  mFile.clear();
  std::string filename = mFileName;
  filename.append(suffix);
  mFile.open(filename.c_str(), mode);
  return mFile.good();
}


///
/**
 */
BvFmr::~BvFmr()
{
  if (mFile.is_open()) {
    mCloseFile();
  }
}


///
/**
 */
int
BvFmr::mOpenFile(std::ios::openmode mode)
{
  if (mFileName.empty()) {
    return 0;
  }
  if (mFile.is_open()) {
    mFile.close();
  }
  mFile.clear();
  std::string filename = mFileName;
  filename.append(".fmr");
  mFile.open(filename.c_str(), mode);

  return mFile.good();
}


///
/**
 */
void
BvFmr::WriteFmr(const FmrHeader& header)
{
  if (!mOpenFile(std::ios::out)) {
    wxLogError(_T("Cannot create file %s.fmr"),
               mFileName.c_str());
    return;
  }

  mFile << "FileVersion:              2\n";
  mFile << "NrOfVolumes:              " << header.volumes << "\n";
  mFile << "NrOfSlices:               " << header.slices << "\n";
  mFile << "NrOfSkippedVolumes:       " << header.skipVolumes << "\n";
  mFile << "Prefix:                   " << header.prefix << "\n";
  mFile << "TR:                       " << header.tr << "\n";
  mFile << "InterSliceTime:           " << header.interSliceT << "\n";
  mFile << "TimeResolutionVerified:   1\n";
  mFile << "ResolutionX:              " << header.columns << "\n";
  mFile << "ResolutionY:              " << header.rows << "\n";
  mFile << "LoadAMRFile:              <none>\n";
  mFile << "ShowAMRFile:              1\n";
  mFile << "ImageIndex:               0\n";
  mFile << "LayoutNColumns:           " << header.layoutColumns << "\n";
  mFile << "LayoutNRows:              " << header.layoutRows << "\n";
  mFile << "LayoutZoomLevel:          1\n";
  mFile << "SegmentSize:              10\n";
  mFile << "SegmentOffset:            0\n";
  mFile << "ProtocolVersion:          2\n";
  mFile << "ProtocolFile:             <none>\n";

  mFile.setf(std::ios_base::fixed);
  mFile.precision(6);
  mFile << "InplaneResolutionX:       " << header.IpResX << "\n";
  mFile << "InplaneResolutionY:       " << header.IpResY << "\n";
  mFile << "SliceThickness:           " << header.sliceThickness << "\n";
  mFile << "SliceGap:                 " << header.sliceGap << "\n";
  mFile << "VoxelResolutionVerified:  1\n";

  mCloseFile();

  if (verbose && !quiet) {
    std::cout << "Wrote " << mFileName << std::endl;
  }
}
