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

#include "MeshLayer.h"
#include "LayerPainterRequest.h"

namespace SciFigs {

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

    Full description of class still missing
  */

  /*!
    Description of constructor still missing
  */
  MeshLayer::MeshLayer(AxisWindow * parent)
      : GraphContentLayer(parent)
  {
    TRACE;
    _dotSize=0.03; // cm
    _step=0.1;
    _size=1.0;
    _size0=_size;
    setOpacity(0.1);
  }

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

  void MeshLayer::setStep(double s)
  {
    _step=s;
    _size0=qFloor(_size/_step)*_step;
  }

  void MeshLayer::setSize(double s)
  {
    _size=s;
    _size0=qFloor(_size/_step)*_step;
  }

  Rect MeshLayer::boundingRect() const
  {
    TRACE;
    return Rect(-_size, -_size, _size, _size);
  }

  /*!
  */
  void MeshLayer::paintData(const LayerPainterRequest& lp, QPainter& p, double dotpercm) const
  {
    TRACE;
    const GraphContentOptions& gc=lp.options();
    int pointSize, halfSize;
    double pointSizeF=_dotSize * dotpercm;
    if(pointSizeF<=2.0) {
      pointSize=2;
      halfSize=1;
    } else {
      pointSize=qRound(pointSizeF);
      halfSize=qRound(0.5*pointSizeF);
    }
    double invKmin=1.0/_step;
    double kmax2=_size*_size;
    int nNodes=qRound(2.0*_size0*invKmin)+1;
    int ixMin, iyMin, ixMax, iyMax;
    ixMin=qFloor((gc.xVisMin()+_size0)*invKmin);
    if(ixMin<0) ixMin=0;
    ixMax=qCeil((gc.xVisMax()+_size0)*invKmin);
    if(ixMax>nNodes) ixMax=nNodes;
    iyMin=qFloor((gc.yVisMin()+_size0)*invKmin);
    if(iyMin<0) iyMin=0;
    iyMax=qCeil((gc.yVisMax()+_size0)*invKmin);
    if(iyMax>nNodes) iyMax=nNodes;

    p.setPen(QPen(Qt::black, 1));
    p.setBrush(QBrush( Qt::black, Qt::SolidPattern) );
    if(fabs(gc.ys2r(pointSize+2)-gc.ys2r(0))>_step ||
       fabs(gc.xs2r(pointSize+2)-gc.xs2r(0))>_step) {
      int x1=gc.xr2s(-_size0);
      int y1=gc.yr2s(-_size0);
      int x2=gc.xr2s(_size0);
      int y2=gc.yr2s(_size0);
      if(x1>x2) qSwap(x1, x2);
      if(y1>y2) qSwap(y1, y2);
      p.drawEllipse(x1, y1, x2-x1, y2-y1);
    } else {
      for(int iy=iyMin; iy<iyMax; iy++) {
        if(lp.terminated()) return;
        double ky2=static_cast<double>(iy)*_step-_size0;
        int ory=gc.yr2s(ky2)-halfSize;
        ky2*=ky2;
        for(int ix=ixMin; ix<ixMax; ix++) {
          double kx=static_cast<double>(ix)*_step-_size0;
          if(kx*kx+ky2<kmax2) {
            int orx=gc.xr2s(kx)-halfSize;
            p.drawEllipse(orx, ory, pointSize, pointSize);
          }
        }
      }
    }
  }

} // namespace SciFigs
