/***************************************************************************
**
**  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: 2009-03-26
**  Copyright: 2009-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#ifndef SIGNALPROCESS_H
#define SIGNALPROCESS_H

#include "GeopsyCoreDLLExport.h"
#include "RotateParameters.h"
#include "MorletParameters.h"
#include "SubSignalPool.h"

namespace GeopsyCore {

  class GEOPSYCORE_EXPORT SignalProcess : public QObject
  {
    Q_OBJECT
  public:
    SignalProcess(QObject * parent=nullptr);
    ~SignalProcess();

    void setCurrentSubPool(SubSignalPool * subPool);
    bool run(const QString& script);

    void clear();

    void addToHistory(const QString& s);
    const QString& history() const {return _history;}

    int stepCount() const {return _steps.count();}
    QStringList steps() const;
    int indexOfStep(const QString& tag) const;
    void saveStep(const QString& tag);
    void restoreStep(int index);

    void fastFourierTransform(DoubleSignal::SignalType st);
    bool exportFile(const QString& filePath, bool useOriginalBaseName=false,
                    const SignalFileFormat& format=SignalFileFormat::Unknown,
                    int maximumSignalsPerFile=0, const QString& pickName=QString());
    QVariant header(int signalIndex, const MetaDataIndex& dataIndex);
    void setHeader(int signalIndex, const MetaDataIndex& dataIndex, const QVariant& value);
    int signalCount();
    void selectSignals(int startIndex, int endIndex, QString tag=QString());

    void removeTrend();
    void subtractValue(double val);
    void subtractSignal(int index);
    void subtractSignals(const QString& groupName);
    void multiply(double val);
    void filter(const FilterParameters& param);
    void whiten();
    void agc(double width);
    void stddevClip(double factor);
    void shift(double dt);
    void overSample(double factor);
    void taper(TimeRangeParameters& range, const WindowFunctionParameters& param);
    void cut(TimeRangeParameters& param);
    bool merge();
    bool mergeStations();
    void decimateAmplitude(int maxCount, double maxRef);
    void decimateTime(int factor);
    void waveletTransform(const MorletParameters& param);
    void stalta(double tsta, double tlta);
    void discreteFourierTransform();
    void rotateComponents(const RotateParameters& param);
    void correlations(double maxDelay, int referenceIndex=-1);
    void normalizedCorrelations(double maxDelay, int referenceIndex=-1);
    void convolution(int referenceIndex);
    void removeInstrumentalResponse(const InstrumentalResponse& sensor);
  private:
    void newStep();
    void restoreStepCore(int index);

    void fastFourierTransformCore(DoubleSignal::SignalType st);
    bool exportFileCore(const QString& filePath, bool useOriginalBaseName,
                        const SignalFileFormat& format, int maximumSignalsPerFile,
                        const QString& pickName);
    void setHeaderCore(int signalIndex, const MetaDataIndex& dataIndex, const QVariant& value);

    void removeTrendCore();
    void subtractValueCore(double val);
    void subtractSignalCore(int index);
    void subtractSignalsCore(const QString& groupName);
    void multiplyCore(double val);
    void filterCore(const FilterParameters& param);
    void whitenCore();
    void agcCore(double width);
    void stddevClipCore(double factor);
    void shiftCore(double dt);
    void overSampleCore(double factor);
    void taperCore(TimeRangeParameters& range, const WindowFunctionParameters& param);
    void cutCore(TimeRangeParameters& param);
    bool mergeCore();
    bool mergeStationsCore();
    void decimateAmplitudeCore(int maxCount, double maxRef);
    void decimateTimeCore(int factor);
    void waveletTransformCore(const MorletParameters& param);
    void staltaCore(double tsta, double tlta);
    void discreteFourierTransformCore();
    void rotateComponentsCore(const RotateParameters& param);
    void correlationsCore(double maxDelay, int referenceIndex);
    void normalizedCorrelationsCore(double maxDelay, int referenceIndex);
    void convolutionCore(int referenceIndex);
    void removeInstrumentalResponseCore(const InstrumentalResponse& sensor);

    SubSignalPool * _current;
    SubSignalPool * _selected;
    QVector<SubSignalPool> _steps;
    QString _history;
  };

} // namespace GeopsyCore

#endif // SIGNALPROCESS_H
