#ifndef TOOLKITGTK_H
#define TOOLKITGTK_H

#include <gtk/gtk.h>
#include <gtk/gtkgl.h>

#include "Toolkit.h"
#include "GraphNode.h"


namespace nsToolkit {

class ToolkitGtk : public Toolkit
{
	private:
		int idleId;
		GtkWidget *window;
		GtkWidget *drawingArea;

		static void realize(GtkWidget *widget, gpointer toolkit);
		static void unrealize(GtkWidget *widget, gpointer toolkit);
		static gboolean event(GtkWidget *widget, GdkEvent *event, gpointer toolkit);
		static gboolean	idle(gpointer toolkit);

	public:
		ToolkitGtk(int argc, char *argv[]);

		virtual void performInit(void);
		virtual void performAction(void);

		void swapBuffers(void);
		void redrawScene(void);

		bool beginGLExecution(void);
		void endGLExececution(void);

		void enableIdleEvent(void);
		void disableIdleEvent(void);

		int timeOutAdd(int interval, GtkFunction callback);
		void timeOutRemove(int timeOutHandler);

		GtkWidget *getWindow(void);
		GtkWidget *getDrawingArea(void);

		// Comments are taken from gtkglext-1.0.0/examples/template.c

		/*
		 * The "realize" signal handler. All the OpenGL initialization
		 * should be performed here, such as default background colour,
		 * certain states etc.
		 */
		virtual void eventRealize(void) = 0;

		/*
		 * The "unrealize" signal handler. Any processing required when
		 * the OpenGL-capable window is unrealized should be done here.
		 */
		virtual void eventUnrealize(void) = 0;

		/*
		 * The "configure_event" signal handler. Any processing required when
		 * the OpenGL-capable drawing area is re-configured should be done
		 * here. Almost always it will be used to resize the OpenGL viewport
		 * when the window is resized.
		 */
		virtual gboolean eventConfigure(GdkEvent *event) = 0;

		/*
		 * The "map_event" signal handler. Any processing required when the
		 * OpenGL-capable drawing area is mapped should be done here.
		 */
		virtual gboolean eventMap(GdkEvent *event) = 0;

		/*
		 * The "unmap_event" signal handler. Any processing required when the
		 * OpenGL-capable drawing area is unmapped should be done here.
		 */
		virtual gboolean eventUnmap(GdkEvent *event) = 0;

		/*
		 * The "expose_event" signal handler. All the OpenGL re-drawing should
		 * be done here. This is repeatedly called as the painting routine
		 * every time the 'expose'/'draw' event is signalled.
		 */
		virtual gboolean eventExpose(GdkEvent *event) = 0;

		/*
		 * The "key_press_event" signal handler. Any processing required when
		 * key presses occur should be done here.
		 */
		virtual gboolean eventKeyPress(GdkEvent *event) = 0;

		/*
		 * The "motion_notify_event" signal handler. Any processing required
		 * when the OpenGL-capable drawing area is under drag motion should be
		 * done here.
		 */
		virtual gboolean eventMotionNotify(GdkEvent *event) = 0;

		/*
		 * The "button_press_event" signal handler. Any processing required
		 * when mouse buttons (only left and middle buttons) are pressed on
		 * the OpenGL capable drawing area should be done here.
		 */
		virtual gboolean eventButtonPress(GdkEvent *event) = 0;
		virtual gboolean eventButtonRelease(GdkEvent *event) = 0;

		/*
		 * The "visibility_notify_event" signal handler. Any processing
		 * required when the OpenGL-capable drawing area is visually obscured
		 * should be done here.
		 */
		virtual gboolean eventVisibilityNotify(GdkEvent *event) = 0;

		virtual void eventIdle(void) = 0;
};

}

#endif
