/***************************************************************************
**
**  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: 2002-10-08
**  Copyright: 2002-2019
**    Marc Wathelet
**    Marc Wathelet (ULg, Liège, Belgium)
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#ifndef SYMBOL_H
#define SYMBOL_H

#include "SciFigsDLLExport.h"
#include "Pen.h"
#include "Brush.h"

namespace SciFigs {

  class SCIFIGS_EXPORT Symbol : public XMLClass
  {
   public:
    enum Type{NoSymbol, Cross, Square, Circle, TriangleUp, TriangleDown, Losange, Star};
    Symbol(Type type=NoSymbol, double size=1.2, Pen pen=Pen(Qt::black),
           Brush brush=Brush(Qt::NoBrush));
    Symbol(const Symbol& s);
    virtual ~Symbol() {}

    Symbol& operator=(const Symbol& o);
    bool operator==(const Symbol& o) const;

    virtual const QString& xml_tagName() const {return xmlSymbolTag;}
    static const QString xmlSymbolTag;

    static Type symbolValue(QString s);
    static QString symbolName(Type s);

    void fromStream(QTextStream& s);

    void setType(Type t) {_type=t;}
    Type type() const {return _type;}

    void setSize(double s) {_size=s;}
    double size() const {return _size;}

    void setPen(const Pen& p) {_pen=p;}
    const Pen& pen() const {return _pen;}

    void setBrush(const Brush& b) {_brush=b;}
    const Brush& brush() const {return _brush;}

    void paint(QPainter& p, const QPointF &center, double dotpercm=28.346457) const;
    static inline void paint(Type type, QPainter& p, QPointF center,
                             double size, double halfSize);

    static const Symbol null;
  protected:
    virtual void xml_writeProperties(XML_WRITEPROPERTIES_ARGS) const;
    virtual void xml_writeChildren(XML_WRITECHILDREN_ARGS) const;
    virtual bool xml_setProperty(XML_SETPROPERTY_ARGS);
    virtual XMLMember xml_member(XML_MEMBER_ARGS);
  protected:
    Type _type;
    // Size in mm
    double _size;
    Pen _pen;
    Brush _brush;
  };

  // SCIFIGS_EXPORT QTextStream& operator>>(QTextStream& s, Symbol& sym);

  inline void Symbol::paint(Type type, QPainter& p, QPointF center,
                            double size, double halfSize)
  {
    TRACE;
    switch(type) {
    case Cross: {
        QPointF h1(halfSize, halfSize);
        QPointF h2(halfSize, -halfSize);
        p.drawLine(center-h1, center+h1);
        p.drawLine(center-h2, center+h2);
      }
      break;
    case Square: {
        p.drawRect(QRectF(center-QPointF(halfSize, halfSize),QSizeF(size,size)));
      }
      break;
    case Circle: {
        p.drawEllipse(center, halfSize, halfSize);
      }
      break;
    case TriangleUp: {
        QPolygonF points(4);
        double halfSize=0.5*0.866025403784439*size;
        center+=QPointF(-halfSize, 0.25*size);
        points[0]=center;
        points[1]=center+QPointF(0.866025403784439*size, 0);
        points[2]=center+QPointF(halfSize, -0.75*size);
        points[3]=points[0];
        p.drawPolygon(points);
      }
      break;
    case TriangleDown: {
        QPolygonF points(4);
        double halfSize=0.5*0.866025403784439*size;
        center+=QPointF(-halfSize, -0.25*size);
        points[0]=center;
        points[1]=center+QPointF(0.866025403784439*size, 0);
        points[2]=center+QPointF(halfSize, 0.75*size);
        points[3]=points[0];
        p.drawPolygon(points);
      }
      break;
    case Losange: {
        QPolygonF points(5);
        double quarterSize=size*0.25;
        points[0]=center-QPointF(0.0, halfSize);
        points[1]=center+QPointF(quarterSize, 0.0);
        points[2]=center+QPointF(0.0, halfSize);
        points[3]=center-QPointF(quarterSize, 0.0);
        points[4]=points[0];
        p.drawPolygon (points);
      }
      break;
    case Star: {
        QPointF h1(halfSize, halfSize);
        QPointF h2(halfSize, -halfSize);
        QPointF h3(halfSize, 0.0);
        QPointF h4(0.0, halfSize);
        p.drawLine(center-h1, center+h1);
        p.drawLine(center-h2, center+h2);
        p.drawLine(center-h3, center+h3);
        p.drawLine(center-h4, center+h4);
      }
      break;
    default:
      break;
    }
  }

} // namespace SciFigs

#endif // SYMBOL_H
