/***************************************************************************
**
**  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-01-05
**  Copyright: 2006-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#ifndef DCREPORTBLOCK_H
#define DCREPORTBLOCK_H

#include <QGpCoreTools.h>
#include <QGpCompatibility.h>
#include <DinverCore.h>

#include "DinverDCCoreDLLExport.h"
#include "ModalStorageReader.h"

namespace DinverDCCore {

#define DCREPORTBLOCK_CURRENT_VERSION 2

  class TargetList;
  class TargetList2D;

class DINVERDCCORE_EXPORT DCReportBlock
{
  TRANSLATIONS("DCReportBlock")
public:
  DCReportBlock(QDataStream& s);
  ~DCReportBlock();

  static void write(ReportWriter * report, const TargetList& tl,
                    const Profile * vp=nullptr, const Profile * vs=nullptr,
                    const Profile * rho=nullptr, const Profile * pitch=nullptr,
                    const Profile * res=nullptr);
  static void write(ReportWriter * outReport, ReportReader * inReport);
  static void writeBeta(ReportWriter * outReport, ReportReader * inReport);
  static void writeNaViewer(ReportWriter * outReport, CompatInversionReport * inReport);

  void readProfiles(int version);
  Seismic1DModel * readSeismicModel();
  Resistivity1DModel * readElectricModel();
  void readModalStorages(int nStorages);
  QDataStream& stream() {return *_s;}

  inline bool profile(int i) const;
  bool vp() const {return profile(0);}
  bool vs() const {return profile(1);}
  bool rho() const {return profile(2);}
  bool pitch() const {return profile(3);}
  bool res() const {return profile(4);}
  bool dispersion() const {return profile(5);}
  bool autocorr() const {return profile(6);}
  bool ellipticity() const {return profile(7);}
  bool refractionVp() const {return profile(8);}
  bool refractionVs() const {return profile(9);}
  bool magnetoTelluric() const {return profile(10);}

  inline bool modalStorage(int i) const;

  void setStorageReader(ModalStorageReader * r) {delete _reader; _reader=r;}
  ModalStorageReader * storageReader() const {return _reader;}

  static Seismic1DModel * surfaceWaveModel(const QVector<double>& zProf,
                                         QVector<double>& vpProf,
                                         const QVector<double>& vsProf,
                                         const QVector<double>& rhoProf,
                                         const QVector<double> * nuMinProf=nullptr,
                                         const QVector<double> * nuMaxProf=nullptr);
  static Seismic1DModel * vspModel(const QVector<double>& zProf,
                                 const QVector<double>& vpProf,
                                 const QVector<double>& vsProf);
  static Seismic1DModel * vpModel(const QVector<double>& zProf,
                                const QVector<double>& vpProf);
  static Seismic1DModel * vsModel(const QVector<double>& zProf,
                                const QVector<double>& vsProf);
private:
  static void writeOffsetTable(QDataStream& s);
  static void writeFactory(QDataStream& s, const ModalFactory& f);
  static void writeFactory(QDataStream& s, DCReportBlock& dcBlock, int storageCount);
  static void writeFactoryBeta(QDataStream& s, DCReportBlock& dcBlock, int nStorages);
  static void writeFactoryNaViewer(QDataStream& s, CompatMultiModalCurves * curves, int nStorages);

  QDataStream * _s;
  qint64 * _profileOffsets;
  qint64 * _modalStorageOffsets;
  ModalStorageReader * _reader;
};

inline bool DCReportBlock::profile(int i) const
{
  TRACE;
  if(_profileOffsets[i]>0) {
    _s->device()->seek(_profileOffsets[i]);
    return true;
  } else return false;
}

inline bool DCReportBlock::modalStorage(int i) const
{
  TRACE;
  if(_modalStorageOffsets[i]>0) {
    _s->device()->seek(_modalStorageOffsets[i]);
    return true;
  } else return false;
}

} // namespace DinverDCCore

#endif // DCREPORTBLOCK_H
