/***************************************************************************
**
**  This file is part of QGpCompatibility.
**
**  QGpCompatibility 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.
**
**  QGpCompatibility 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: 2004-09-17
**  Copyright: 2004-2019
**    Marc Wathelet
**    Marc Wathelet (ULg, Liège, Belgium)
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <QGpCoreWave.h>
#include "CompatHodoChroneData.h"

namespace QGpCompatibility {

void CompatHodoChroneData::calculate(RefractionDippingModel& model)
{
  TRACE;
  model.setXLeft(_omegas[0]);
  model.setXRight(_omegas[CompatMultiModalFrequency::_omegasCount-1]);
  model.begin();
  TiltNode * nodes=new TiltNode [CompatMultiModalFrequency::_omegasCount];
  for(int iRec=0;iRec<CompatMultiModalFrequency::_omegasCount;iRec++) {
    nodes[iRec].init(_omegas[iRec],model);
  }
  
  int minTimeLayer;
  for(int iSrc=0;iSrc<CompatMultiModalFrequency::_modesCount;iSrc++) {
    double * measurements=_measurements[iSrc];
    double * value=_values[iSrc];
    int omegaISrc=srcIndex(iSrc);
    // Go towards negative receivers
    if(omegaISrc>0) {
      for(int iRec=0;iRec<omegaISrc;iRec++) {
        if(measurements[iRec]!=CompatHODOCHRONE_INVALID_VALUE) {
          value[iRec]=
              model.travelTime(nodes[omegaISrc], nodes[iRec], minTimeLayer);
         }
        else value[iRec]=CompatHODOCHRONE_INVALID_VALUE;
      }
    }
    value[omegaISrc]=0;
    // Go towards positive receivers
    if(omegaISrc<CompatMultiModalFrequency::_omegasCount-1) {
      for(int iRec=omegaISrc+1;iRec<CompatMultiModalFrequency::_omegasCount;iRec++) {
        if(measurements[iRec]!=CompatHODOCHRONE_INVALID_VALUE) {
          value[iRec]=
              model.travelTime(nodes[omegaISrc], nodes[iRec], minTimeLayer);
        }
        else value[iRec]=CompatHODOCHRONE_INVALID_VALUE;
      }
    }
  }
  delete [] nodes;
  model.end();
}

/*
void CompatHodoChroneData::rays(RefractionDippingModel& model,
                             LineLayer * raysLayer)
{
  TRACE;
  raysLayer->clear();

  model.begin();
  CompatTiltNode * nodes=new CompatTiltNode [CompatMultiModalFrequency::_omegasCount];
  for(int iRec=0;iRec<CompatMultiModalFrequency::_omegasCount;iRec++) {
    nodes[iRec].init(_omegas[iRec],model);
  }

  for(int iSrc=0;iSrc<CompatMultiModalFrequency::_modesCount;iSrc++) {
    double * measurements=_measurements[iSrc];
    int omegaISrc=srcIndex(iSrc);
    // Go towards negative receivers
    if(omegaISrc>0) {
      for(int iRec=0;iRec<omegaISrc;iRec++) {
        if(measurements[iRec]!=CompatHODOCHRONE_INVALID_VALUE) {
          CompatCurve<Point> * ray=model.ray(nodes[omegaISrc].left(), nodes[iRec].right());
          raysLayer->addLine(ray,CompatPen(Qt::black,0),CompatSymbol());
        }
      }
    }
    // Go towards positive receivers
    if(omegaISrc<CompatMultiModalFrequency::_omegasCount-1) {
      for(int iRec=omegaISrc+1;iRec<CompatMultiModalFrequency::_omegasCount;iRec++) {
        if(measurements[iRec]!=CompatHODOCHRONE_INVALID_VALUE) {
          CompatCurve<Point> * ray=model.ray(nodes[omegaISrc].right(), nodes[iRec].left());
          raysLayer->addLine(ray,CompatPen(Qt::black,0),CompatSymbol());
        }
      }
    }
  }
  delete [] nodes;
  model.end();
}*/

int CompatHodoChroneData::srcIndex(int iSrc)
{
  TRACE;
  double * measurements=_measurements[iSrc];
  for(int i=0;i<CompatMultiModalFrequency::_omegasCount;i++) {
    if(measurements[i]==0) return i;
  }
  fprintf(stderr,"Error in CompatHodoChroneData no source location defined");
  return 0;
}

void CompatHodoChroneData::setSource(QString srcFile)
{
  TRACE;
  QFile f(srcFile);
  if(!f.open(QIODevice::ReadOnly)) {
    fprintf(stderr," *** ERROR *** Cannot open source file\n");
    return;
  }
  QTextStream s(&f);
  QString str;
  int iSrc=0;
  for(iSrc=0;iSrc<CompatMultiModalFrequency::_modesCount;iSrc++) {
    double * measurements=_measurements[iSrc];
    for(int i=0;i<CompatMultiModalFrequency::_omegasCount;i++)
      measurements[i]=1;
  }
  iSrc=0;
  while(!s.atEnd()) {
    str=s.readLine().trimmed();
    if(!str.isEmpty() && str.left(1)!="#") {
      int srcIndex=str.section(QRegExp("[ \t]"),0,0).toInt();
      if(srcIndex>=0 && srcIndex<CompatMultiModalFrequency::_omegasCount)
        _measurements[iSrc][srcIndex]=0;
      else
        fprintf(stderr,"Receiver index out of range in CompatHodoChroneData::setSource\n");
      iSrc++;
      if(iSrc>=CompatMultiModalFrequency::_modesCount) break;
    }
  }  
}


} // namespace QGpCompatibility
