/***************************************************************************
**
**  This file is part of HVCore.
**
**  HVCore 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.
**
**  HVCore 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: 2012-02-03
**  Copyright: 2012-2019
**    Marc Wathelet (ISTerre, Grenoble, France)
**
***************************************************************************/

#include "HVParameters.h"

namespace HVCore {

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

    Full description of class still missing
  */

  /*!
    Description of constructor still missing
  */
  HVParameters::HVParameters()
    : AbstractParameters()
  {
    TRACE;
    _windowing.setLength(50.0);  // Default 50 s windows
    _sampling.setRange(0.2, 20.0);
    _sampling.setType(SamplingParameters::Log);
    _sampling.setStep(1.025);

    _smoothing.setMethod(SmoothingParameters::Function);
    _smoothing.windowFunction().setShape(WindowFunctionParameters::KonnoOhmachi);
    _smoothing.setWidthType(SmoothingParameters::Log);
    _smoothing.setScaleType(SamplingParameters::Log);
    _smoothing.setWidth(0.2); // Correspond to b-exponent of approximately 40

    _commonTimeWindows=false;

    _highPassFrequency=0;
    _horizontal=Squared;
    _horizontalAzimuth=0.0;

    _doMakeUp=true;
    _plotCountPerLineResults=2;
    _pageHeightResults=29.7;

    _tapering.setShape(WindowFunctionParameters::Tukey);
    _tapering.setAlpha(0.1);

    _rotationStep=Angle::degreesToRadians(10.0);
  }

  /*!
    Description of constructor still missing
  */
  HVParameters::HVParameters(const HVParameters& o)
    : AbstractParameters(o),
      _timeRange(o._timeRange),
      _windowing(o._windowing),
      _sampling(o._sampling),
      _smoothing(o._smoothing),
      _tapering(o._tapering)

  {
    TRACE;
    _commonTimeWindows=o._commonTimeWindows;

    _highPassFrequency=o._highPassFrequency;
    _horizontal=o._horizontal;
    _horizontalAzimuth=o._horizontalAzimuth;

    _doMakeUp=o._doMakeUp;
    _makeUpResults=o._makeUpResults;
    _makeUpSummary=o._makeUpSummary;
    _plotCountPerLineResults=o._plotCountPerLineResults;
    _pageHeightResults=o._pageHeightResults;

    _rotationStep=o._rotationStep;
  }

  void HVParameters::setHorizontal(const QString& h)
  {
    TRACE;
    if(h.count()>0) {
      QString hl=h.toLower();
      switch(hl[0].unicode()) {
      case 'e':
        if(hl=="energy") {
          _horizontal=Energy;
        }
        break;
      case 'a':
        if(hl=="azimuth") {
          _horizontal=Azimuth;
        }
        break;
      case 's':
        if(hl=="squared") {
          _horizontal=Squared;
        }
        break;
      default:
        break;
      }
    }
  }

  QString HVParameters::horizontalString() const
  {
    TRACE;
    switch(_horizontal) {
    case Energy:
      break;
    case Azimuth:
      return "Azimuth";
    case Squared:
      return "Squared";
    }
    return "Energy";
  }

  int HVParameters::keywordCount(PARAMETERS_KEYWORDCOUNT_ARGS) const
  {
    return 11+AbstractParameters::keywordCount();
  }

  int HVParameters::totalKeywordCount(PARAMETERS_TOTALKEYWORDCOUNT_ARGS) const
  {
    return AbstractParameters::totalKeywordCount()+
        _timeRange.totalKeywordCount()+
        _windowing.totalKeywordCount()+
        _smoothing.totalKeywordCount()+
        _tapering.totalKeywordCount()+
        _sampling.totalKeywordCount();
  }

  void HVParameters::collectKeywords(PARAMETERS_COLLECTKEYWORDS_ARGS)
  {
    TRACE;
    int baseIndex=AbstractParameters::keywordCount();
    keywords.add(prefix+"DO_HIGH_PASS"+suffix, this, baseIndex);           // Kept for compatibility
    keywords.add(prefix+"HIGH_PASS_FREQUENCY"+suffix, this, baseIndex+1);
    keywords.add(prefix+"HORIZONTAL_COMPONENTS"+suffix, this, baseIndex+2);
    keywords.add(prefix+"HORIZONTAL_AZIMUTH"+suffix, this, baseIndex+3);
    keywords.add(prefix+"ROTATION_STEP"+suffix, this, baseIndex+4);
    keywords.add(prefix+"COMMON_TIME_WINDOWS"+suffix, this, baseIndex+5);
    keywords.add(prefix+"SIGNAL_FILE_NAME"+suffix, this, baseIndex+6);   // Kept for compatibility
    keywords.add(prefix+"MINIMUM"+suffix, this, baseIndex+7);            // Kept for compatibility
    keywords.add(prefix+"MAXIMUM"+suffix, this, baseIndex+8);            // Kept for compatibility
    keywords.add(prefix+"SAMPLES_NUMBER"+suffix, this, baseIndex+9);      // Kept for compatibility
    keywords.add(prefix+"SAMPLING_TYPE"+suffix, this, baseIndex+10);     // Kept for compatibility
    _timeRange.collectKeywords(keywords, prefix, suffix);
    _windowing.collectKeywords(keywords, prefix, suffix);
    _sampling.collectKeywords(keywords, prefix, "_FREQUENCY"+suffix);
    _tapering.collectKeywords(keywords, prefix, suffix);
    _smoothing.collectKeywords(keywords, prefix, suffix);
  }

  QString HVParameters::toString(PARAMETERS_TOSTRING_ARGS_IMPL) const
  {
    TRACE;
    QString log;
    log+=_timeRange.toString(prefix, suffix);
    log+=prefix+"COMMON_TIME_WINDOWS"+suffix+"="+(_commonTimeWindows ? "true" : "false")+"\n";
    log+=_windowing.toString(prefix, suffix);
    log+=_tapering.toString(prefix, suffix);
    log+=_smoothing.toString(prefix, suffix);
    log+=_sampling.toString(prefix, "_FREQUENCY"+suffix);
    log+=prefix+"HIGH_PASS_FREQUENCY"+suffix+"="+QString::number(_highPassFrequency)+"\n";
    log+="# Possible values for HORIZONTAL_COMPONENTS: Squared, Energy, Azimuth\n";
    log+=prefix+"HORIZONTAL_COMPONENTS"+suffix+"="+horizontalString()+"\n";
    log+="# HORIZONTAL_AZIMUTH is used only when HORIZONTAL_COMPONENTS==Azimuth\n";
    log+=prefix+"HORIZONTAL_AZIMUTH"+suffix+"="+QString::number(_horizontalAzimuth)+"\n";
    log+="# Used only for rotated output\n";
    log+=prefix+"ROTATION_STEP"+suffix+"="+QString::number(Angle::radiansToDegrees(_rotationStep))+"\n";
    return log;
  }

  bool HVParameters::setValue(PARAMETERS_SETVALUE_ARGS)
  {
    TRACE;
    bool ok=true;
    switch(index-AbstractParameters::keywordCount()) {
    case 0:
      obsoleteKeyword(keywords, 0);
      if(value=="false") {
        _highPassFrequency=0.0;
      }
      return _highPassFrequency>=0.0;
    case 1:
      _highPassFrequency=value.toDouble(&ok);
      return ok && _highPassFrequency>=0.0;
    case 2:
      setHorizontal(value);
      return true;
    case 3:
      _horizontalAzimuth=value.toDouble(&ok);
      return ok;
    case 4:
      _rotationStep=Angle::degreesToRadians(value.toDouble(&ok));
      return ok;
    case 5:
      _commonTimeWindows=(value=="true");
      return true;
    case 6:         // kept for compatibility
    case 7:         // kept for compatibility
    case 8:         // kept for compatibility
    case 9:         // kept for compatibility
    case 10:        // kept for compatibility
      obsoleteKeyword(keywords, index-AbstractParameters::keywordCount());
      return true;
    default:
      break;
    }
    return AbstractParameters::setValue(index, value, unit, keywords);
  }

} // namespace HVCore
