/***************************************************************************
**
**  This file is part of QGpCoreMath.
**
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Lesser General Public
**  License as published by the Free Software Foundation; either
**  version 2.1 of the License, or (at your option) any later version.
**
**  This file 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 Lesser General Public
**  License for more details.
**
**  You should have received a copy of the GNU Lesser General Public
**  License along with this library; if not, write to the Free Software
**  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2016-08-23
**  Copyright: 2016-2019
**    Marc Wathelet (ISTerre, Grenoble, France)
**
***************************************************************************/

#include "ComplexStatisticalProxy.h"

namespace QGpCoreMath {

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

    Full description of class still missing
  */

  CURVEPROXY_BASICIMPLEMENTATIONS(ComplexStatisticalProxy)

  QString ComplexStatisticalProxy::columnName(int col) const
  {
    TRACE;
    switch(col) {
      case 0: return tr("X");
      case 1: return tr("Re");
      case 2: return tr("Im");
      case 3: return tr("Abs");
      case 4: return tr("Phase");
      case 5: return tr("Stddev");
      case 6: return tr("Weight");
      default: return QString();
    }
  }

  QString ComplexStatisticalProxy::columnUnit(int) const
  {
    TRACE;
    return QString();
  }

  QVector<int> ComplexStatisticalProxy::savedColumns() const
  {
    TRACE;
    QVector<int> l;
    l << 0 << 1 << 2 << 5 << 6;
    return l;
  }

  QVariant ComplexStatisticalProxy::columnValue(int sample, int col) const
  {
    TRACE;
    const ComplexStatisticalPoint& p=curve()[ sample ];
    switch(col) {
    case 0: return p.x();
    case 1: return p.mean().re();
    case 2: return p.mean().im();
    case 3: return p.mean().abs();
    case 4: return p.mean().phase();
    case 5: return p.stddev();
    case 6: return p.weight();
    default: return QVariant();
    }
  }

  void ComplexStatisticalProxy::setColumnValue(int sample, int col, const QVariant & value)
  {
    TRACE;
    ComplexStatisticalPoint& p=curve()[ sample ];
    Complex c=p.mean();
    switch(col) {
    case 0: p.setX(value.toDouble()); break;
    case 1:
      c.setRe(value.toDouble());
      break;
    case 2:
      c.setIm(value.toDouble());
      break;
    case 3:
      c.setAbs(value.toDouble());
      break;
    case 4:
      c.setPhase(value.toDouble());
      break;
    case 5: p.setStddev(value.toDouble()); break;
    case 6: p.setWeight(value.toDouble()); break;
    default: break;
    }
    p.setMean(c);
  }

  QStringList ComplexStatisticalProxy::columnFileTypes() const
  {
    TRACE;
    static QStringList types;
    if(types.isEmpty()) {
      types << tr("X")                      // 1
            << tr("Average real part")      // 2
            << tr("Average imaginary part") // 3
            << tr("Average absolute value") // 4
            << tr("Average phase")          // 5
            << tr("Stddev")                 // 6
            << tr("Weight")                 // 7
            << tr("Valid");                 // 8
    }
    return types;
  }

  QVector<int> ComplexStatisticalProxy::defaultColumnFileTypes() const
  {
    TRACE;
    QVector<int> l;
    l << 1 << 2 << 3 << 6 << 7 << 8;
    return l;
  }

  bool ComplexStatisticalProxy::parse(ColumnTextIterator& it)
  {
    TRACE;
    const ColumnTextParser * parser=it.parser();
    int nColumns=parser->columnCount();
    Curve<ComplexStatisticalPoint>& c=curve();
    c.clear();
    bool ok=true;
    while(!it.atEnd() && c.isEmpty()) {
      while(!it.atSectionEnd()) {
        ComplexStatisticalPoint p;
        Complex average;
        for(int iCol=0;iCol<nColumns;iCol++) {
          switch(parser->type(iCol)) {
          case 1:
            p.setX(parser->text(it.currentRow(), iCol).toDouble(&ok));
            break;
          case 2:
            average.setRe(parser->text(it.currentRow(), iCol).toDouble(&ok));
            break;
          case 3:
            average.setIm(parser->text(it.currentRow(), iCol).toDouble(&ok));
            break;
          case 4:
            average.setAbs(parser->text(it.currentRow(), iCol).toDouble(&ok));
            break;
          case 5:
            average.setPhase(parser->text(it.currentRow(), iCol).toDouble(&ok));
            break;
          case 6:
            p.setStddev(parser->text(it.currentRow(), iCol).toDouble(&ok));
            break;
          case 7:
            p.setWeight(parser->text(it.currentRow(), iCol).toDouble(&ok));
            break;
          case 8:
            p.setValid(parser->text(it.currentRow(), iCol).toInt(&ok)==1);
            break;
         default:
            break;
          }
          if(!ok) {
            parser->errorParsingColumn(iCol, it.currentRow());
            return false;
          }
        }
        p.setMean(average);
        c.append(p);
        it.nextRow();
      }
    }
    return true;
  }

} // namespace QGpCoreMath

