#include <CGAL/Cartesian.h>
#include <CGAL/Point_2.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/IO/Qt_widget_Delaunay_triangulation_2.h>
#include <CGAL/IO/Qt_widget.h>
#include <CGAL/IO/Qt_widget_layer.h>
#include <qapplication.h>

typedef CGAL::Cartesian<double>		    Rep;
typedef CGAL::Point_2<Rep>		    Point;
typedef CGAL::Delaunay_triangulation_2<Rep> Delaunay;


typedef CGAL::Circle_2<Rep>		    Circle;
typedef CGAL::Triangle_2<Rep>		    Triangle;
typedef Delaunay::Vertex_handle             Vertex;
typedef Delaunay::Face_handle               Face;
typedef Delaunay::Finite_faces_iterator     Faces_it;


/////////////////////////////////////////////////////////
//  The displayed objects are declared here as global variables.
//  The display code is the "draw" member function below.

Delaunay dt;
Point    the_point = Point(-1, -1);
Vertex   neighbor;
Face     found_face;
Triangle triang;
Circle   circle;

class My_layer : public CGAL::Qt_widget_layer {
  void draw() {

    // coloring of the faces
    Faces_it it  = dt.finite_faces_begin();
    Faces_it end = dt.finite_faces_end();
    for ( ; it != end ; ++it ) {
      Triangle tt = dt.triangle(it);
      double ratio = tt.area()
	/ CGAL::squared_distance(dt.circumcenter(it), it->vertex(0)->point());
      if ( ratio > 0.3 )
	*widget << CGAL::FillColor( CGAL::Color(100, 255, 100) ) << tt;
      else
	*widget << CGAL::FillColor( CGAL::Color(255, 100, 100) ) << tt;
    }

    // display the triangulation and the clicked point
    *widget << CGAL::LineWidth(3) << CGAL::noFill << CGAL::RED << dt
	    << CGAL::PointSize(6) << CGAL::BLUE << the_point;

    // display of the face and the circumscribing circle
    if (found_face != Face() &&   ! dt.is_infinite(found_face) )
      *widget << CGAL::LineWidth(4) << CGAL::BLACK << circle
	      <<                       CGAL::ORANGE << triang;

    // display of the nearest neighbor
    if (neighbor != Vertex())
       *widget << CGAL::GREEN << neighbor->point();
  }
};

class My_window : public CGAL::Qt_widget {
public:
  My_window(int x, int y)
  {
    resize(x, y);
    attach(&layer);
  }
private:
  //this method is called when the user presses the mouse
  void mousePressEvent(QMouseEvent *e)
  {
    Qt_widget::mousePressEvent(e);

    /////////////////////////////////////////////////////////////
    //  HERE IS WHAT IS EXECUTED ON A MOUSE CLICK !
    //
    if (e->button() == Qt::LeftButton) {
      dt.insert(Point(x_real(e->x()), y_real(e->y())));
    }
    if (e->button() == Qt::MidButton) {
      found_face = dt.locate(Point(x_real(e->x()), y_real(e->y())));
      circle = Circle(found_face->vertex(0)->point(),
		      found_face->vertex(1)->point(),
		      found_face->vertex(2)->point());
      triang = Triangle(found_face->vertex(0)->point(),
		        found_face->vertex(1)->point(),
		        found_face->vertex(2)->point());
    }
    if (e->button() == Qt::RightButton) {
      the_point = Point(x_real(e->x()), y_real(e->y()));
      neighbor = dt.nearest_vertex( the_point);
    }
    /////////////////////////////////////////////////////////////

    redraw();
  }
  My_layer layer;
};

int main( int argc, char **argv )
{
    QApplication app( argc, argv );
    My_window *W = new My_window(400, 400);
    app.setMainWidget(W);
    W->show();
    W->set_window(0, 400, 0, 400);
    return app.exec();
}
