/***************************************************************************
**
**  This file is part of HVGui.
**
**  HVGui 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.
**
**  HVGui 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: 2007-08-17
**  Copyright: 2007-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <GeopsyGui.h>
#include <HVCore.h>

#include "AbstractHVWidget.h"
#include "AbstractSummary.h"
#include "AbstractResultSheet.h"
#include "LoadWinStatList.h"

namespace HVGui {

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

    Full description of class still missing
  */

  /*!
    Description of constructor still missing
  */
  AbstractHVWidget::AbstractHVWidget(QWidget * parent)
      : AbstractToolWidget(parent, 2)
  {
    TRACE;
    setupUi(this);

    _forceReProcessAll=true;
    _childrenList[0]=nullptr;
    _childrenList[1]=nullptr;

    connect(currentDisplayStation, SIGNAL(activated( int) ), this, SLOT(setCurrentDisplayStation()) );
    connect(startBut, SIGNAL(clicked()), this, SLOT(start()));
    connect(stopBut, SIGNAL(clicked()), this, SLOT(stop()));
    connect(loadParam, SIGNAL(clicked()), this, SLOT(loadLogParameters()) );

    winParam->createSelectMenu(selectBut);
    connect(winParam, SIGNAL(autoWindows()), this, SLOT(autoWindows()));
    connect(winParam, SIGNAL(beginAddWindowsManually()), this, SLOT(beginAddWindowsManually()));
    connect(winParam, SIGNAL(endAddWindowsManually()), this, SLOT(endAddWindowsManually()));
    connect(winParam, SIGNAL(beginRemoveWindowsManually()), this, SLOT(beginRemoveWindowsManually()));
    connect(winParam, SIGNAL(endRemoveWindowsManually()), this, SLOT(endRemoveWindowsManually()));
    connect(winParam, SIGNAL(inverseWindows()), this, SLOT(inverseWindows()));
    connect(winParam, SIGNAL(clearWindows()), this, SLOT(clearWindows()));
    connect(winParam, SIGNAL(loadWindows()), this, SLOT(loadWindows()));

    sampling->setUnit(tr(" Hz"));
    sampling->setPrecision(2);
    sampling->setSingleStep(0.25);
    sampling->setAdmissibleRange(1e-99, std::numeric_limits<double>::infinity());

    WindowFunctionParameters t;
    t.setAlpha(0.1);
    tapering->setParameters(t);

    smoothing->setUnit("Hz");

    connect(winParam, SIGNAL(parametersChanged()), this, SLOT(winParamChanged()));
    connect(smoothing, SIGNAL(parametersChanged()), this, SLOT(procParamChanged()));
    connect(tapering, SIGNAL(parametersChanged()), this, SLOT(procParamChanged()));
    connect(sampling, SIGNAL(parametersChanged()), this, SLOT(procParamChanged()));
    connect(azimuthValue, SIGNAL(valueChanged(double)), this, SLOT(procParamChanged()));
    connect(horizontalEnergy, SIGNAL(toggled(bool)), this, SLOT(procParamChanged()));
    connect(azimuth, SIGNAL(toggled(bool)), this, SLOT(procParamChanged()));
    connect(highPassFrequency, SIGNAL(valueChanged(double)), this, SLOT(procParamChanged()));
  }

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

  void AbstractHVWidget::restoreFields()
  {
    TRACE;
    AbstractToolWidget::restoreFields();
    if(timeWindowLayer()) {
      connect(timeWindowLayer(), SIGNAL(addWindows(Signal *, const TimeRange&)),
              this, SLOT(manualAddWindows(Signal *, const TimeRange&)));
      connect(timeWindowLayer(), SIGNAL(removeWindows(Signal *, const TimeRange&)),
              this, SLOT(manualRemoveWindows(Signal *, const TimeRange&)));
    }
    if(pickLayer()) {
      connect(pickLayer(), SIGNAL(pickChanged(Signal *, QString)), timeLimits, SLOT(updatePicks()));
    }
  }

  void AbstractHVWidget::updateAllFields()
  {
    TRACE;
    winParam->updateAllFields();
    sampling->updateAllFields();
    smoothing->updateAllFields();
    on_useMakeUpResults_toggled();
    on_useMakeUpSummary_toggled();
    on_doHighPass_toggled();
    currentDisplayStation->setCurrentIndex(0);
    timeLimits->setSubPool(_tool->subPool());
    timeLimits->updateAllFields();
    tapering->updateAllFields();
    setMakeUp();
  }

  bool AbstractHVWidget::setSubPool(SubSignalPool * subPool)
  {
    // Connection delayed here because tool is notyet available in base class constructor
    // Here it must be initialized.
    connect(tool(), SIGNAL(finished()), this, SLOT(finish()));

    if(!AbstractToolWidget::setSubPool(subPool)) {
      return false;
    }
    int n=tool()->stations().count();
    for(int i=0; i<n; i++) {
      AbstractStation * stat=tool()->stations().at(i);
      if(timeWindowLayer()) {
        connect(stat, SIGNAL(windowsChanged()), timeWindowLayer(), SLOT(deepUpdate()));
        const StationSignals * sigs=stat->originalSignals();
        int ncomp=sigs->nComponents();
        for(int i=0; i<ncomp; i++) {
          timeWindowLayer()->addTimeWindows(sigs->originals(i), &stat->windows());
        }
      }
      currentDisplayStation->addItem(stat->name());
      winParam->addStation(stat->name());
    }
    createResults(subPool->name());
    return true;
  }

  void AbstractHVWidget::createResults(QString subPoolName)
  {
    TRACE;
    ASSERT(!_winResults && !_summary);

    _childrenList[0]=createResultSheet();
    _winResults->setObjectName("HVGuiResults");
    _winResults->addActions();
    _winResults->setStations(tool()->stations());
    _winResults->setWindowTitle(subPoolName);
    connect(_winResults, SIGNAL(categoryChanged()), this, SLOT(updateSummary()));
    GeopsyGuiEngine::instance()->addSubWindow(this, _winResults)->setUserClosable(false);

    if(tool()->stations().count()>1) {
      _childrenList[1]=createSummary();
      if(_summary) {
        _summary->setObjectName("HVGuiSummary");
        _summary->addActions();
        _summary->setStations(tool()->stations());
        _summary->setWindowTitle(subPoolName);
        GeopsyGuiEngine::instance()->addSubWindow(this, _summary)->setUserClosable(false);
      }
    }
    samplingPeriod();
  }

  /*!
    This function is called once the stations are setup, we check
    if all stations have the same sampling frequency to enable
    commonTimeWindow option. Return 0 if the sampling frequency is not constant.
  */
  double AbstractHVWidget::samplingPeriod()
  {
    double sp=0.0;
    int n=tool()->stations().count();
    for(int i=0;i < n;i++ ) {
      AbstractStation * stat=tool()->stations()[i];
      if(sp==0.0) {
        sp=stat->originalSignals()->samplingPeriod();
      } else if(sp!=stat->originalSignals()->samplingPeriod()) {
        commonTimeWindows->setEnabled(false);
        commonTimeWindows->setChecked(false);
        commonTimeWindows->setToolTip(tr("Common time windows disabled because sampling frequencies differ"));
        return 0.0;
      }
    }
    return sp;
  }

  AbstractStation * AbstractHVWidget::belongsTo(Signal * sig)
  {
    TRACE;
    const QList<AbstractStation *> list=tool()->stations();
    for(QList<AbstractStation *>::const_iterator it=list.begin();it!=list.end();++it) {
      if((*it)->originalSignals()->contains(sig)) {
        return *it;
      }
    }
    return nullptr;
  }

  /*!
    Return stations selected in result page. If no station is selected, the returned list contains
    all stations.
  */
  QList<AbstractStation *> AbstractHVWidget::selectedStations()
  {
    TRACE;
    QList<AbstractStation *> sel=_winResults->selectedStations();
    if(sel.isEmpty()) {
      sel=tool()->stations();
    } else if(sel.count()<tool()->stations().count()) {
      QString statListString;
      for(QList<AbstractStation *>::iterator it=sel.begin();it!=sel.end();++it) {
        statListString+="\n     "+(*it)->name();
      }
      switch(Message::question(MSG_ID, windowTitle(), tr("%1 station(s) is/are selected in result sheet:%2\n"
                               "Do you want to process all station(s) or only the selected one(s)?")
                               .arg(sel.count()).arg(statListString),
                               tr("All"), tr("Selection"), Message::cancel())) {
      case Message::Answer0:
        sel=tool()->stations();
        break;
      case Message::Answer1:
        break;
      case Message::Answer2:
        sel.clear();
        break;
      }
    }
    return sel;
  }

  void AbstractHVWidget::windowsChanged()
  {
    TRACE;
    if(timeWindowLayer()) timeWindowLayer()->deepUpdate();
    QFont f(startBut->font());
    f.setBold(true);
    startBut->setFont(f);
    updateNofWindows();
  }

  void AbstractHVWidget::beginAddWindowsManually()
  {
    TRACE;
    if(timeWindowLayer()) {
      timeWindowLayer()->toggleTrackingAction(true, TimeWindowLayer::Add);
    }
  }

  void AbstractHVWidget::endAddWindowsManually()
  {
    TRACE;
    if(timeWindowLayer()) {
      timeWindowLayer()->toggleTrackingAction(false, TimeWindowLayer::Add);
    }
  }

  void AbstractHVWidget::beginRemoveWindowsManually()
  {
    TRACE;
    if(timeWindowLayer()) {
      timeWindowLayer()->toggleTrackingAction(true, TimeWindowLayer::Remove);
    }
  }

  void AbstractHVWidget::endRemoveWindowsManually()
  {
    TRACE;
    if(timeWindowLayer()) {
      timeWindowLayer()->toggleTrackingAction(false, TimeWindowLayer::Remove);
    }
  }

  void AbstractHVWidget::manualAddWindows(Signal * sig, const TimeRange& r)
  {
    TRACE;
    AbstractStation * stat=belongsTo(sig);
    if(stat) {
      updateParameters();
      QString log=tr("Add windows in range [%1, %2]\n")
                      .arg(r.start().toString(DateTime::defaultUserFormat))
                      .arg(r.end().toString(DateTime::defaultUserFormat));

      LayerLocker ll(timeWindowLayer());
      tool()->addWindows(stat, &r, log);
      ll.unlock();
      windowsChanged();
      setWinParamChanged(false);
    }
  }

  void AbstractHVWidget::manualRemoveWindows(Signal * sig, const TimeRange& r)
  {
    TRACE;
    AbstractStation * stat=belongsTo(sig);
    if(stat) {
      updateParameters();
      LayerLocker ll(timeWindowLayer());
      tool()->removeWindows(stat, r);
      ll.unlock();
      windowsChanged();
    }
  }

  void AbstractHVWidget::autoWindows()
  {
    TRACE;
    QList<AbstractStation *> statList=selectedStations();
    if(statList.isEmpty()) return;
    updateParameters();

    LayerLocker ll(timeWindowLayer());
    tool()->autoWindows(&statList);
    ll.unlock();
    windowsChanged();
    setWinParamChanged(false);
  }

  void AbstractHVWidget::inverseWindows()
  {
    TRACE;
    QList<AbstractStation *> statList=selectedStations();
    if(statList.isEmpty()) return;
    updateParameters();

    LayerLocker ll(timeWindowLayer());
    tool()->inverseWindows(&statList);
    ll.unlock();
    windowsChanged();
    setWinParamChanged(false);
  }

  /*!
    One of the signals changed (mostly enlarged by DynamicSignal), check for supplementary windows
  */
  void AbstractHVWidget::refreshSignal(Signal * sig)
  {
    TRACE;
    if(!dynamicUpdate->isChecked()) return;
    updateParameters();

    LayerLocker ll(timeWindowLayer());
    if(tool()->addWindows(sig)) {
      /* Temporarily removed the automatic computation

      SpectrumParameters hvparam;
      hvparam.setFromDialog(_d);
      for(int i=0;i < n;i++ ) {
        AbstractStation * stat=_stations[ i ];
        if(oldWindowsCount[i]<stat->windowCount()) {
          TimeRangeList addedList(stat->windows(), oldWindowsCount[i]);
          stat->start(addedList, hvparam);
        }
      }*/
    }
    ll.unlock();
    windowsChanged();
  }

  void AbstractHVWidget::clearWindows()
  {
    TRACE;
    QList<AbstractStation *> statList=selectedStations();
    if(statList.isEmpty()) return;

    QList<AbstractStation *>::iterator it;
    // Test if there are any gray windows
    for(it=statList.begin();it!=statList.end();++it) {
      if((*it)->hasGrayWindows()) break;
    }
    if(it!=statList.end()) {
      switch (Message::question(MSG_ID, tr("Removing time windows"),
                                        tr("You discarded some time windows (grayed). Do you really want to remove all windows or only the grayed ones?"),
                                        tr("Remove all"), tr("Remove grayed"),
                                        Message::cancel()) ) {
      case Message::Answer0:
        break;
      case Message::Answer1:
        for(it=statList.begin();it!=statList.end();++it) {
          (*it)->clearGrayWindows();
        }
        windowsChanged();
        return ;
      default:
        return ;
      }
    }
    LayerLocker ll(timeWindowLayer());
    for(it=statList.begin();it!=statList.end();++it) {
      (*it)->clearAllWindows();
      (*it)->clearWindowingLog();
    }
    ll.unlock();
    windowsChanged();
  }

  bool AbstractHVWidget::hasWindows()
  {
    TRACE;
    if (countTimeWindows()==0) {
      if (Message::warning(MSG_ID, tr("Calculating H/V"),
                           tr("No windows have been selected. Do you want to "
                              "select them automatically with current parameters?"),
                           Message::yes(), Message::no())==Message::Answer0) {
        autoWindows();
      } else {
        return false;
      }
    }
    return true;
  }

  void AbstractHVWidget::start()
  {
    TRACE;
    if(subPoolLocked()) {
      return;
    }
    if(!hasWindows()) return;
    QList<AbstractStation *> statList=selectedStations();
    if(statList.isEmpty()) return;

    updateParameters();
    lockSubPool();
    detailedStatus->setLoop(tool()->loop());
    setRunning(true);
    tool()->setWindowColors();
    // High pass filter to be integrated in core tool
    tool()->start();
    for(int i=statList.count()-1; i>=0; i--) {
      statList.at(i)->setWindowsChanged(false);
    }
  }

  void AbstractHVWidget::stop()
  {
    TRACE;
    tool()->stop();
  }

  void AbstractHVWidget::finish()
  {
    unlockSubPool();
    setRunning(false);
    _winResults->showValues();
    _winResults->setParameters(*tool()->parameters());
    if(_summary) {
      updateSummary();
      _summary->show();
    }
    _winResults->show();
    if(timeWindowLayer()) {
      timeWindowLayer()->setShowColors(true);
    }
    // Set homogeneous limits
    setLimits();

    setMakeUp();

    if(timeWindowLayer()) timeWindowLayer()->deepUpdate();
    QFont f(startBut->font());
    f.setBold(false);
    startBut->setFont(f);
    _forceReProcessAll=false;
  }

  void AbstractHVWidget::setRunning(bool r, const QString& message)
  {
    TRACE;
    selectBut->setEnabled(!r);
    startBut->setEnabled(!r);
    stopBut->setEnabled(r);
    if(r) {
      if(message.isEmpty()) {
        mainStatus->setText(tr("Running..."));
      } else {
        mainStatus->setText(message);
      }
    } else {
      mainStatus->setText(tr("Not running"));
    }
  }

  void AbstractHVWidget::setMakeUp()
  {
    TRACE;
    HVParameters param;
    getParameters(param);
    if(!param.makeUpResults().isEmpty()) {
      _winResults->restoreMakeUp(param.makeUpResults());
    }
    _winResults->setLayout(param.plotCountPerLineResults(), param.pageHeightResults());
    if(_summary && !param.makeUpSummary().isEmpty()) {
      _summary->sheet()->restoreMakeUp(param.makeUpSummary());
    }
  }

  void AbstractHVWidget::forceReprocess()
  {
    TRACE;
    _forceReProcessAll=true;
  }

  void AbstractHVWidget::setLimits()
  {
    TRACE;
    double max=-std::numeric_limits<double>::infinity();
    const QList<AbstractStation *>& list=tool()->stations();
    for(QList<AbstractStation *>::const_iterator it=list.begin();it!=list.end();++it) {
      double statMax=(*it)->resultMaxAmplitude();
      if(statMax>max) max=statMax;
    }
    if(max>-std::numeric_limits<double>::infinity()) {
      _winResults->setLimits(max);
    }
  }

  AbstractParameters * AbstractHVWidget::parameters(AbstractParameters * param) const
  {
    TRACE;
    if(!param) {
      param=new HVParameters;
    }
    getParameters(*static_cast<HVParameters *>(param));
    return param;
  }

  void AbstractHVWidget::setParameters(const AbstractParameters * param)
  {
    TRACE;
    setParameters(*static_cast<const HVParameters *>(param));
  }

  void AbstractHVWidget::loadWindows(QStringList fileNames)
  {
    TRACE;
    if(fileNames.isEmpty()) {
      fileNames=Message::getOpenFileNames(tr("Loading windows in log file(s)"), tr("Log file (*.log)"));
    }
    LayerLocker ll(timeWindowLayer());
    tool()->loadWindows(fileNames);
    procParamChanged();
    updateNofWindows();
  }

  void AbstractHVWidget::setCurrentDisplayStation()
  {
    TRACE;
    int stat=currentDisplayStation->currentIndex() - 1;
    if(signalLayer()) {
      if(stat==-1) {
        signalLayer()->graph()->yAxis()->setRange(0.5, _tool->subPool()->count()+0.5);
      } else {
        AbstractStation * s=tool()->stations().at(stat);
        // Find min and max index of s in _subpool
        int n=_tool->subPool()->count();
        int i=0;
        while(i<n && !s->originalSignals()->contains(_tool->subPool()->at(i))) {
          i++;
        }
        int minIndex=i;
        i++;
        while(i<n && s->originalSignals()->contains(_tool->subPool()->at(i))) {
          i++;
        }
        int maxIndex=i;
        signalLayer()->graph()->yAxis()->setRange(minIndex+0.5, maxIndex+0.5);
      }
      signalLayer()->graph()->deepUpdate();
    }
    updateNofWindows();
  }

  int AbstractHVWidget::countTimeWindows() const
  {
    int winCount=0;
    const QList<AbstractStation *>& list=tool()->stations();
    for(QList<AbstractStation *>::const_iterator it=list.begin();it!=list.end();++it) {
      winCount+=(*it)->windowCount();
    }
    return winCount;
  }

  void AbstractHVWidget::updateNofWindows()
  {
    TRACE;
    int stat=currentDisplayStation->currentIndex()-1;
    if(stat==-1) {
      nofWindows->display(countTimeWindows());
    } else {
      nofWindows->display(tool()->stations().at(stat)->windowCount());
    }
  }

  void AbstractHVWidget::updateSummary()
  {
    TRACE;
    if(_summary) {
      _summary->setStations(tool()->stations());
    }
  }

  void AbstractHVWidget::removeHorizontalComponents()
  {
    TRACE;
    delete squaredAverage;
    delete horizontalEnergy;
    delete azimuth;
    delete azimuthValue;
    squaredAverage=nullptr;
    horizontalEnergy=nullptr;
    azimuth=nullptr;
    azimuthValue=nullptr;
    if(!rotationStepEdit) {
      delete hComponentsGroup;
      hComponentsGroup=nullptr;
    }
  }

  void AbstractHVWidget::removeRotateStep()
  {
    TRACE;
    delete rotationStepLabel;
    delete rotationStepEdit;
    rotationStepLabel=nullptr;
    rotationStepEdit=nullptr;
    if(!squaredAverage) {
      delete hComponentsGroup;
      hComponentsGroup=nullptr;
    }
  }

  void AbstractHVWidget::on_azimuth_toggled()
  {
    TRACE;
    if(hComponentsGroup) {
      azimuthValue->setEnabled(azimuth->isChecked());
    }
  }

  void AbstractHVWidget::winParamChanged()
  {
    TRACE;
    setWinParamChanged(true);
  }

  void AbstractHVWidget::setWinParamChanged(bool c)
  {
    TRACE;
    selectBut->setText(c ? tr("Select*") : tr("Select"));
  }

  void AbstractHVWidget::procParamChanged()
  {
    TRACE;
    QFont f(startBut->font());
    f.setBold(true);
    startBut->setFont(f);
    forceReprocess();
  }

  void AbstractHVWidget::on_doHighPass_toggled()
  {
    TRACE;
    highPassFrequency->setEnabled(doHighPass->isChecked());
    procParamChanged();
  }

  void AbstractHVWidget::on_makeUpResultsBrowse_clicked()
  {
    TRACE;
    QString s=Message::getOpenFileName(tr("Make-up for results"), tr("Sheet make-up (*.mkup)"));
    if(s.length()>0) makeUpResults->setText(s);
  }

  void AbstractHVWidget::on_makeUpSummaryBrowse_clicked()
  {
    TRACE;
    QString s=Message::getOpenFileName(tr("Make-up for summary"), tr("Sheet make-up (*.mkup)"));
    if(s.length()>0) makeUpSummary->setText(s);
  }

  void AbstractHVWidget::on_useMakeUpResults_toggled()
  {
    TRACE;
    bool b=useMakeUpResults->isChecked();
    makeUpResults->setEnabled(b);
    makeUpResultsBrowse->setEnabled(b);
  }

  void AbstractHVWidget::on_useMakeUpSummary_toggled()
  {
    TRACE;
    bool b=useMakeUpSummary->isChecked();
    makeUpSummary->setEnabled(b);
    makeUpSummaryBrowse->setEnabled(b);
  }

  void AbstractHVWidget::updateParameters()
  {
    HVParameters param;
    getParameters(param);
    tool()->setParameters(param);
  }

  void AbstractHVWidget::setParameters(const HVParameters& param)
  {
    TRACE;
    makeUp->setChecked(param.doMakeUp());
    if(param.makeUpResults().isEmpty()) {
      useMakeUpResults->setChecked(false);
    } else {
      useMakeUpResults->setChecked(true);
      makeUpResults->setText(param.makeUpResults());
    }
    if(param.makeUpSummary().isEmpty()) {
      useMakeUpSummary->setChecked(false);
    } else {
      useMakeUpSummary->setChecked(true);
      makeUpSummary->setText(param.makeUpSummary());
    }
    nPlotsPerLineResults->setValue(param.plotCountPerLineResults());
    pageHeightResults->setValue(param.pageHeightResults());

    timeLimits->setParameters(param.timeRange());
    winParam->setParameters(param.windowing());
    sampling->setParameters(param.sampling());
    smoothing->setParameters(param.smoothing());
    tapering->setParameters(param.tapering());
    if(hComponentsGroup) {
      if(squaredAverage) {
        switch(param.horizontal()) {
        case HVParameters::Energy:
          horizontalEnergy->setChecked(true);
          break;
        case HVParameters::Azimuth:
          azimuth->setChecked(true);
          break;
        case HVParameters::Squared:
          squaredAverage->setChecked(true);
          break;
        }
        azimuthValue->setValue(param.horizontalAzimuth());
      }
      if(rotationStepEdit) {
        rotationStepEdit->setValue(Angle::radiansToDegrees(param.rotationStep()));
      }
    }
    if(param.highPassFrequency()>0.0) {
      doHighPass->setChecked(true);
      highPassFrequency->setValue(param.highPassFrequency());
    } else {
      doHighPass->setChecked(false);
    }
  }

  void AbstractHVWidget::getParameters(HVParameters& param) const
  {
    TRACE;
    param.setDoMakeUp(makeUp->isChecked());
    if(useMakeUpResults->isChecked()) {
      param.setMakeUpResults(makeUpResults->text());
    }
    if(useMakeUpSummary->isChecked()) {
      param.setMakeUpSummary(makeUpSummary->text());
    }
    param.setPlotCountPerLineResults(nPlotsPerLineResults->value());
    param.setPageHeightResults(pageHeightResults->value());

    timeLimits->getParameters(param.timeRange());
    winParam->getParameters(param.windowing());
    sampling->getParameters(param.sampling());
    smoothing->getParameters(param.smoothing());
    tapering->getParameters(param.tapering());
    if(hComponentsGroup) {
      if(squaredAverage) {
        if(horizontalEnergy->isChecked()) {
          param.setHorizontal(HVParameters::Energy);
        } else if(azimuth->isChecked()) {
          param.setHorizontal(HVParameters::Azimuth);
          param.setHorizontalAzimuth(azimuthValue->value());
        } else {
          param.setHorizontal(HVParameters::Squared);
        }
      }
      if(rotationStepEdit) {
        param.setRotationStep(Angle::degreesToRadians(rotationStepEdit->value()));
      }
    }
    if(doHighPass->isChecked()) {
      param.setHighPassFrequency(highPassFrequency->value());
    }
    param.setCommonTimeWindows(commonTimeWindows->isChecked());
  }

} // namespace HVGui
