/***************************************************************************
**
**  This file is part of vslarray.
**
**  vslarray 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.
**
**  vslarray 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: 2008-03-24
**  Copyright: 2008-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <GeopsyCore.h>
#include "AcquisitionSignals.h"
#include "Acquisition.h"

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

  Full description of class still missing
*/

/*!
  Description of constructor still missing
*/
AcquisitionSignals::AcquisitionSignals(const StationSignals * originalSignals, double timeScale)
    : StationProcessSignals(originalSignals)
{
  TRACE;
  _on=false;
  _timer=nullptr;
  _timeScale=timeScale;
}

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

bool AcquisitionSignals::setProcessed(const TimeRange& tw, const AbstractParameters * )
{
  TRACE;
  int nComp=nComponents();
  for(int iComp=0; iComp<nComp; iComp++) {
    if(!copyOriginalSignal(iComp, tw)) {
      return false;
    }
  }
  return true;
}

void AcquisitionSignals::stop()
{
  if(_timer) {
    _timer->stop();
  }
}

void AcquisitionSignals::start(double delay)
{
  _delay=delay;
  if(!_timer) {
    _timer=new QTimer;
    connect(_timer, SIGNAL(timeout()), this, SLOT(sendSignals()), Qt::DirectConnection);
  }
  _timer->setSingleShot(true);
  int rDelay=qRound(static_cast<double>(rand())/static_cast<double>(RAND_MAX)
                    *_delay*1000.0/_timeScale);
  _timer->start(rDelay);
}

void AcquisitionSignals::sendSignals()
{
  if(isOn()) {
    //printf("Sending signals for station %s\n",originalSignals()->name().toLatin1().data());
    DateTime now(QDateTime::currentDateTime());
    DateTime sentTime=_signalStartTime.shifted(_playStartTime.secondsTo(now)*_timeScale);
    TimeRange r(_lastSentTime, sentTime);
    SparseTimeRange sr=originalSignals()->timeRange(r);
    // Calculate the sampling times (startTime and deltaT) of each sub-ranges of sr
    // Incompatible time ranges are automatically suppressed from keep
    SparseKeepSignal keep(sr);
    originalSignals()->setSampling(&keep);
    const QVector<KeepSignal *>& keeps=keep.keeps();
    static const QString fileNameSuffix=".mseed";
    for(QVector<KeepSignal *>::const_iterator it=keeps.begin();it!=keeps.end();it++) {
      setProcessed((*it)->timeRange(), nullptr);
      save((*it)->startTime(), fileNameSuffix);
    }
    _lastSentTime=sentTime;
  }
  int rDelay=qRound((0.5*static_cast<double>(rand())/static_cast<double>(RAND_MAX)+0.75)
                    *_delay*1000.0/_timeScale);
  _timer->start(rDelay);
}

void AcquisitionSignals::save(const DateTime& startTime, const QString& fileNameSuffix)
{
  int nComp=nComponents();
  for(int iComp=0; iComp<nComp; iComp++) {
    Signal * sig=new Signal(GeopsyCoreEngine::instance()->defaultDatabase());
    sig->setTemporary();
    DoubleSignal * data=processed(iComp);
    sig->setNSamples(data->nSamples());
    sig->setSamplingPeriod(data->samplingPeriod());
    sig->setStartTime(startTime);
    sig->setName(originalSignals()->name());
    sig->setComponent(StationSignals::component(iComp, originalSignals()->components()));
    sig->SignalTemplate<double>::copySamplesFrom(data);
    //printf("Save from %lf to %lf\n",sig->t0(), sig->endTime());
    QFile f(Acquisition::destination().absoluteFilePath(sig->nameComponent() + fileNameSuffix));
    if(f.open(QIODevice::Append)) {
      sig->writeMiniSeed(f);
    }
    delete sig;
  }
}

/*void AcquisitionSignals::save(int iStart, int iEnd, double deltaT, double t0, const QString& fileNameSuffix)
{
  int nComp=nComponents();
  for(int iComp=0; iComp<nComp; iComp++) {
    Signal * sig=new Signal(GeopsyCoreEngine::instance()->currentDB());
    sig->setTemporary();
    sig->setTimeReference(_referenceTime);
    sig->setNSamples(iEnd-iStart);
    sig->setDeltaT(deltaT);
    sig->setT0(t0); // milliseconds are never taken into account in timeReference
    sig->setName(originalSignals()->name());
    sig->setComponent(StationSignals::component(iComp, originalSignals()->components()) );
    sig->SignalTemplate<double>::copySamplesFrom(processed(iComp), iStart, 0, sig->nSamples());
    QFile f(Acquisition::destination().absoluteFilePath(sig->nameComponent() + fileNameSuffix));
    if(f.open(QIODevice::Append)) {
      sig->writeMiniSeed(f);
    }
    delete sig;
  }
}*/
