/***************************************************************************
**
**  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)
**
***************************************************************************/

#include "SignalHeaderObject.h"

namespace GeopsyCore {

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

    Full description of class still missing
  */

  /*!
    Description of constructor still missing
  */
  SignalHeaderObject::SignalHeaderObject(Signal *sig, QObject * parent)
    : QObject(parent)
  {
    TRACE;
    _signal=sig;
  }

  void SignalHeaderObject::setAmplitudeUnit(const QString& v)
  {
    TRACE;
    Signal * sig=thisSignal();
    emit(beginSignalChange(sig));
    sig->setAmplitudeUnit(Signal::standardAmplitudeUnit(v));
    sig->setHeaderModified(true);
    emit(endSignalChange(sig));
  }

  void SignalHeaderObject::setComponent(const QString& v)
  {
    TRACE;
    Signal * sig=thisSignal();
    emit(beginSignalChange(sig));
    sig->setComponent(Signal::standardComponent(v));
    sig->setHeaderModified(true);
    emit(endSignalChange(sig));
  }

  void SignalHeaderObject::setCountPerVolt(double v)
  {
    TRACE;
    Signal * sig=thisSignal();
    emit(beginSignalChange(sig));
    sig->setCountPerVolt(v);
    sig->setHeaderModified(true);
    emit(endSignalChange(sig));
  }

  void SignalHeaderObject::setSamplingPeriod(double v)
  {
    TRACE;
    Signal * sig=thisSignal();
    emit(beginSignalChange(sig));
    sig->setSamplingPeriod(v);
    sig->setHeaderModified(true);
    emit(endSignalChange(sig));
  }

  void SignalHeaderObject::setDuration(const QString& v)
  {
    TRACE;
    Signal * sig=thisSignal();
    bool ok=true;
    double d=Number::durationToSeconds(v, ok);
    if(ok) {
      emit(beginSignalChange(sig));
      sig->setSamplingPeriod(d/static_cast<double>(sig->nSamples()));
      sig->setHeaderModified(true);
      emit(endSignalChange(sig));
    }
  }

  void SignalHeaderObject::setEndTime(const QString& v)
  {
    TRACE;
    Signal * sig=thisSignal();
    DateTime e;
    if(e.fromString(v, ScriptContext::timeFormat)) {
      emit(beginSignalChange(sig));
      e.addSeconds(-sig->duration());
      sig->setStartTime(e);
      sig->setHeaderModified(true);
      emit(endSignalChange(sig));
    }
  }

  void SignalHeaderObject::setName(const QString& v)
  {
    TRACE;
    Signal * sig=thisSignal();
    emit(beginSignalChange(sig));
    sig->setName(v);
    sig->setHeaderModified(true);
    emit(endSignalChange(sig));
  }

  void SignalHeaderObject::setUtmZone(const QString& v)
  {
    TRACE;
    Signal * sig=thisSignal();
    emit(beginSignalChange(sig));
    UtmZone z;
    z.fromString(v);
    sig->setUtmZone(z);
    sig->setHeaderModified(true);
    emit(endSignalChange(sig));
  }

  void SignalHeaderObject::setReceiverX(double v)
  {
    TRACE;
    Signal * sig=thisSignal();
    Point p=sig->receiver();
    p.setX(v);
    emit(beginSignalChange(sig));
    sig->setReceiver(p);
    sig->setHeaderModified(true);
    emit(endSignalChange(sig));
  }

  void SignalHeaderObject::setReceiverY(double v)
  {
    TRACE;
    Signal * sig=thisSignal();
    Point p=sig->receiver();
    p.setY(v);
    emit(beginSignalChange(sig));
    sig->setReceiver(p);
    sig->setHeaderModified(true);
    emit(endSignalChange(sig));
  }

  void SignalHeaderObject::setReceiverZ(double v)
  {
    TRACE;
    Signal * sig=thisSignal();
    Point p=sig->receiver();
    p.setZ(v);
    emit(beginSignalChange(sig));
    sig->setReceiver(p);
    sig->setHeaderModified(true);
    emit(endSignalChange(sig));
  }

  void SignalHeaderObject::setSamplingFrequency(double v)
  {
    TRACE;
    Signal * sig=thisSignal();
    emit(beginSignalChange(sig));
    sig->setSamplingFrequency(v);
    sig->setHeaderModified(true);
    emit(endSignalChange(sig));
  }

  void SignalHeaderObject::setStartTime(const QString& v)
  {
    TRACE;
    Signal * sig=thisSignal();
    DateTime s;
    if(s.fromString(v, ScriptContext::timeFormat)) {
      emit(beginSignalChange(sig));
      sig->setStartTime(s);
      sig->setHeaderModified(true);
    }
    emit(endSignalChange(sig));
  }

  void SignalHeaderObject::addSeconds(double dt)
  {
    TRACE;
    Signal * sig=thisSignal();
    DateTime s=sig->startTime();
    s.addSeconds(dt);
    emit(beginSignalChange(sig));
    sig->setStartTime(s);
    sig->setHeaderModified(true);
    emit(endSignalChange(sig));
  }

  void SignalHeaderObject::setUnitPerVolt(double v)
  {
    TRACE;
    Signal * sig=thisSignal();
    emit(beginSignalChange(sig));
    sig->setUnitPerVolt(v);
    sig->setHeaderModified(true);
    emit(endSignalChange(sig));
  }

  void SignalHeaderObject::setVoltPerCount(double v)
  {
    TRACE;
    Signal * sig=thisSignal();
    emit(beginSignalChange(sig));
    sig->setVoltPerCount(v);
    sig->setHeaderModified(true);
    emit(endSignalChange(sig));
  }

  void SignalHeaderObject::setVoltPerUnit(double v)
  {
    TRACE;
    Signal * sig=thisSignal();
    emit(beginSignalChange(sig));
    sig->setVoltPerUnit(v);
    sig->setHeaderModified(true);
    emit(endSignalChange(sig));
  }

  QString SignalHeaderObject::fileFormat() const
  {
    TRACE;
    Signal * sig=thisSignal();
    if(sig->file()) {
      return sig->file()->format().name();
    } else {
      return tr("### Temporary signal ###");
    }
  }

  QString SignalHeaderObject::fileName() const
  {
    TRACE;
    Signal * sig=thisSignal();
    if(sig->file()) {
      return sig->file()->name();
    } else {
      return tr("### Temporary signal ###");
    }
  }

  quint32 SignalHeaderObject::crc32() const
  {
    TRACE;
    Signal * sig=thisSignal();
    if(sig->file()) {
      return sig->file()->crc32();
    } else {
      return 0;
    }
  }

  QString SignalHeaderObject::shortFileName() const
  {
    TRACE;
    Signal * sig=thisSignal();
    if(sig->file()) {
      return sig->file()->shortName();
    } else {
      return tr("### Temporary signal ###");
    }
  }

  // Currently no way to provide dynamic properties with correct binding between JS and C++
  // We provide static properties for common metadata

  void SignalHeaderObject::setComments(const QString& v)
  {
    TRACE;
    Signal * sig=thisSignal();
    emit(beginSignalChange(sig));
    Comments& md=sig->beginModifyMetaData<Comments>();
    md.setValue(v);
    sig->endModifyMetaData(md);
    emit(endSignalChange(sig));
  }

  void SignalHeaderObject::setTimePick(const QString& name, const QString& time)
  {
    TRACE;
    Signal * sig=thisSignal();
    DateTime dt;
    if(dt.fromString(time, ScriptContext::timeFormat)) {
      emit(beginSignalChange(sig));
      TimePick& md=sig->beginModifyMetaData<TimePick>();
      md.setValue(name, dt);
      sig->endModifyMetaData(md);
      emit(endSignalChange(sig));
    }
  }

  QString SignalHeaderObject::timePick(const QString& name) const
  {
    return thisSignal()->metaData<TimePick>().value(name).toString(ScriptContext::timeFormat);
  }

} // namespace GeopsyCore
