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

#include "GridViewer.h"
#include "AxisWindow.h"
#include "XMLSciFigs.h"
#include "LayerLocker.h"
#include "GraphContentLayerFactory.h"

namespace SciFigs {

/*!
  \class GridViewer GridViewer.h qtbgridviewer.cpp
  \brief A GridViewer is a layer to plot a 2D regular grid

*/

const QString GridViewer::xmlGridViewerTag="GridViewer";

REGISTER_GRAPHCONTENTLAYER(GridViewer, "GridViewer" );

GridViewer::GridViewer(AxisWindow * parent) :
    GridPlot(parent)
{
  TRACE;
  _grid=new Grid2D<double>;
}

GridViewer::~GridViewer()
{
  TRACE;
  delete _grid;
}

/*!
  Sets current grid and takes ownership of \a grid.
*/
void GridViewer::setGrid(Grid2D<double> * grid)
{
  TRACE;
  LayerLocker ll(this);
  delete _grid;
  _grid=grid;
}

void GridViewer::paintData(const LayerPainterRequest& lp, QPainter& p, double) const
{
  TRACE;
  if(!_grid || _grid->nx()<2 || _grid->ny()<2) return;

  /*if(smooth()) {
    drawGrid2DSmooth(*_grid, colorMap(), lp, p);
  } else {*/
    drawGrid2DBlock(*_grid, colorMap(), lp, p);
  //}
  if(showGrid()) {
    drawGridLines(*_grid, lp, p);
  }
}

bool GridViewer::mouseReleaseEvent (QMouseEvent * e, int)
{
  TRACE;
  if(e->buttons() & Qt::LeftButton) {
    Point2D p=graphContent()->options().s2r2D(e->pos());
    emit clicked(_grid->indexOfX(p.x()), _grid->indexOfY(p.y()) );
  }
  return true;
}

bool GridViewer::trackRectangle(int, double rx1, double ry1, double rx2, double ry2, Qt::KeyboardModifiers)
{
  TRACE;
  Rect r(rx1, ry1, rx2, ry2);
  int nx=_grid->nx(), ny=_grid->ny();
  for(int iy=0;iy < ny;iy++ ) {
    for(int ix=0;ix < nx;ix++ ) {
      Point2D p=_grid->coordinates(ix, iy);
      if(r.includes(p, _fillType) )
        _grid->setValue(ix, iy, _fillValue);
    }
  }
  graphContent() ->deepUpdate();
  return true;
}

Rect GridViewer::boundingRect() const
{
  TRACE;
  return Rect(_grid->west(0),
              _grid->south(0),
              _grid->east(_grid->nx()-1),
              _grid->north(_grid->ny()-1));
}

void GridViewer::xml_writeChildren(XML_WRITECHILDREN_ARGS) const
{
  TRACE;
  XMLSciFigs * scifigsContext=static_cast<XMLSciFigs *>(context);
  if(scifigsContext->data()) {
    _grid->xml_save(s, context);
  }
  GridPlot::xml_writeChildren(s, context);
}

XMLMember GridViewer::xml_member(XML_MEMBER_ARGS)
{
  TRACE;
  XMLSciFigs * scifigsContext=static_cast<XMLSciFigs *>(context);
  if(scifigsContext->data()) {
    if(tag=="Grid2D") return XMLMember(_grid);
  }
  return GridPlot::xml_member(tag, attributes, context);
}

} // namespace SciFigs
