
/* -------------------------------------------------------------------------
 * BKG NTRIP Server
 * -------------------------------------------------------------------------
 *
 * Class:      bncoutf
 *
 * Purpose:    Basis Class for File-Writers
 *
 * Author:     L. Mervart
 *
 * Created:    25-Apr-2008
 *
 * Changes:    
 *
 * -----------------------------------------------------------------------*/

#include <math.h>
#include <iomanip>

#include "bncoutf.h"
#include "bncsettings.h"

using namespace std;

// Constructor
////////////////////////////////////////////////////////////////////////////
bncoutf::bncoutf(const QString& sklFileName, const QString& intr, int sampl) {

  bncSettings settings;

  _headerWritten = false;
  _sampl         = sampl;
  _intr          = intr;

  QFileInfo fileInfo(sklFileName);
  _path        = fileInfo.absolutePath() + QDir::separator();
  _sklBaseName = fileInfo.baseName();
  _extension   = fileInfo.completeSuffix(); 

  expandEnvVar(_path);
  if (!_extension.isEmpty()) {
    _extension = "." + _extension;
  }

  _append = Qt::CheckState(settings.value("rnxAppend").toInt()) == Qt::Checked;
}

// Destructor
////////////////////////////////////////////////////////////////////////////
bncoutf::~bncoutf() {
  closeFile();
}

// Close the Old RINEX File
////////////////////////////////////////////////////////////////////////////
void bncoutf::closeFile() {
  _out.close();
}

// Epoch String
////////////////////////////////////////////////////////////////////////////
QString bncoutf::epochStr(const QDateTime& datTim, const QString& intStr) {

  QString epoStr;

  int indHlp = intStr.indexOf("min");

  if ( indHlp != -1) {
    int step = intStr.left(indHlp-1).toInt();
    char ch = 'A' + datTim.time().hour();
    epoStr = QString("_") + ch;
    if (datTim.time().minute() >= 60-step) {
      epoStr += QString("%1").arg(60-step, 2, 10, QChar('0'));
    }
    else {
      for (int limit = step; limit <= 60-step; limit += step) {
        if (datTim.time().minute() < limit) {
          epoStr += QString("%1").arg(limit-step, 2, 10, QChar('0'));
          break;
        }
      }
    }
  }
  else if (intStr == "1 hour") {
    char ch = 'A' + datTim.time().hour();
    epoStr = QString("_") + ch;
  }
  else {
    epoStr = "";
  }

  return epoStr;
}

// File Name according to RINEX Standards
////////////////////////////////////////////////////////////////////////////
QString bncoutf::resolveFileName(int GPSweek, const QDateTime& datTim) {

  int dayOfWeek = datTim.date().dayOfWeek();
  if (dayOfWeek == 7) {
    dayOfWeek = 0;
  }
  QString gpswd    = QString("%1%2").arg(GPSweek).arg(dayOfWeek);
  QString baseName = _sklBaseName; baseName.replace("${GPSWD}", gpswd);
  QString epoStr   = epochStr(datTim, _intr);

  return _path + baseName + epoStr + _extension;
}

// Re-Open Output File
////////////////////////////////////////////////////////////////////////////
t_irc bncoutf::reopen(int GPSweek, double GPSweeks) {

  if (_sampl != 0 && fmod(GPSweeks, _sampl) != 0.0) {
    return failure;
  }

  QDateTime datTim = dateAndTimeFromGPSweek(GPSweek, GPSweeks);

  QString newFileName = resolveFileName(GPSweek, datTim);

  // Close the file
  // --------------
  if (newFileName != _fName) {
    closeFile();
    _headerWritten = false;
    _fName = newFileName;
  }

  // Re-Open File, Write Header
  // --------------------------
  if (!_headerWritten) {
    _out.setf(ios::showpoint | ios::fixed);
    if (_append && QFile::exists(_fName)) {
      _out.open(_fName.toAscii().data(), ios::out | ios::app);
    }
    else {
      _out.open(_fName.toAscii().data());
      writeHeader(datTim);
    }
    _headerWritten = true;
  }

  return success;
}

// Write String
////////////////////////////////////////////////////////////////////////////
t_irc bncoutf::write(int GPSweek, double GPSweeks, const QString& str) {
  reopen(GPSweek, GPSweeks);
  _out << str.toAscii().data();
  _out.flush();
  return success;
}
