/***************************************************************************
**
**  This file is part of DinverDCCore.
**
**  DinverDCCore 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.
**
**  DinverDCCore 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: 2006-05-19
**  Copyright: 2006-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <QGpCoreTools.h>
#include "ModalStorageReader.h"

namespace DinverDCCore {

ModalStorageReader::ModalStorageReader(QDataStream& s)
{
  TRACE;
  s >> _nModes;
  _offsets.append(s.device()->pos());
}

bool ModalStorageReader::seek(QDataStream& s, int iMode)
{
  TRACE;
  if(iMode>=_nModes) return false;
  QIODevice& f=*s.device();
  if(iMode>=_offsets.count()) {
    f.seek(_offsets.last());
    int nf;
    while(_offsets.count()<=iMode) {
      s >> nf;
      qint64 o=_offsets.last()+4+nf*16;
      f.seek(o);
      _offsets.append(o);
    }
  } else {
    f.seek(_offsets.at(iMode));
  }
  return true;
}

/*!
  Compatibility with older reports: for Beta Release 2.0.0 from June 2006.
  If \a rayleigh is true only Rayleigh modes are considered, else only Love
*/
void ModalStorageReader::setBetaReleaseOffsets(QDataStream& s, bool rayleigh)
{
  TRACE;
  ASSERT(_offsets.count()==1); // only the first offset from the constructor must be there
  int nR;
  s >> nR; // number of Rayleigh modes
  if(nR<0) nR=0;
  _offsets.last()+=4; // Correct for nR
  if(rayleigh) {
    _nModes=nR; // Reduce the number of modes to Rayleigh only
  } else {
    // Skip all rayleigh modes
    seek(s, nR);
    // Remove all offsets except the last one (the first Love)
    qint64 o=_offsets.last();
    _offsets.clear();
    _offsets.append(o);
    _nModes -= nR; // Reduce the number of modes to Love only
  }
}

/*!
  pos() of data stream must point to the beginning of a curve
*/
void ModalStorageReader::toPlot(QDataStream& s, Point2D * points)
{
  TRACE;
  int nf;
  s >> nf;
  //qDebug ("%i",nf);
  double freq,value;
  for(int i=0; i<nf; i++) {
    s >> freq;
    s >> value;
    Point2D& p=points[i];
    //qDebug ("%lg %lg",freq, value);
    p.setX(freq);
    p.setY(value);
  }
}

/*!
  pos() of data stream must point to the beginning of a curve
*/
void ModalStorageReader::toAbsolutePlot(QDataStream& s, Point2D * points)
{
  TRACE;
  int nf;
  s >> nf;
  //qDebug ("%i",nf);
  double freq,value;
  for(int i=0; i<nf; i++) {
    s >> freq;
    s >> value;
    Point2D& p=points[i];
    //qDebug ("%lg %lg",freq, value);
    p.setX(freq);
    p.setY(fabs(value));
  }
}

void ModalStorageReader::toStream(QDataStream& s, QTextStream& sOut)
{
  TRACE;
  int nf;
  s >> nf;
  double freq,value;
  static const QString fmt("%1 %2\n");
  for(int i=0;i<nf;i++) {
    s >> freq >> value;
    sOut << fmt.arg(freq, 20, 'g', 15).arg(value, 20, 'g', 15);
  }
  sOut << flush;
}

void ModalStorageReader::toAbsoluteStream(QDataStream& s, QTextStream& sOut)
{
  TRACE;
  int nf;
  s >> nf;
  double freq,value;
  static const QString fmt("%1 %2\n");
  for(int i=0;i<nf;i++) {
    s >> freq >> value;
    sOut << fmt.arg(freq, 20, 'g', 15).arg(fabs(value), 20, 'g', 15);
  }
  sOut << flush;
}

void ModalStorageReader::toStream(QDataStream& s, QDataStream& sOut)
{
  TRACE;
  int nf;
  s >> nf;
  sOut << nf;
  double freq,value;
  for(int i=0;i<nf;i++) {
    s >> freq >> value;
    sOut << freq << value;
  }
}

void ModalStorageReader::toAbsoluteStream(QDataStream& s, QDataStream& sOut)
{
  TRACE;
  int nf;
  s >> nf;
  sOut << nf;
  double freq,value;
  for(int i=0;i<nf;i++) {
    s >> freq >> value;
    sOut << freq << fabs(value);
  }
}

} // namespace DinverDCCore
