#ifdef CGAL_USE_QT

#include <list>
#include <fstream>
#include <qapplication.h>
#include <qmainwindow.h>
#include <qfiledialog.h>
#include <CGAL/Cartesian.h>
#include <CGAL/Gmpq.h>
#include <CGAL/Point_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/Timer.h>

#include <CGAL/Pm_default_dcel.h>
#include <CGAL/Pm_segment_traits_2.h>
#include <CGAL/Planar_map_2.h>
#include <CGAL/IO/Pm_drawer.h>
#include <CGAL/IO/draw_pm.h>
#include <CGAL/IO/Pm_iostream.h>

using namespace CGAL;
using namespace std;

typedef Gmpq number;
typedef Cartesian<number> K;

typedef Pm_segment_traits_2<K> Pm_traits;
typedef Pm_traits::Point_2 Point;
typedef Pm_traits::X_monotone_curve_2 Segment;

/***** algorithm *****/

number discrepancy (const list<Point> & points)
{
   return 0;
}

/***** one layer *****/

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

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

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

class PlainWindow : public QMainWindow
{
      Q_OBJECT

      Qt_widget *cgal_widget;
      Qt_widget_standard_toolbar *cgal_toolbar;
      PointLayer ptlayer;
      
   public:
      PlainWindow(int width=600, int height=600, int xleft=0, int xright=1, int ylower=0, int yupper=1);

   private slots:
      void mouse_pressed (QMouseEvent* e);
      void key_pressed (QKeyEvent* e);
};

PlainWindow::PlainWindow (int x, int y, int xleft, int xright, int ylower, int yupper)
{
   cgal_widget = new Qt_widget(this);
   cgal_widget->resize(x,y);
   cgal_widget->set_window (xleft, xright, ylower, yupper);
   cgal_toolbar = new CGAL::Qt_widget_standard_toolbar (cgal_widget, this, "Plain Window Toolbar");
   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->setFocusPolicy (QWidget::StrongFocus);
}

void PlainWindow::key_pressed (QKeyEvent* e)
{
   cgal_widget->clear();
   switch (e->key())
   {
      case Qt::Key_Q:
	 close();
	 break;
      case Qt::Key_C:
	 ptlayer.pts.clear();
	 break;
      case Qt::Key_R:
      {
	 cout << "=======================================\n";
	 cout << ptlayer.pts.size() << " points; calculating...\n";
	 Timer t;
	 t.start();
	 number discr = discrepancy(ptlayer.pts);
	 t.stop();
	 cout << "discrepancy: " << discr << "\n";
	 cout << "time: " << t.time() << "s\n";
	 cout << "=======================================\n";
	 break;
      }
      case Qt::Key_S:
      {
	 QString filename = QFileDialog::getSaveFileName(".","",this,"save file dialog","Choose a filename to save the point list" );
	 if (filename.isNull() || filename.isEmpty())
	    break;
	 ofstream outfile (filename.ascii());
	 if (outfile)
	    for (list<Point>::const_iterator p = ptlayer.pts.begin(); p != ptlayer.pts.end(); ++p)
	       outfile << *p << "\n";
	 break;
      }
      case Qt::Key_L:
      {
	 QString filename = QFileDialog::getOpenFileName(".","",this,"open file dialog","Choose a file containing a valid point list");
	 if (filename.isNull() || filename.isEmpty())
	    break;
	 ifstream infile (filename.ascii());
	 if (infile)
	    while (infile.good())
	       {
		  Point p;
		  infile >> p;
		  if (infile.good())
		     if ((0 <= p.x()) && (p.x() <= 1) && (0 <= p.y()) && (p.y() <= 1))
			ptlayer.pts.push_back(p);
	       }
	 break;
      }
   }
   cgal_widget->redraw();
}

void PlainWindow::mouse_pressed (QMouseEvent* e)
{
   number x = cgal_widget->x_real(e->x());
   number y = cgal_widget->y_real(e->y());
   if ((0 <= x) && (x <= 1) && (0 <= y) && (y <= 1))
   {
      ptlayer.pts.push_back(Point(x,y));
      cgal_widget->redraw();
   }
}

//moc_source_file : discrepancy.C
#include "discrepancy.moc"

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

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

   return app.exec();
}

#else

#include <iostream>

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

#endif // CGAL_USE_QT

