#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::Circle_2<Rep>		    Circle;
typedef CGAL::Delaunay_triangulation_2<Rep> Delaunay;
typedef Delaunay::Vertex_handle             VertexH;
typedef Delaunay::Vertex_circulator         VCirculator;

class Dist_order {
  const Delaunay *t;
  const Point *p;

public:
  Dist_order(const Delaunay *tr, Point *po)
    : t(tr), p(po) {}

  bool operator()(const VertexH v1, const VertexH v2) const 
  {
    return (CGAL::compare_distance_to_point(*p,v1->point(),v2->point()) == CGAL::SMALLER );
  }
};

typedef  std::set<VertexH,Dist_order> Queue;


/////////////////////////////////////////////////////////
//  Les objets affiches sont declares ici en variable globales
//  l'affichage est fait dans la methode "draw" ci dessous

Delaunay         dt;
Point            the_point=Point();
Queue            queue(Dist_order(&dt,&the_point));
Queue::iterator  all_neighbors;
Point            the_neighbor;

class My_layer : public CGAL::Qt_widget_layer{
  void draw(){
    *widget << CGAL::RED << dt << CGAL::PointSize(6) << CGAL::BLUE << the_point ;

    if (dt.number_of_vertices() < 2) return;
    if (the_neighbor == Point() ) return;

    *widget << CGAL::YELLOW 
	    << Circle(the_point,CGAL::squared_distance(the_point,the_neighbor))
	    << CGAL::GREEN << the_neighbor ;
  }
};

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);

    /////////////////////////////////////////////////////////////
    //  C'EST ICI QUE CA SE PASSE QUAND ON CLIQUE !
    //
    if (e->button() == Qt::LeftButton){
      dt.insert(Point(x_real(e->x()), y_real(e->y())));
      the_neighbor = Point();
      the_point = Point();
    }    
    if (e->button() == Qt::MidButton){
      if (the_point == Point()) {
	std::cout<<"pas de point dont chercher les voisins !"<<std::endl;
      } else if (all_neighbors==queue.end()){
	std::cout<<"c'est fini!"<<std::endl;
	the_neighbor = Point();
	the_point = Point();
      }else{
	VertexH v = *all_neighbors;
	the_neighbor = v->point();
	VCirculator circ = dt.incident_vertices(v), circDone=circ;
	do {
	  if (!dt.is_infinite(circ)) queue.insert(circ);
	  ++circ;
	} while (circ!=circDone);
	++all_neighbors;
      }
    }
    if (e->button() == Qt::RightButton){
      the_point =  Point(x_real(e->x()), y_real(e->y()));
      queue.clear();
      queue.insert(dt.nearest_vertex(the_point));
      all_neighbors = queue.begin();
      the_neighbor = 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();
}

