/***************************************************************************
**
**  This file is part of GeopsyCore.
**
**  GeopsyCore 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.
**
**  GeopsyCore 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: 2003-12-19
**  Copyright: 2003-2019
**    Marc Wathelet
**    Marc Wathelet (ULg, Liège, Belgium)
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#ifndef WINDOWINGPARAMETERS_H
#define WINDOWINGPARAMETERS_H

#include <QGpCoreTools.h>

#include "GeopsyCoreDLLExport.h"
#include "FilterParameters.h"

namespace GeopsyCore {

class GEOPSYCORE_EXPORT WindowingParameters: public AbstractParameters
{
public:
  WindowingParameters();
  WindowingParameters(const WindowingParameters& o);
  ~WindowingParameters();

  void operator=(const WindowingParameters& o);

  virtual AbstractParameters * clone() const {return new WindowingParameters(*this);}

  struct ShortLongTermAverage
  {
    bool enabled;
    double shortLength;
    double longLength;
    double minimumThreshold;
    double maximumThreshold;
  };

  void setComponentCount(int n);
  int componentCount() const {return _componentCount;}

  void setStationCount(int n);
  int stationCount() const {return _stationCount;}

  void setRawComponent(int comp, bool b) {ASSERT(comp<_componentCount); _rawComponent[comp]=b;}
  void setFilterComponent(int comp, bool b) {ASSERT(comp<_componentCount); _filterComponent[comp]=b;}
  void setRawStation(int stat, bool b) {ASSERT(stat<_stationCount); _rawStation[stat]=b;}
  void setFilterStation(int stat, bool b) {ASSERT(stat<_stationCount); _filterStation[stat]=b;}

  bool rawComponent(int comp) const {return comp<_componentCount ? _rawComponent[comp] : true;}
  bool filterComponent(int comp) const {return comp<_componentCount ? _filterComponent[comp] : true;}
  bool rawStation(int stat) const {return stat<_stationCount ? _rawStation[stat] : true;}
  bool filterStation(int stat) const {return stat<_stationCount ? _filterStation[stat] : true;}

  enum LengthType {Exactly, AtLeast, FrequencyDependent};
  void setLength(double tmin, double tmax);
  void setLength(double t);
  void setPeriodCount(double n);
  bool setLengthType(const QString& l);
  LengthType lengthType() const {return _lengthType;}
  QString lengthTypeString() const;

  double minimumLength(double frequency) const;
  double maximumLength(double frequency) const;
  double periodCount() const {return _periodCount;}

  bool powerOfTwo() const {return _powerOfTwo;}
  void setPowerOfTwo(bool p2) {_powerOfTwo=p2;}

  void setMaximumWindowCount(int n) {_maximumWindowCount=n;}
  int maximumWindowCount() const {return _maximumWindowCount;}

  double overlap() const {return _overlap>0.0 ? _overlap : 0.0;}
  void setOverlap(double o) {_overlap=o;}

  enum SampleThreshold {NoSampleThreshold, RelativeSampleThreshold, AbsoluteSampleThreshold};

  void setBadSampleThresholdType(SampleThreshold t) {_badSampleThresholdType=t;}
  bool setBadSampleThresholdType(const QString& t);
  SampleThreshold badSampleThresholdType() const {return _badSampleThresholdType;}
  QString badSampleThresholdTypeString() const;

  double badSampleThreshold() const {return _badSampleThresholdValue;}
  void setBadSampleThreshold(double b) {_badSampleThresholdValue=b;}

  double badSampleTolerance() const {return _badSampleTolerance;}
  void setBadSampleTolerance(double b) {_badSampleTolerance=b;}

  double badSampleGap() const {return _badSampleGap;}
  void setBadSampleGap(double g) {_badSampleGap=g;}

  const ShortLongTermAverage& rawSignalAntiTrigger() const {return _rawSignalAntiTrigger;}
  void setRawSignalAntiTrigger(const ShortLongTermAverage& r) {_rawSignalAntiTrigger=r;}

  const ShortLongTermAverage& filterSignalAntiTrigger() const {return _filterSignalAntiTrigger;}
  void setFilterSignalAntiTrigger(const ShortLongTermAverage& f) {_filterSignalAntiTrigger=f;}

  const FilterParameters& filter() const {return _filter;}
  FilterParameters& filter() {return _filter;}

  bool seismicEventTrigger() const {return _seismicEventTrigger;}
  void setSeismicEventTrigger(bool e) {_seismicEventTrigger=e;}

  double seismicEventDelay() const {return _seismicEventDelay;}
  void setSeismicEventDelay(double d) {_seismicEventDelay=d;}

  bool isValid();
  void printDebug();

  virtual QString toString(PARAMETERS_TOSTRING_ARGS_DECL) const;
  virtual void collectKeywords(PARAMETERS_COLLECTKEYWORDS_ARGS);
  virtual void setVersion(PARAMETERS_SETVERSION_ARGS);
  virtual int totalKeywordCount(PARAMETERS_TOTALKEYWORDCOUNT_ARGS) const;
protected:
  virtual int keywordCount(PARAMETERS_KEYWORDCOUNT_ARGS) const;
  virtual bool setValue(PARAMETERS_SETVALUE_ARGS);
private:
  void copyBasicValues(const WindowingParameters& o);
  static bool * copyComponentStation(bool * v, int count);

  int _stationCount;
  int _componentCount;
  LengthType _lengthType;
  SampleThreshold _badSampleThresholdType;
  bool _powerOfTwo, _seismicEventTrigger;
  int _maximumWindowCount;

  bool * _rawComponent;
  bool * _filterComponent;
  bool * _rawStation;
  bool * _filterStation;

  double _minimumLength;
  double _maximumLength;
  double _periodCount;

  double _overlap;
  double _badSampleThresholdValue;
  double _badSampleTolerance;
  double _badSampleGap;

  double _seismicEventDelay;

  ShortLongTermAverage _rawSignalAntiTrigger;
  ShortLongTermAverage _filterSignalAntiTrigger;
  FilterParameters _filter;
};

} // namespace GeopsyCore

#endif // WINDOWINGPARAMETERS_H

