//
// This file is part of MorphoGraphX - http://www.MorphoGraphX.org
// Copyright (C) 2012-2015 Richard S. Smith and collaborators.
//
// If you use MorphoGraphX in your work, please cite:
//   http://dx.doi.org/10.7554/eLife.05864
//
// MorphoGraphX is free software, and is licensed under under the terms of the 
// GNU General (GPL) Public License version 2.0, http://www.gnu.org/licenses.
// 
#include "CuttingSurface.hpp"
#include "Information.hpp"

namespace mgx {
  
  using qglviewer::Vec;
  
  CuttingSurface::CuttingSurface()
    : _mode(PLANE), _drawGrid(false), _size(Point3f(1.0f, 1.0f, 1.0f)), _draw(false),
      _surfSize(15, 15), _changed(false) {} 
  
  CuttingSurface::~CuttingSurface() {}
  
  void CuttingSurface::getSurfPoints(const qglviewer::Frame* stk_frame, 
  								           std::vector<Point3f>& points, int& uSize, int& vSize)
  {
    uSize = _surfSize.x();
    vSize = _surfSize.y();
  
    for(int u = 0; u < uSize; u++)
      for(int v = 0; v < vSize; v++) {
        Point3f p = evalCoord(float(u) / float(uSize - 1), float(v) / float(vSize - 1));
        if(stk_frame)
          points.push_back(Point3f(stk_frame->coordinatesOf(_frame.inverseCoordinatesOf(Vec(p)))));
        else
          points.push_back(p);
      }
  }
  
  
  Point3f CuttingSurface::evalCoord(float u, float v) const
  {
    // Make sure u and v between 0.0 and 1.0
    u = trim(u, 0.0f, 1.0f);
    v = trim(v, 0.0f, 1.0f);

    if(_mode == BEZIER)
      return Point3f(bezier().evalCoord(u, v));

    Point3f pos;
    pos.x() = 2 * (u - .5) * _size.x();
    pos.y() = 2 * (v - .5) * _size.y();
    return pos;
  }
  
  Point3f CuttingSurface::evalNormal(float u, float v) const
  {
    // Make sure u and v between 0.0 and 1.0
    u = trim(u, 0.0f, 1.0f);
    v = trim(v, 0.0f, 1.0f);
    Point3f du;
    Point3f dv;
    if(u < 0.05)
      du = (evalCoord(u + 0.05, v) - evalCoord(u, v)) / 0.05;
    else if(u > 0.95)
      du = (evalCoord(u, v) - evalCoord(u - 0.05, v)) / 0.05;
    else
      du = (evalCoord(u + 0.05, v) - evalCoord(u - 0.05, v)) / 0.1;
    if(v < 0.05)
      dv = (evalCoord(u, v + 0.05) - evalCoord(u, v)) / 0.05;
    else if(v > 0.95)
      dv = (evalCoord(u, v) - evalCoord(u, v - 0.05)) / 0.05;
    else
      dv = (evalCoord(u, v + 0.05) - evalCoord(u, v - 0.05)) / 0.1;
    return normalized(du ^ dv);
  }
  

  
}
