/***************************************************************************
**
**  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: 2008-11-09
**  Copyright: 2008-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include "PointND.h"
#include "Point2D.h"
#include "PointNDOptions.h"

namespace QGpCoreMath {

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

    Full description of class still missing
  */

  /*!
    Copy constructor from a vector
  */
  PointND::PointND(const QVector<double>& p)
  {
    ASSERT(p.count()>1);
    _x=p.at(0);
    _y=p;
    _y.remove(0);
  }

  double PointND::y(const CurvePointOptions * options) const
  {
    if(options) {
      const PointNDOptions * po=static_cast<const PointNDOptions *>(options);
      return po->toDouble(*this);
    } else {
      return _y.first();
    }
  }

  void PointND::setY(double y, const CurvePointOptions * options)
  {
    if(options) {
      const PointNDOptions * po=static_cast<const PointNDOptions *>(options);
      po->fromDouble(*this, y);
    } else {
      _y.first()=y;
    }
  }

  Point2D PointND::point2D(const CurvePointOptions * options) const
  {
    if(options) {
      const PointNDOptions * po=static_cast<const PointNDOptions *>(options);
      return Point2D(_x, po->toDouble(*this));
    } else {
      return Point2D(_x, _y.first());
    }
  }

  /*!
    Returns the point as a string with space separation between coordinates.
    \a precision is the number of significant digits. \a format is 'g' or 'f'.
  */
  QString PointND::toString(int precision, char format) const
  {
    TRACE;
    QString tmp;
    tmp+=QString::number(_x, format, precision);
    int n=count();
    for(int i=0; i<n; i++) {
      tmp+=" ";
      tmp+=QString::number(y(i), format, precision);
    }
    return tmp;
  }

  bool PointND::fromString(const StringSection& str)
  {
    TRACE;
    const QChar * ptr=0;
    StringSection f;
    f=str.nextField(ptr);
    if(f.isValid()) _x=f.toDouble(); else return false;
    f=str.nextField(ptr);
    int i=0;
    while(f.isValid()) {
      setY(i++, f.toDouble());
      f=str.nextField(ptr);
    }
    return true;
  }

  double PointND::at(int index) const
  {
    switch(index) {
    case 0:
      return _x;
    default:
      return _y.at(index-1);
    }
  }

} // namespace QGpCoreMath
