#ifdef CGAL_USE_QT

#include <list>
#include <qapplication.h>
#include <qmainwindow.h>
#include <CGAL/Cartesian.h>
#include <CGAL/Gmpq.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/IO/Qt_widget.h>
#include <CGAL/IO/Qt_widget_layer.h>
#include <CGAL/IO/Qt_widget_standard_toolbar.h>
#include <CGAL/IO/Qt_widget_Polygon_2.h>

using namespace CGAL;
using std::list;

//typedef double number;
typedef Gmpq number;
typedef Cartesian<number> K;
typedef Point_2<K> Point;

/***** polygon layer *****/

class PolygonLayer : public Qt_widget_layer
{
      void draw();
   public:
      int vertices;
};

void PolygonLayer::draw()
{
   Polygon_2<K> poly;

   for (int i = 0; i < vertices; ++i)
   {
      double phi = 2*i*CGAL_PI/vertices;
      poly.push_back (Point(cos(phi),sin(phi)));
   }
   widget->lock();
   *widget << BLUE << poly;
   widget->unlock();
}

/***** point layer *****/

class PointLayer : public Qt_widget_layer
{
      void draw();
   public:
      list<Point> all_points;
};

void PointLayer::draw()
{
   widget->lock();
   for (list<Point>::const_iterator pit = all_points.begin(); pit != all_points.end(); ++pit)
      *widget << GREEN << *pit;
   widget->unlock();
}

/***** main window *****/

class PolygonWindow : public QMainWindow
{
      Q_OBJECT
      
      Qt_widget *cgal_widget;
      Qt_widget_standard_toolbar *cgal_toolbar;
      PolygonLayer polylayer;
      PointLayer ptlayer;
      
   public:
      PolygonWindow (int x=600, int y=600);
      
   private slots:
      void mouse_pressed (QMouseEvent* e);
      void key_pressed (QKeyEvent* e);
};

PolygonWindow::PolygonWindow (int x, int y)
{
   polylayer.vertices = 3;
   ptlayer.all_points.push_back(Point(0,0));
   cgal_widget = new Qt_widget(this);
   cgal_widget->resize(x,y);
   cgal_widget->set_window (-1.1,1.1,-1.1,1.1);
   cgal_toolbar = new CGAL::Qt_widget_standard_toolbar (cgal_widget, this, "Polygon Drawer Toolbar");
   cgal_widget->attach (&polylayer);
   cgal_widget->attach (&ptlayer);
   connect (cgal_widget, SIGNAL(s_keyPressEvent(QKeyEvent*)), this, SLOT(key_pressed(QKeyEvent*)));
   connect (cgal_widget, SIGNAL(s_mousePressEvent(QMouseEvent*)), this, SLOT(mouse_pressed(QMouseEvent*)));
   setCentralWidget (cgal_widget);
   cgal_widget->grabKeyboard();
}

/* event handling */

void PolygonWindow::mouse_pressed (QMouseEvent* e)
{
   ptlayer.all_points.push_back(Point (cgal_widget->x_real(e->x()), cgal_widget->y_real(e->y())));
   cgal_widget->redraw();
}

void PolygonWindow::key_pressed (QKeyEvent* e)
{
   cgal_widget->clear();
   switch (e->key())
   {
      case Qt::Key_Q:
	 close();
	 break;
      case Qt::Key_C:
	 ptlayer.all_points = list<Point>();
	 break;
      case Qt::Key_Backspace:
	 if (!ptlayer.all_points.empty())
	    ptlayer.all_points.pop_back();
	 break;
      case Qt::Key_Up:
	 ++polylayer.vertices;
	 break;
      case Qt::Key_Down:
	 if (polylayer.vertices > 3)
	    --polylayer.vertices;
	 break;
      case Qt::Key_Prior:
	 polylayer.vertices += 10;
	 break;
      case Qt::Key_Next:
	 if (polylayer.vertices > 12)
	    polylayer.vertices -= 10;
	 break;
   }
   cgal_widget->redraw();
}

//moc_source_file : qt-polygons.C
#include "qt-polygons.moc"

/***** main() *****/

int main (int argc, char** argv)
{
   QApplication app(argc,argv);
   PolygonWindow polygonwindow;
   app.setMainWidget (&polygonwindow);
   polygonwindow.show();

   return app.exec();
}

#else

#include <iostream>

int main ()
{
   std::cout << "Sorry, this demo needs QT...";
   std::cout << std::endl;
   return 0;
}

#endif // CGAL_USE_QT

