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

#include "AbstractLine.h"
#include "LineLayer.h"
#include "XMLSciFigs.h"

namespace SciFigs {

/*!
  \class AbstractLine AbstractLine.h
  \brief An abstract class for ploting curves with pen and symbol properties
*/

const QString AbstractLine::xmlAbstractLineTag="Line";

/*!
  If overloaded you must call this function in your implementation.
*/
void AbstractLine::operator=(const AbstractLine& o)
{
  _pen=o._pen;
  _symbol=o._symbol;
  _selected=o._selected;
  _visible=o._visible;
  _editable=o._editable;
}

bool AbstractLine::fromString(int index, const StringSection& str, const QChar *& ptr, const CurvePointOptions * options)
{
  bool ok=true;
  StringSection f;
  f=str.nextField(ptr);
  if(f.isValid()) {
    setX(index, f.toDouble(&ok));
    if(!ok) return false;
  } else {
    return false;
  }
  f=str.nextField(ptr);
  if(f.isValid()) {
    setY(index, f.toDouble(&ok), options);
    if(!ok) return false;
  } else {
    return false;
  }
  const QChar * oldPtr=ptr;
  f=str.nextField(ptr);
  if(f.isValid()) {
    setZ(index, f.toDouble(&ok), options);
    if(!ok) return false;
  } else { // Z is optional
    setZ(index, 0.0, options);
    ptr=oldPtr;
  }
  return true;
}

/*!
*/
void AbstractLine::xml_writeProperties(XML_WRITEPROPERTIES_ARGS) const
{
  TRACE;
  ASSERT(context);
  LineLayerContext * lineContext=static_cast<LineLayerContext *>(context);
  XMLSciFigs * scifigsContext=lineContext->parent();
  CurvePointOptions * options=lineContext->options();
  if(scifigsContext->data()) {
    QString tmp;
    tmp+=s.indent();
    tmp+="<points>\n";
    int n=count();
    for(int j=0; j<n; j++) {
      if(isValid(j)) {
        tmp+=s.indent();
        tmp+="    ";
        tmp+=toString(j, options);
        tmp+="\n";
      }
    }
    tmp+=s.indent();
    tmp+="</points>";
    s << tmp << endl;
  }
  if(scifigsContext->makeUp()) {
    writeProperty(s, "selected", isSelected());
    writeProperty(s, "visible", isVisible());
    writeProperty(s, "editable", isEditable());
  }
}

/*!
*/
void AbstractLine::xml_writeChildren(XML_WRITECHILDREN_ARGS) const
{
  TRACE;
  XMLSciFigs * scifigsContext=static_cast<LineLayerContext *>(context)->parent();
  if(scifigsContext->makeUp()) {
    _pen.xml_save(s, context);
    _symbol.xml_save(s, context);
  }
}

/*!
*/
XMLMember AbstractLine::xml_member(XML_MEMBER_ARGS)
{
  TRACE;
  Q_UNUSED(attributes)
  XMLSciFigs * scifigsContext=static_cast<LineLayerContext *>(context)->parent();
  if(scifigsContext->data()) {
    if(tag=="points") return XMLMember(0);
  }
  if(scifigsContext->makeUp()) {
    if(tag=="selected") return XMLMember(1);
    else if(tag=="visible") return XMLMember(2);
    else if(tag=="editable") return XMLMember(3);
    else if(tag=="Pen") return XMLMember(&_pen);
    else if(tag=="Symbol") return XMLMember(&_symbol);
  }
  return XMLMember(XMLMember::Unknown);
}

/*!
*/
bool AbstractLine::xml_setProperty(XML_SETPROPERTY_ARGS)
{
  TRACE;
  Q_UNUSED(tag)
  Q_UNUSED(attributes)
  LineLayerContext * lineContext=static_cast<LineLayerContext *>(context);
  switch (memberID) {
  case 0: {
      const QChar * ptr=0;
      clear();
      int i=0;
      while(true) {
        append();
        if(!content.nextLine(ptr)) break;
        if(!fromString(i, content, ptr, lineContext->options())) break;
        i++;
      }
      removeLast();
      checkSort();
    }
    return true;
  case 1:
    _selected=content.toBool();
    return true;
  case 2:
    _visible=content.toBool();
    return true;
  case 3:
    _editable=content.toBool();
    return true;
  default:
    return false;
  }
}

} // namespace SciFigs
