/***************************************************************************
**
**  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: 2012-12-19
**  Copyright: 2012-2019
**    Marc Wathelet (ISTerre, Grenoble, France)
**
***************************************************************************/

#include "HistogramLayer.h"
#include "GraphContentLayerFactory.h"
#include "LayerPainterRequest.h"
#include "XMLSciFigs.h"
#include "LayerLocker.h"

namespace SciFigs {

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

    Full description of class still missing
  */

  const QString HistogramLayer::xmlHistogramLayerTag="HistogramLayer";

  REGISTER_GRAPHCONTENTLAYER(HistogramLayer, "HistogramLayer");

  /*!
    Description of constructor still missing
  */
  HistogramLayer::HistogramLayer(AxisWindow * parent)
    : GraphContentLayer(parent)
  {
    TRACE;
  }

  /*!
    Description of destructor still missing
  */
  HistogramLayer::~HistogramLayer()
  {
    TRACE;
  }

  /*!
    \todo Add support for multiple histograms with the same sampling
  */
  void HistogramLayer::set(const Histogram& h)
  {
    TRACE;
    LayerLocker ll(this);
    _histogram=h;
  }

  void HistogramLayer::paintData(const LayerPainterRequest& lp, QPainter& p, double) const
  {
    TRACE;
    const GraphContentOptions& gc=lp.options();
    QVector<Rect> rects=_histogram.boxes();
    int n=rects.count()-1;
    if(n>0) {
      p.save();
      p.setPen(Qt::NoPen);
      p.setBrush(QBrush(Qt::black, Qt::SolidPattern));
      const Rect& r1=rects.first();
      p.drawRect(QRect(gc.r2s(gc.xVisMin(), 0), gc.r2s(r1.x2(), r1.y2())));
      for(int i=1; i<n; i++) {
         const Rect& r=rects.at(i);
         p.drawRect(QRect(gc.r2s(r.x1(), r.y1()), gc.r2s(r.x2(), r.y2())));
      }
      const Rect& r2=rects.last();
      p.drawRect(QRect(gc.r2s(r2.x1(), r2.y2()), gc.r2s(gc.xVisMax(), 0)));
      p.restore();
    }
  }

  Rect HistogramLayer::boundingRect() const
  {
    TRACE;
    return _histogram.limits();
  }

  void HistogramLayer::xml_writeProperties(XML_WRITEPROPERTIES_ARGS) const
  {
    TRACE;
    XMLSciFigs * scifigsContext=static_cast<XMLSciFigs *>(context);
    if(scifigsContext->data()) {
      QString tmp;
      tmp+=s.indent();
      tmp+="<values>\n";
      int n=_histogram.countClasses();
      for(int j=0; j<n; j++) {
        tmp+=s.indent();
        tmp+="    ";
        tmp+=_histogram.classAt(j).toString(20);
        tmp+="\n";
      }

      tmp+=s.indent();
      tmp+="</values>";
      s << tmp << endl;
      writeProperty(s, "lastClass", _histogram.lastClass());
    }
  }

  XMLMember HistogramLayer::xml_member(XML_MEMBER_ARGS)
  {
    Q_UNUSED(attributes)
    XMLSciFigs * scifigsContext=static_cast<XMLSciFigs *>(context);
    if(scifigsContext->data()) {
      if(tag=="points") return XMLMember(0);
      else if(tag=="lastClass") return XMLMember(1);
    }
    return XMLMember(XMLMember::Unknown);
  }

  bool HistogramLayer::xml_setProperty(XML_SETPROPERTY_ARGS)
  {
    Q_UNUSED(tag)
    Q_UNUSED(attributes)
    Q_UNUSED(context)
    switch (memberID) {
    case 0: {
        const QChar * ptr=0;
        _histogram.clearClasses();
        Point2D c;
        while(true) {
          if(!content.nextLine(ptr)) break;
          StringSection l=content.readLine(ptr);
          if(!c.fromString(l)) return false;
          _histogram.addClass(c);
        }
      }
      return true;
    case 1: {
        bool ok=true;
        _histogram.setLastClass(content.toDouble(&ok));
        return ok;
      }
    default:
      return false;
    }
  }

} // namespace SciFigs
