/***************************************************************************
**
**  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: 2020-02-18
**  Copyright: 2020
**    Marc Wathelet (ISTerre, Grenoble, France)
**
***************************************************************************/

#ifndef ABSTRACTSTATION_H
#define ABSTRACTSTATION_H

#include <GeopsyCore.h>

#include "HVCoreDLLExport.h"

namespace HVCore {

  class AbstractResults;
  class HVParameters;

  class HVCORE_EXPORT AbstractStation : public QObject
  {
    Q_OBJECT
  public:
    AbstractStation(StationProcessSignals * sig);
    ~AbstractStation();

    int indexOf(AbstractResults * c) {return _results.indexOf(c);}

    virtual StationProcessSignals * createProcessSignals()=0;
    virtual void process(StationProcessSignals * proc, int windowIndex, const HVParameters * param) const=0;
    virtual void setStatistics();
    virtual void setPeaks();
    virtual bool save(QDir outputDir, const HVParameters& param);
    virtual bool save(int index, QDir outputDir, const HVParameters& param)=0;

    void addResults();
    int resultCount() const {return _results.count();}
    void clearResults();
    void initResults(int windowCount, const HVParameters& param);
    virtual const AbstractResults * results(int index) const {return index<resultCount() ? _results[index] : nullptr;}
    virtual AbstractResults * results(int index) {return index<resultCount() ? _results[index] : nullptr;}
    virtual double resultMaxAmplitude() const;
    void setHighPassFilter(double frequency) {_signals->setHighPassFilter(frequency);}

    virtual QString name(int index) const=0;
    virtual QString name() const=0;
    QString shortFileName() const;
    const StationSignals * originalSignals() const {return _signals->originalSignals();}
    int nComponents() const {return _signals->nComponents();}

    SparseKeepSignal * keep(const TimeRange& r, const WindowingParameters& param, int stationIndex) const;
    SparseTimeRange timeRange(const TimeRange& r) const {return _signals->originalSignals()->timeRange(r);}
    void setSampling(SparseKeepSignal * keep) const {_signals->originalSignals()->setSampling(keep);}
    void setKeep(SparseKeepSignal * keep, const WindowingParameters& param, int stationIndex) const {_signals->originalSignals()->setKeep(keep,param,stationIndex);}

    void addWindows(const TimeRange& r, const WindowingParameters& param, const SparseKeepSignal& keep);
    bool addWindows(QTextStream& s, const QString& beginPattern, const QString& endPattern);
    void removeWindows(const TimeRange& r);
    void clearAllWindows();
    void clearGrayWindows();
    void setWindowColors();
    bool hasGrayWindows();
    void inverseWindows(const TimeRange& r, const WindowingParameters& param, const SparseKeepSignal& keep);

    void setWindowsChanged(bool c) {_windowsChanged=c;}
    bool isWindowsChanged() {return _windowsChanged;}

    TimeRange windowRange() const {return _timeWindows.timeRange();}
    int windowCount() const {return _timeWindows.count();}
    TimeWindowList& windows() {return _timeWindows;}
    const TimeWindow& windowAt(int index) const {return _timeWindows.at(index);}

    QString windowingLog() const {return _winLog;}
    void clearWindowingLog() {_winLog.clear();}
    void addWindowingLog(const QString& t) {_winLog+=t;}
    QString log(const HVParameters& param) const;

    SignalDatabase * database() const;
  public slots:
    void changeColors(const QVector<int>* selCurves, const Color &col);
  signals:
    void windowsChanged();
  protected:
    virtual AbstractResults * createResults()=0;

    StationProcessSignals * _signals;
    QVector<AbstractResults *> _results;
  private:
    SparseKeepSignal * _keep;
    TimeWindowList _timeWindows;

    bool _windowsChanged;
    QString _winLog;
  };

} // namespace HVCore

#endif // ABSTRACTSTATION_H

