/***************************************************************************
**
**  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: 2011-10-24
**  Copyright: 2011-2019
**    Marc Wathelet (ISTerre, Grenoble, France)
**
***************************************************************************/

#ifndef SIGNALHEADEROBJECT_H
#define SIGNALHEADEROBJECT_H

#include "GeoSignal.h"
#include "Comments.h"
#include "TimePick.h"

namespace GeopsyCore {

  class SignalHeaderObject: public QObject
  {
    Q_OBJECT
    Q_PROPERTY(QString amplitudeUnit READ amplitudeUnit WRITE setAmplitudeUnit)
    Q_PROPERTY(double averageAmplitude READ averageAmplitude)
    Q_PROPERTY(double countPerUnit READ countPerUnit)
    Q_PROPERTY(double countPerVolt READ countPerVolt WRITE setCountPerVolt)
    Q_PROPERTY(QString component READ component WRITE setComponent)
    Q_PROPERTY(double samplingPeriod READ samplingPeriod WRITE setSamplingPeriod)
    Q_PROPERTY(QString duration READ duration WRITE setDuration)
    Q_PROPERTY(QString endTime READ endTime WRITE setEndTime)
    Q_PROPERTY(QString fileFormat READ fileFormat)
    Q_PROPERTY(QString fileName READ fileName)
    Q_PROPERTY(bool headerModified READ headerModified)
    Q_PROPERTY(int id READ id)
    Q_PROPERTY(bool isOriginalFile READ isOriginalFile)
    Q_PROPERTY(double maximumAmplitude READ maximumAmplitude)
    Q_PROPERTY(QString name READ name WRITE setName)
    Q_PROPERTY(int nSamples READ nSamples)
    Q_PROPERTY(int numberInFile READ numberInFile)
    Q_PROPERTY(QString pointer READ pointer)
    Q_PROPERTY(QString utmZone READ utmZone WRITE setUtmZone)
    Q_PROPERTY(double receiverX READ receiverX WRITE setReceiverX)
    Q_PROPERTY(double receiverY READ receiverY WRITE setReceiverY)
    Q_PROPERTY(double receiverZ READ receiverZ WRITE setReceiverZ)
    Q_PROPERTY(double samplingFrequency READ samplingFrequency WRITE setSamplingFrequency)
    Q_PROPERTY(int sampleSize READ sampleSize)
    Q_PROPERTY(QString shortFileName READ shortFileName)
    Q_PROPERTY(QString startTime READ startTime WRITE setStartTime)
    Q_PROPERTY(QString type READ type)
    Q_PROPERTY(double unitPerCount READ unitPerCount)
    Q_PROPERTY(double unitPerVolt READ unitPerVolt WRITE setUnitPerVolt)
    Q_PROPERTY(double voltPerCount READ voltPerCount WRITE setVoltPerCount)
    Q_PROPERTY(double voltPerUnit READ voltPerUnit WRITE setVoltPerUnit)

    Q_PROPERTY(QString comments READ comments WRITE setComments)
  public:
    SignalHeaderObject(Signal * sig, QObject * parent=nullptr);

    void setAmplitudeUnit(const QString& v);
    void setComponent(const QString& v);
    void setCountPerVolt(double v);
    void setSamplingPeriod(double v);
    void setDuration(const QString& v);
    void setEndTime(const QString& v);
    void setName(const QString& v);
    void setUtmZone(const QString& v);
    void setReceiverX(double v);
    void setReceiverY(double v);
    void setReceiverZ(double v);
    void setSamplingFrequency(double v);
    void setStartTime(const QString& v);
    void setUnitPerVolt(double v);
    void setVoltPerCount(double v);
    void setVoltPerUnit(double v);

    void setComments(const QString& v);

    QString amplitudeUnit() const {return thisSignal()->amplitudeUnitStandardName();}
    double averageAmplitude() const {return thisSignal()->averageAmplitude();}
    QString component() const {return thisSignal()->componentStandardName();}
    double countPerUnit() const {return thisSignal()->countPerUnit();}
    double countPerVolt() const {return thisSignal()->countPerVolt();}
    double samplingPeriod() const {return thisSignal()->samplingPeriod();}
    QString duration() const {return QString::number(thisSignal()->duration(), 'g', 20);}
    QString endTime() const {return thisSignal()->endTime().toString(ScriptContext::timeFormat);}
    QString fileFormat() const;
    QString fileName() const;
    quint32 crc32() const;
    bool headerModified() const {return thisSignal()->isHeaderModified();}
    int id() const {return thisSignal()->id();}
    bool isOriginalFile() const {return thisSignal()->isOriginalFile();}
    double maximumAmplitude() const {return thisSignal()->maximumAmplitude();}
    QString name() const {return thisSignal()->name();}
    int nSamples() const {return thisSignal()->nSamples();}
    int numberInFile() const {return thisSignal()->numberInFile();}
    QString pointer() const {return QString::number(reinterpret_cast<qint64>(thisSignal()), 16);}
    QString utmZone() const {return thisSignal()->utmZone().toString();}
    double receiverX() const {return thisSignal()->receiver().x();}
    double receiverY() const {return thisSignal()->receiver().y();}
    double receiverZ() const {return thisSignal()->receiver().z();}
    double samplingFrequency() const {return thisSignal()->samplingFrequency();}
    int sampleSize() const {return qRound(thisSignal()->dataSizeMb());}
    QString shortFileName() const;
    QString startTime() const {return thisSignal()->startTime().toString(ScriptContext::timeFormat);}
    QString type() const {return Signal::typeString(thisSignal()->type());}
    double unitPerCount() const {return thisSignal()->unitPerCount();}
    double unitPerVolt() const {return thisSignal()->unitPerVolt();}
    double voltPerCount() const {return thisSignal()->voltPerCount();}
    double voltPerUnit() const {return thisSignal()->voltPerUnit();}

    QString comments() const {return thisSignal()->metaData<Comments>().value();}
  public slots:
    QString timePick(const QString& name) const;
    void setTimePick(const QString& name, const QString& time);

    void addSeconds(double dt);
  signals:
    void beginSignalChange(Signal * sig);
    void endSignalChange(Signal * sig);
  private:
    inline Signal * thisSignal() const;

    Signal * _signal;
  };

  inline Signal * SignalHeaderObject::thisSignal() const
  {
    //return qscriptvalue_cast<Signal *>(thisObject().data());
    return _signal;
  }

} // namespace GeopsyCore

Q_DECLARE_METATYPE(GeopsyCore::Signal *)

#endif // SIGNALHEADEROBJECT_H
