/***************************************************************************
**
**  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 "Acquisition.h"
#include "AcquisitionSignals.h"

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

  Full description of class still missing
*/

QDir Acquisition::_destDir;

/*!
  Description of constructor still missing
*/
Acquisition::Acquisition(double timeScale)
    : Thread()
{
  TRACE;
  srand(time(nullptr)); // initialize random generator
  _globalTimer=nullptr;
  _timeScale=timeScale;
}

/*!
  Description of destructor still missing
*/
Acquisition::~Acquisition()
{
  TRACE;
  qDeleteAll(_stations);
  delete _globalTimer;
}

bool Acquisition::setSignals(SubSignalPool subPool)
{
  TRACE;
  QString log;
  if( !_array.addSignals(&subPool) ||
      !_array.hasAllComponents()) {
    App::log(log+"\n");
    return false;
  }
  if(_array.count()<2) {
    App::log(tr("Creating array: found less than 2 stations.\n"));
    return false;
  }
  log += tr("Found %1 different stations\n").arg(_array.count());
  App::log(log+"\n");
  int n=_array.count();
  for(int i=0; i<n; i++) {
    AcquisitionSignals * stat=new AcquisitionSignals(_array.at(i), _timeScale);
    _stations.append(stat);
  }
  // Set available signals for each station
  DateTime globalMinTime=DateTime::maximumTime;
  DateTime globalMaxTime=DateTime::minimumTime;
  /*WindowingParameters param;
  param.setNComponents(_array.nComponents());
  param.setNStations(_array.count());
  param.rawSignal.doIt=false;
  param.filtSignal.doIt=false;
  param.percClip=100;*/
  for(int i=0;i<n;i++) {
    DateTime t1, t2;
    t1=_array.at(i)->minTime();
    if(t1<globalMinTime) globalMinTime=t1;
    t2=_array.at(i)->maxTime();
    if(t2>globalMaxTime) globalMaxTime=t2;
    AcquisitionSignals * stat=_stations.at(i);
    /*TimeRange tw(t1, t2);
    AcquisitionSignals * stat=_stations.at(i);
    //SparseTimeRange stat->originalSignals()->timeRange(tw) const;
    //stat->setRange(tw);
    //stat->setKeep(param,i);
    stat->setProcessed(tw, 0);*/
  }
  _globalTimeWindow.setStart(globalMinTime);
  _globalTimeWindow.setEnd(globalMaxTime);
  for(int i=0;i<n;i++) {
    _stations.at(i)->setSignalStartTime(_globalTimeWindow.start());
  }
  return true;
}

bool Acquisition::setDestination(QString destDir)
{
  TRACE;
  _destDir.setPath(destDir);
  if(_destDir.exists()) {
    QStringList filters;
    filters.append("*.mseed");
    QStringList files=_destDir.entryList(filters);
    for(QStringList::iterator it=files.begin();it!=files.end();it++) {
      _destDir.remove( *it);
    }
    return true;
  } else {
    return false;
  }
}

void Acquisition::startStations(QString stationList)
{
  TRACE;
  QStringList stations=stationList.split(",", QString::SkipEmptyParts);
  bool all=(stationList=="all");
  int n=_array.count();
  for(QStringList::iterator it=stations.begin();it!=stations.end();it++) {
    for(int i=0;i<n;i++) {
      AcquisitionSignals * s=_stations.at(i);
      if(all || s->originalSignals()->name()==*it) {
        s->setOn(true);
      }
    }
  }
}

void Acquisition::stopStations(QString stationList)
{
  TRACE;
  QStringList stations=stationList.split(",", QString::SkipEmptyParts);
  bool all=(stationList=="all");
  int n=_array.count();
  for(QStringList::iterator it=stations.begin();it!=stations.end();it++) {
    for(int i=0;i<n;i++) {
      AcquisitionSignals * s=_stations.at(i);
      if(all || s->originalSignals()->name()==*it) {
        s->setOn(false);
      }
    }
  }
}

void Acquisition::stop()
{
  TRACE;
  _globalTimer->stop();
  int n=_array.count();
  for(int i=0;i<n;i++) {
    _stations.at(i)->stop();
  }
  exit();
  while(isRunning()) {
    CoreApplication::sleep(500);
    QCoreApplication::processEvents();
  }
}

void Acquisition::status()
{
  TRACE;
  int n=_array.count();
  for(int i=0;i<n;i++) {
    printf("%-20s:",_array.at(i)->name().toLatin1().data());
    printf(" %6s",_stations.at(i)->isOn() ? "on" : "off");
    printf(" %6s",_stations.at(i)->isActive() ? "active" : "idle");
    printf("\n");
  }
}

void Acquisition::run()
{
  TRACE;
  mainLoop();
  _globalTimer=new QTimer;
  _globalTimer->setSingleShot(false);
  connect(_globalTimer, SIGNAL(timeout()), this, SLOT(mainLoop()), Qt::DirectConnection);
  _globalTimer->start(qCeil((_globalTimeWindow.lengthSeconds()+2.0*_delay)*1000.0/_timeScale));

  QThread::exec();
}

void Acquisition::mainLoop()
{
  int n=_array.count();
  for(int i=0;i<n;i++) {
    _stations.at(i)->stop();
  }
  DateTime now(QDateTime::currentDateTime());
  for(int i=0;i<n;i++) {
    _stations.at(i)->setPlayStartTime(now);
  }
  for(int i=0;i<n;i++) {
    _stations.at(i)->start(_delay);
  }
}
