/***************************************************************************
**
**  This file is part of waran.
**
**  waran 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, either version 3 of the License, or
**  (at your option) any later version.
**
**  waran 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 Foobar.  If not, see <http://www.gnu.org/licenses/>
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2011-09-05
**  Copyright: 2011-2019
**    Marc Wathelet (ISTerre, Grenoble, France)
**
***************************************************************************/

#include "Station.h"
#include "CubeLink.h"
#include "GpsLink.h"
#include "SystemLink.h"
#include "NetLink.h"
#include "SeismicParameters.h"

/*!
  \class Station Station.h
  \brief Brief description of class still missing

  Full description of class still missing
*/

/*!
  Description of constructor still missing
*/
Station::Station()
{
  TRACE;
  _index=-1;

  _cubeLink=0;
  _gpsLink=0;
  _systemLink=0;
  _netLink=0;

  clear();
}

/*!
  Description of destructor still missing
*/
Station::~Station()
{
  TRACE;
}

void Station::clear()
{
  TRACE;
  _frequency=0;
  _hardwareGain=0;
  _numberOfBits=0.0;
  _seismicState.clear();
  _gpsState.clear();
  _diskSpace=0.0;
  _internalBattery=QString();
  _externalBattery=QString();
  _temperature=QString();
  _comments=QString();
  _buddies.clear();

  if(_systemLink) {
    _systemLink->highRateRefresh();
  }
  if(_gpsLink) {
    _gpsLink->highRateRefresh();
  }
  if(_cubeLink) {
    _cubeLink->highRateRefresh();
  }
}

void Station::setType(Type t)
{
  TRACE;
  if(_netLink || _systemLink) {
    App::log(tr("Type of station cannot be modified\n") );
    return;
  }
  _type=t;
  if(_type==AcquisitionUnit) {
    _cubeLink=new CubeLink(this);
    _gpsLink=new GpsLink(this);
    connect(_gpsLink, SIGNAL(rawFileSize(int)), this, SIGNAL(rawFileSize(int)));
    connect(_gpsLink, SIGNAL(rawFileReady()), this, SIGNAL(rawFileReady()));
    connect(_gpsLink, SIGNAL(rawFileError()), this, SIGNAL(rawFileError()));
  } else {
    _gpsLink=new GpsLink(this);
  }
  _systemLink=new SystemLink(this);
  _netLink=new NetLink(this);
}

bool Station::isAvailable()
{
  TRACE;
  if(!_systemLink->isAvailable()) {
    clear();
    return false;
  }
  return true;
}

QString Station::linkState() const
{
  TRACE;
  QString msg;
  if(!_netLink->isAvailable()) {
    if(!msg.isEmpty()) msg+="\n";
    msg+="Network daemon not active";
  }
  if(!_systemLink->isAvailable()) {
    if(!msg.isEmpty()) msg+="\n";
    msg+="System daemon not active";
  }
  if(_type==AcquisitionUnit) {
    if(!_gpsLink->isAvailable()) {
      if(!msg.isEmpty()) msg+="\n";
      msg+="GPS daemon not active";
    }
    if(!_cubeLink->isAvailable()) {
      if(!msg.isEmpty()) msg+="\n";
      msg+="Cube deamon not active";
    }
  }
  return msg;
}

void Station::setFrequency(int f)
{
  TRACE;
  if(f!=_frequency) {
    _frequency=f;
    emit dataChanged(_index);
  }
}

void Station::setHardwareGain(int g)
{
  TRACE;
  if(g!=_hardwareGain) {
    _hardwareGain=g;
    emit dataChanged(_index);
  }
}

void Station::setNumberOfBits(double n)
{
  TRACE;
  if(n!=_numberOfBits) {
    _numberOfBits=n;
    emit dataChanged(_index);
  }
}

void Station::setSeismicState(const QString& s)
{
  TRACE;
  if(s!=_seismicState) {
    _seismicState=s;
    emit dataChanged(_index);
  }
}

void Station::setGpsState(const QString& s)
{
  TRACE;
  if(s!=_gpsState) {
    _gpsState=s;
    emit dataChanged(_index);
  }
}

void Station::setDiskSpace(double s)
{
  TRACE;
  if(s!=_diskSpace) {
    _diskSpace=s;
    emit dataChanged(_index);
  }
}

void Station::setInternalBattery(const QString& b)
{
  TRACE;
  if(b!=_internalBattery) {
    _internalBattery=b;
    emit dataChanged(_index);
  }
}

void Station::setExternalBattery(const QString& b)
{
  TRACE;
  if(b!=_externalBattery) {
    _externalBattery=b;
    emit dataChanged(_index);
  }
}

void Station::setTemperature(const QString& t)
{
  TRACE;
  if(t!=_temperature) {
    _temperature=t;
    emit dataChanged(_index);
  }
}

void Station::setBuddies(const QString& b)
{
  TRACE;
  if(b!=_buddies) {
    _buddies=b;
    emit dataChanged(_index);
  }
}

void Station::requestComments()
{
  TRACE;
  _systemLink->comments();
}

void Station::addComment(const QString &c)
{
  TRACE;
  _systemLink->addComment(c);
}

void Station::setComments(const QString& c)
{
  TRACE;
  if(c!=_comments) {
    _comments=c;
    emit dataChanged(_index);
  }
  emit commentsRefreshed(_index);
}

void Station::setSeismicParameters(const SeismicParameters& param)
{
  TRACE;
  if(_cubeLink->isAvailable()) {
    if(_seismicState.startsWith("stopped")) {
      _cubeLink->setFrequency(param.frequency());
      // General user mode cannot use a software level other than 1 (maximum bit dynamic).
      _cubeLink->setGains(param.hardwareGain(), 1);
    } else {
      Message::warning(MSG_ID, tr("Changing seismic parameters"),
                       tr("Station '%1' must be stopped before any modification of its acquisition parameters").arg(_name),
                       Message::ok(), true);
    }
  }
}

void Station::startSeismic()
{
  TRACE;
  if(_cubeLink->isAvailable()) {
    _cubeLink->start();
  }
}

void Station::stopSeismic()
{
  TRACE;
  if(_cubeLink->isAvailable()) {
    _cubeLink->stop();
  }
}

void Station::startGps(int duration)
{
  TRACE;
  if(_gpsLink->isAvailable()) {
    _gpsLink->start(duration);
  }
}

void Station::stopGps()
{
  TRACE;
  if(_gpsLink->isAvailable()) {
    _gpsLink->stop();
  }
}

void Station::navigationGps()
{
  TRACE;
  if(_gpsLink->isAvailable()) {
    _gpsLink->navigation();
  }
}

void Station::downloadGps()
{
  TRACE;
  if(_gpsLink->isAvailable()) {
    _gpsLink->raw();
  }
}

void Station::abortDownloadGps()
{
  TRACE;
  if(_gpsLink->isAvailable()) {
    _gpsLink->abortRaw();
  }
}

void Station::reboot()
{
  TRACE;
  _systemLink->reboot();
}

void Station::powerOff()
{
  TRACE;
  _systemLink->powerOff();
}

void Station::clearUsb()
{
  TRACE;
  _systemLink->clearUsb();
}

QString Station::gpsFileName()
{
  TRACE;
  QString fileName=_name;
  fileName.replace("WAU", "WA");
  fileName="/tmp/waran/"+fileName;
  QDate d=QDate::currentDate();
  fileName+=QString("%1").arg(d.dayOfYear(), 3, 10, QChar('0'));
  fileName+="0.";
  fileName+=QString::number(d.year()).right(2);
  _currentGpsFileName=fileName;
  return fileName;
}
