// Part of BNC, a utility for retrieving decoding and
// converting GNSS data streams from NTRIP broadcasters.
//
// Copyright (C) 2007
// German Federal Agency for Cartography and Geodesy (BKG)
// http://www.bkg.bund.de
// Czech Technical University Prague, Department of Geodesy
// http://www.fsv.cvut.cz
//
// Email: euref-ip@bkg.bund.de
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation, version 2.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

/* -------------------------------------------------------------------------
 * BKG NTRIP Client
 * -------------------------------------------------------------------------
 *
 * Class:      t_pppWidgets
 *
 * Purpose:    This class stores widgets for PPP options
 *
 * Author:     L. Mervart
 *
 * Created:    29-Jul-2014
 *
 * Changes:    
 *
 * -----------------------------------------------------------------------*/

#include <iostream>

#include "PPP/pppwidgets.h"
#include "qtfilechooser.h"
#include "bncsettings.h"

using namespace std;

// Constructor
////////////////////////////////////////////////////////////////////////////
t_pppWidgets::t_pppWidgets() {

  _dataSource   = new QComboBox();     _dataSource  ->setObjectName("PPP/dataSource");   _widgets << _dataSource;  
  _rinexObs     = new qtFileChooser(); _rinexObs    ->setObjectName("PPP/rinexObs");     _widgets << _rinexObs;    
  _rinexNav     = new qtFileChooser(); _rinexNav    ->setObjectName("PPP/rinexNav");     _widgets << _rinexNav;    
  _corrMount    = new QLineEdit();     _corrMount   ->setObjectName("PPP/corrMount");    _widgets << _corrMount;
  _corrFile     = new qtFileChooser(); _corrFile    ->setObjectName("PPP/corrFile");     _widgets << _corrFile;    
  _crdFile      = new qtFileChooser(); _crdFile     ->setObjectName("PPP/crdFile");      _widgets << _crdFile;     
  _antexFile    = new qtFileChooser(); _antexFile   ->setObjectName("PPP/antexFile");    _widgets << _antexFile;   
  _logFile      = new QLineEdit();     _logFile     ->setObjectName("PPP/logFile");      _widgets << _logFile;     
  _nmeaFile     = new QLineEdit();     _nmeaFile    ->setObjectName("PPP/nmeaFile");     _widgets << _nmeaFile;    
  _nmeaPort     = new QLineEdit();     _nmeaPort    ->setObjectName("PPP/nmeaPort");     _widgets << _nmeaPort;    
  _staTable     = new QTableWidget();  _staTable    ->setObjectName("PPP/staTable");     _widgets << _staTable;    
  _lcGPS        = new QComboBox();     _lcGPS       ->setObjectName("PPP/lcGPS");        _widgets << _lcGPS;       
  _lcGLONASS    = new QComboBox();     _lcGLONASS   ->setObjectName("PPP/lcGLONASS");    _widgets << _lcGLONASS;   
  _lcGalileo    = new QComboBox();     _lcGalileo   ->setObjectName("PPP/lcGalileo");    _widgets << _lcGalileo;   
  _sigmaC1      = new QLineEdit();     _sigmaC1     ->setObjectName("PPP/sigmaC1");      _widgets << _sigmaC1;     
  _sigmaL1      = new QLineEdit();     _sigmaL1     ->setObjectName("PPP/sigmaL1");      _widgets << _sigmaL1;     
  _corrWaitTime = new QSpinBox();      _corrWaitTime->setObjectName("PPP/corrWaitTime"); _widgets << _corrWaitTime;
  _addStaButton = new QPushButton("Add Station");                                        _widgets << _addStaButton;
  _delStaButton = new QPushButton("Delete Station");                                     _widgets << _delStaButton;
  
  _dataSource->setEditable(false);
  _dataSource->addItems(QString("no,Real-Time Streams,RINEX Files").split(","));
  connect(_dataSource, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(slotEnableWidgets()));

  _lcGPS->setEditable(false);
  _lcGPS->addItems(QString("no,P3,L3,P3&L3").split(","));

  _lcGLONASS->setEditable(false);
  _lcGLONASS->addItems(QString("no,P3,L3,P3&L3").split(","));

  _lcGalileo->setEditable(false);
  _lcGalileo->addItems(QString("no,P3,L3,P3&L3").split(","));

  _corrWaitTime->setMinimum(0);
  _corrWaitTime->setMaximum(20);
  _corrWaitTime->setSingleStep(1);
  _corrWaitTime->setSuffix(" sec");
  _corrWaitTime->setSpecialValueText("no");

  _staTable->setColumnCount(9);
  _staTable->setRowCount(0);
  _staTable->setHorizontalHeaderLabels(
     QString("Station,Sigma N,Sigma E,Sigma H,Noise N,Noise E,Noise H,Tropo Sigma,Tropo Noise").split(","));
  _staTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
  _staTable->setSelectionBehavior(QAbstractItemView::SelectRows);
  _staTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
  /// _staTable->horizontalHeader()->setStretchLastSection(true);
  _staTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
  
  connect(_addStaButton, SIGNAL(clicked()), this, SLOT(slotAddStation()));
  connect(_delStaButton, SIGNAL(clicked()), this, SLOT(slotDelStation()));

  readOptions();
}

// 
////////////////////////////////////////////////////////////////////////////
void t_pppWidgets::readOptions() {

  bncSettings settings;

  // ComboBoxes
  // ----------
  int ii = _dataSource->findText(settings.value(_dataSource->objectName()).toString());
  if (ii != -1) {
    _dataSource->setCurrentIndex(ii);
  }
  ii = _lcGPS->findText(settings.value(_lcGPS->objectName()).toString());
  if (ii != -1) {
    _lcGPS->setCurrentIndex(ii);
  }
  ii = _lcGLONASS->findText(settings.value(_lcGLONASS->objectName()).toString());
  if (ii != -1) {
    _lcGLONASS->setCurrentIndex(ii);
  }
  ii = _lcGalileo->findText(settings.value(_lcGalileo->objectName()).toString());
  if (ii != -1) {
    _lcGalileo->setCurrentIndex(ii);
  }

  // FileChoosers
  // ------------
  _rinexObs ->setFileName(settings.value(_rinexObs ->objectName()).toString());
  _rinexNav ->setFileName(settings.value(_rinexNav ->objectName()).toString());
  _corrFile ->setFileName(settings.value(_corrFile ->objectName()).toString());
  _crdFile  ->setFileName(settings.value(_crdFile  ->objectName()).toString());
  _antexFile->setFileName(settings.value(_antexFile->objectName()).toString());

  // LineEdits
  // ---------
  _corrMount->setText(settings.value(_corrMount->objectName()).toString());
  _logFile  ->setText(settings.value(_logFile  ->objectName()).toString());
  _nmeaFile ->setText(settings.value(_nmeaFile ->objectName()).toString());
  _nmeaPort ->setText(settings.value(_nmeaPort ->objectName()).toString());
  _sigmaC1  ->setText(settings.value(_sigmaC1  ->objectName()).toString());
  _sigmaL1  ->setText(settings.value(_sigmaL1  ->objectName()).toString());

  // SpinBox
  // -------
  _corrWaitTime->setValue(settings.value(_corrWaitTime->objectName()).toInt());

  // Table with stations
  // -------------------
  for (int iRow = _staTable->rowCount()-1; iRow >=0; iRow--) {
    _staTable->removeRow(iRow);
  }
  int iRow = -1;
  QListIterator<QString> it(settings.value(_staTable->objectName()).toStringList());
  while (it.hasNext()) {
    QStringList hlp = it.next().split(",");
    ++iRow;
    _staTable->insertRow(iRow);
    for (int iCol = 0; iCol < hlp.size(); iCol++) {
      _staTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
    }
  }
}

// 
////////////////////////////////////////////////////////////////////////////
void t_pppWidgets::saveOptions() {

  bncSettings settings;

  settings.setValue(_dataSource  ->objectName(), _dataSource  ->currentText());
  settings.setValue(_rinexObs    ->objectName(), _rinexObs    ->fileName());
  settings.setValue(_rinexNav    ->objectName(), _rinexNav    ->fileName());
  settings.setValue(_corrMount   ->objectName(), _corrMount   ->text());
  settings.setValue(_corrFile    ->objectName(), _corrFile    ->fileName());
  settings.setValue(_crdFile     ->objectName(), _crdFile     ->fileName());
  settings.setValue(_antexFile   ->objectName(), _antexFile   ->fileName());
  settings.setValue(_logFile     ->objectName(), _logFile     ->text());
  settings.setValue(_nmeaFile    ->objectName(), _nmeaFile    ->text());
  settings.setValue(_nmeaPort    ->objectName(), _nmeaPort    ->text());
  settings.setValue(_lcGPS       ->objectName(), _lcGPS       ->currentText());
  settings.setValue(_lcGLONASS   ->objectName(), _lcGLONASS   ->currentText());
  settings.setValue(_lcGalileo   ->objectName(), _lcGalileo   ->currentText());
  settings.setValue(_sigmaC1     ->objectName(), _sigmaC1     ->text());
  settings.setValue(_sigmaL1     ->objectName(), _sigmaL1     ->text());
  settings.setValue(_corrWaitTime->objectName(), _corrWaitTime->value());

  QStringList staList;
  for (int iRow = 0; iRow < _staTable->rowCount(); iRow++) {
    QString hlp;
    for (int iCol = 0; iCol < _staTable->columnCount(); iCol++) {
      if (_staTable->item(iRow, iCol)) {
        hlp += _staTable->item(iRow, iCol)->text() + ",";
      }
    }
    if (!hlp.isEmpty()) {
      staList << hlp;
    }
  }
  settings.setValue(_staTable->objectName(), staList);
}

// 
////////////////////////////////////////////////////////////////////////////
void t_pppWidgets::slotEnableWidgets() {

  const static QPalette paletteWhite(QColor(255, 255, 255));
  const static QPalette paletteGray(QColor(230, 230, 230));

  bool allDisabled = _dataSource->currentText() == "no";
  bool realTime    = _dataSource->currentText() == "Real-Time Streams";
  bool rinexFiles  = _dataSource->currentText() == "RINEX Files";

  QListIterator<QWidget*> it(_widgets);
  while (it.hasNext()) {
    QWidget* widget = it.next();
    widget->setEnabled(!allDisabled);
  }

  if      (realTime) {
    _rinexObs->setEnabled(false);    
    _rinexNav->setEnabled(false);    
    _corrFile->setEnabled(false);    
  }
  else if (rinexFiles) {
    _corrMount->setEnabled(false);
  }

  _dataSource->setEnabled(true);

  it.toFront();
  while (it.hasNext()) {
    QWidget* widget = it.next();
    if (widget->isEnabled()) {
      widget->setPalette(paletteWhite);
    }
    else {
      widget->setPalette(paletteGray);
    }
  }
}

// 
////////////////////////////////////////////////////////////////////////////
void t_pppWidgets::slotAddStation() {
  int iRow = _staTable->rowCount();
  _staTable->insertRow(iRow);
  for (int iCol = 0; iCol < _staTable->columnCount(); iCol++) {
    _staTable->setItem(iRow, iCol, new QTableWidgetItem(""));
  }
}

// 
////////////////////////////////////////////////////////////////////////////
void t_pppWidgets::slotDelStation() {
  int nRows = _staTable->rowCount();
  bool flg[nRows];
  for (int iRow = 0; iRow < nRows; iRow++) {
    if (_staTable->isItemSelected(_staTable->item(iRow,1))) {
      flg[iRow] = true;
    }
    else {
      flg[iRow] = false;
    }
  }
  for (int iRow = nRows-1; iRow >= 0; iRow--) {
    if (flg[iRow]) {
      _staTable->removeRow(iRow);
    }
  }
}