// QtSupport.cs - QtSupport c-sharp support file
//
// Copyright (C) 2002  Adam Treat (manyoso@yahoo.com)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

namespace Qt {

	using Qt;
	using System;
	using System.Collections;
	using System.Reflection;
	using System.Text.RegularExpressions;
	using System.Runtime.InteropServices;

	public class QtSupport: IDisposable {

		private static Hashtable QtObjects;
		private static int cleanCount;
		private static int cleanLimit;

		private static QtEventHandler qtEventHandler;

		// Runtime flags, set by QApplication.ParseArguments
		internal static bool enableDebug;
		internal static bool disableTracking;
		internal static bool traceObjects;
		internal static bool traceChildren;

		static QtSupport() {
			//QtObjects = Hashtable.Synchronized (new Hashtable ());
			QtObjects = new Hashtable();

			cleanCount = 0;
			cleanLimit = 750;

			enableDebug = false;
			disableTracking = false;
			traceObjects = false;
			traceChildren = false;
		}

		internal protected IntPtr rawObject;
		internal protected bool disposed;
		internal bool deleted;
		protected QtSupport qparent;
		protected ArrayList qchildren;

		internal IntPtr RawObject {
			get { return rawObject; }
		}

		public bool Disposed {
			get { return disposed; }
		}

		public QtSupport QParent {
			get { return qparent; }
		}

		public ArrayList QChildren {
			get { return qchildren; }
		}

		// A dummy constructor for inherited classes
		internal QtSupport (QNull dummy) {
			disposed = false;
			deleted = false;
			qchildren = new ArrayList ();
		}

		public void Dispose ()
		{
			GC.SuppressFinalize (this);
			Dispose (true);
		}

		protected virtual void Dispose (bool disposeManaged)
		{
			if (disposed)
				return;

			if (rawObject == IntPtr.Zero)
				deleted = true;

			if (disposeManaged) {
				disposed = true;

				UnregisterObject (this);

				if (qparent != null && ! qparent.Disposed)
					qparent.RemoveChild (this);

				foreach (QtSupport qts in qchildren)
					qts.Dispose ();
			}

			/*
			DbgMsg ("({0}) {1}: {2} managed. {3} native instance.",
				deleted ? IntPtr.Zero : rawObject,
				this,
				disposeManaged ? "Disposing" : "Not disposing",
				deleted ? "Not deleting" : "Deleting");
			*/

			qparent = null;
			qchildren = null;

			Delete ();
		}

		internal virtual void Delete ()
		{
			WarnMsg ("({0}) {1}: QtSupport.Dispose() running", rawObject, this);
			deleted = true;
		}

		/************************** General Utility Methods *********************************/

		public static void QAssert (bool value)
		{
			if (!value) throw new ApplicationException ("Assertion failed");
		}

		public static void QAssert (bool value, string message)
		{
			if (!value) throw new ApplicationException ("Assertion failed: " + message);
		}

		internal bool IsQObject ()
		{
			return GetType ().IsSubclassOf (typeof (QObject));
		}

		internal static void WarnMsg (string format, params object[] arg)
		{
			if (enableDebug)
				Console.Error.WriteLine ("Qt# Warning: " + format, arg);
		}

		internal static void DbgMsg (string format, params object[] arg)
		{
			if (enableDebug) Console.WriteLine (format, arg);
		}

		internal static void ErrMsg (string format, params object[] arg)
		{
			Console.Error.WriteLine (format, arg);
		}

		internal static void Msg (string format, params object[] arg)
		{
			Console.WriteLine (format, arg);
		}

		public static string SIGNAL (string signal)
		{
			return "2"+
				Regex.Replace (signal, @"\s*\(\s*\)", "()");
			

		}

		public static string SLOT (string slot)
		{
			return "1" + 
				Regex.Replace (slot, @"\s*\(\s*\)", "()");
		}

		/************************** Object Tracking/Boxing and Disposal *********************************/

		internal static void RegisterObject (QtSupport o)
		{
			if (disableTracking) return;

			if (o.RawObject == IntPtr.Zero) {
				WarnMsg ("Asked to register object with null pointer: {0}", o);
				return;
			}

			string replacing = String.Empty;
			WeakReference wref;

			if (QtObjects.ContainsKey (o.RawObject))
			{
				wref = QtObjects[o.RawObject] as WeakReference;
				QAssert (! wref.IsAlive,
					"New object "+o+" has same RawObject as "+(QtSupport)wref.Target+"! Please report this error!");
				replacing = "(replacing)";
				QtObjects.Remove (o.RawObject);
			}

			if (traceObjects)
				ErrMsg ("Object Registered: {0} ({1}) {2}", o, o.RawObject, replacing);

			QtObjects[o.RawObject] = new WeakReference (o);

			if (cleanCount > cleanLimit) {
				cleanCount = 0;
				IDictionaryEnumerator de = QtObjects.GetEnumerator ();
				ArrayList obituaries = new ArrayList ();

				while (de.MoveNext ()) {
					wref = de.Value as WeakReference;
					if (!wref.IsAlive) obituaries.Add (de.Key);
				}

				if (traceObjects)
					ErrMsg ("RegisterObject: Removing {0} of {1} references from QtObjects", obituaries.Count, QtObjects.Count);

				foreach (IntPtr p in obituaries)
					QtObjects.Remove (p);
			}
			else
				cleanCount++;
		}

		internal static void UnregisterObject (QtSupport o)
		{
			if (disableTracking) return;
			if (traceObjects) ErrMsg ("Object Unregistered: {0} ({1})", o, o.RawObject);

			if (o.RawObject == IntPtr.Zero) {
				WarnMsg ("Asked to unregister object with null pointer: {0}", o);
				return;
			}

			QtObjects.Remove (o.RawObject);
		}

		internal static QtSupport LookupObject (IntPtr ptr)
		{
			if (disableTracking) return null;

			if (ptr == IntPtr.Zero) {
				WarnMsg ("Asked to lookup null pointer");
				return null;
			}

			QtSupport ret = null;

			if (QtObjects.ContainsKey (ptr)) {
				WeakReference wref = QtObjects[ptr] as WeakReference;
				if (wref.IsAlive)
					ret = wref.Target as QtSupport;
				else
					QtObjects.Remove (ptr);
			}

			return ret;
		}

		internal static QtSupport LookupObject (IntPtr ptr, Type type)
		{
			if (ptr == IntPtr.Zero) {
				WarnMsg ("Asked to lookup null pointer of type {0}", type);
				return null;
			}

			if (! (type.IsSubclassOf (typeof(QtSupport)) || type == typeof (QtSupport)) )
				throw new ArgumentException ("Type '" +type+ "' is not related to QtSupport.");

			QtSupport qtsObj = LookupObject (ptr);

			if (qtsObj == null) {
				//DbgMsg (type+" ("+ptr+"): Boxing foreign object");
				qtsObj = (QtSupport)Activator.CreateInstance (
					type,
					BindingFlags.NonPublic | BindingFlags.Instance,
					null,
					new object[] {ptr},
					null);
				
				// FIXME Must handle cases where qtsObj is a QObject root
				// or child. Should we box the entire object tree in
				// C#? Also, RegisterObject will only track this object
				// if it is a root node. Child nodes are assumed to be
				// referenced by their parents. Must ponder and seek
				// opinions.
			}

			return qtsObj;
		}

		internal virtual void AddChild (QtSupport o) {
			// FIXME: Faster way to do this? O(n), where n == Count
			if (!qchildren.Contains(o)) {
				qchildren.Add(o);
				if (traceChildren)
					ErrMsg ("({0}) {1}::AddChild: ({2}) {3}", rawObject, this, o.RawObject, o);
			}
		}

		internal virtual void RemoveChild (QtSupport o) {
			// FIXME: Faster way to do this? O(n), where n == Count
			if (qchildren.Contains(o)) {
				qchildren.Remove(o);
				if (traceChildren)
					ErrMsg ("({0}) {1}::RemoveChild: ({2}) {3}", rawObject, this, o.RawObject, o);
			}
		}

		/************************** The Event Handler ******************************************/

		private delegate void QtEventHandler (IntPtr instance, string eventname, IntPtr eventinstance, string eventclass);

		private static QEventList eventList = new QEventList ();

		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
	        private static extern void qtsharp_QObject_registerEventDelegate
			([MarshalAs (UnmanagedType.FunctionPtr)] Delegate qtdelegate);

		internal static void RegisterEventDelegate ()
		{
			qtEventHandler = new QtEventHandler (DispatchEvent);
			qtsharp_QObject_registerEventDelegate (qtEventHandler);
		}

		internal static QEventList EventList {
  			get { return eventList; }
		}

		private static void DispatchEvent (IntPtr instance, string eventname, IntPtr eventinstance, string eventclass)
		{
			ArrayList array;
			QObject obj;
			QEvent ev;
			Type evtype = Type.GetType ("Qt."+eventclass+",Qt");

			if ((obj = (QObject)LookupObject (instance)) == null) return;

			try
			{
				if ((ev = (QEvent)LookupObject (eventinstance)) == null) {
					object[] args = new object[] { eventinstance };
					BindingFlags bflags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
					ev = Activator.CreateInstance (evtype, bflags, null, args, null) as QEvent;
				}

				// Notify global event handlers first.
				if ((array = EventList.QEventHandlers (eventclass)) != null) {
					foreach (Delegate del in array) {
						QEventArgs evargs = new QEventArgs (eventname, ev);
						del.DynamicInvoke (new object[] { obj, evargs });
					}
				}

				// Notify local event handlers second.
				if ((array = EventList.QEventHandlers (eventname)) != null) {
					foreach (Delegate del in array) {
						if (ReferenceEquals (del.Target, obj))
							del.DynamicInvoke (new object[] { ev });
					}
				}
			}
			catch (TargetInvocationException e) {
				throw e.InnerException;
			}

			ev.deleted = true; // Qt deletes events for us
			ev.Dispose ();
		}

		// Global events.
		public static event QChildHandler childHandler {
			add		{ EventList.Add 	("QChildEvent", value); }
			remove	{ EventList.Remove	("QChildEvent", value); }
		}
		public static event QDragEnterHandler dragEnterHandler {
			add		{ EventList.Add 	("QDragEnterEvent", value); }
			remove	{ EventList.Remove	("QDragEnterEvent", value); }
		}
		public static event QDropHandler dropHandler {
			add		{ EventList.Add 	("QDropEvent", value); }
			remove	{ EventList.Remove	("QDropEvent", value); }
		}
		public static event QIMHandler imHandler {
			add		{ EventList.Add 	("QIMEvent", value); }
			remove	{ EventList.Remove	("QIMEvent", value); }
		}
		public static event QPaintHandler paintHandler {
			add		{ EventList.Add 	("QPaintEvent", value); }
			remove	{ EventList.Remove	("QPaintEvent", value); }
		}
		public static event QTimerHandler timerHandler {
			add		{ EventList.Add 	("QTimerEvent", value); }
			remove	{ EventList.Remove	("QTimerEvent", value); }
		}
		public static event QCloseHandler closeHandler {
			add		{ EventList.Add 	("QCloseEvent", value); }
			remove	{ EventList.Remove	("QCloseEvent", value); }
		}
		public static event QDragLeaveHandler dragLeaveHandler {
			add		{ EventList.Add 	("QDragLeaveEvent", value); }
			remove	{ EventList.Remove	("QDragLeaveEvent", value); }
		}
		public static event QEventHandler eventHandler {
			add		{ EventList.Add 	("QEventEvent", value); }
			remove	{ EventList.Remove	("QEventEvent", value); }
		}
		public static event QKeyHandler keyHandler {
			add		{ EventList.Add 	("QKeyEvent", value); }
			remove	{ EventList.Remove	("QKeyEvent", value); }
		}
		public static event QResizeHandler resizeHandler {
			add		{ EventList.Add 	("QResizeEvent", value); }
			remove	{ EventList.Remove	("QResizeEvent", value); }
		}
		public static event QWheelHandler wheelHandler {
			add		{ EventList.Add 	("QWheelEvent", value); }
			remove	{ EventList.Remove	("QWheelEvent", value); }
		}
		public static event QContextMenuHandler contextMenuHandler {
			add		{ EventList.Add 	("QContextMenuEvent", value); }
			remove	{ EventList.Remove	("QContextMenuEvent", value); }
		}
		public static event QDragMoveHandler dragMoveHandler {
			add		{ EventList.Add 	("QDragMoveEvent", value); }
			remove	{ EventList.Remove	("QDragMoveEvent", value); }
		}
		public static event QFocusHandler focusHandler {
			add		{ EventList.Add 	("QFocusEvent", value); }
			remove	{ EventList.Remove	("QFocusEvent", value); }
		}
		public static event QMouseHandler mouseHandler {
			add		{ EventList.Add 	("QMouseEvent", value); }
			remove	{ EventList.Remove	("QMouseEvent", value); }
		}
		public static event QShowHandler showHandler {
			add		{ EventList.Add 	("QShowEvent", value); }
			remove	{ EventList.Remove	("QShowEvent", value); }
		}
		public static event QCustomHandler customHandler {
			add		{ EventList.Add 	("QCustomEvent", value); }
			remove	{ EventList.Remove	("QCustomEvent", value); }
		}
		public static event QDragResponseHandler dragResponseHandler {
			add		{ EventList.Add 	("QDragResponseEvent", value); }
			remove	{ EventList.Remove	("QDragResponseEvent", value); }
		}
		public static event QHideHandler hideHandler {
			add		{ EventList.Add 	("QHideEvent", value); }
			remove	{ EventList.Remove	("QHideEvent", value); }
		}
		public static event QMoveHandler moveHandler {
			add		{ EventList.Add 	("QMoveEvent", value); }
			remove	{ EventList.Remove	("QMoveEvent", value); }
		}
		public static event QTabletHandler tabletHandler {
			add		{ EventList.Add 	("QTabletEvent", value); }
			remove	{ EventList.Remove	("QTabletEvent", value); }
		}

		// Local events.
		protected static event ChildEvent childEvent {
			add		{ EventList.Add 	("childEvent", value); }
			remove	{ EventList.Remove	("childEvent", value); }
		}
		protected static event CloseEvent closeEvent {
			add		{ EventList.Add 	("closeEvent", value); }
			remove	{ EventList.Remove	("closeEvent", value); }
		}
		protected static event ContentsContextMenuEvent contentsContextMenuEvent {
			add		{ EventList.Add 	("contentsContextMenuEvent", value); }
			remove	{ EventList.Remove	("contentsContextMenuEvent", value); }
		}
		protected static event ContentsDragEnterEvent contentsDragEnterEvent {
			add		{ EventList.Add 	("contentsDragEnterEvent", value); }
			remove	{ EventList.Remove	("contentsDragEnterEvent", value); }
		}
		protected static event ContentsDragLeaveEvent contentsDragLeaveEvent {
			add		{ EventList.Add 	("contentsDragLeaveEvent", value); }
			remove	{ EventList.Remove	("contentsDragLeaveEvent", value); }
		}
		protected static event ContentsDragMoveEvent contentsDragMoveEvent {
			add		{ EventList.Add 	("contentsDragMoveEvent", value); }
			remove	{ EventList.Remove	("contentsDragMoveEvent", value); }
		}
		protected static event ContentsDropEvent contentsDropEvent {
			add		{ EventList.Add 	("contentsDropEvent", value); }
			remove	{ EventList.Remove	("contentsDropEvent", value); }
		}
		protected static event ContentsMouseDoubleClickEvent contentsMouseDoubleClickEvent {
			add		{ EventList.Add 	("contentsMouseDoubleClickEvent", value); }
			remove	{ EventList.Remove	("contentsMouseDoubleClickEvent", value); }
		}
		protected static event ContentsMouseMoveEvent contentsMouseMoveEvent {
			add		{ EventList.Add 	("contentsMouseMoveEvent", value); }
			remove	{ EventList.Remove	("contentsMouseMoveEvent", value); }
		}
		protected static event ContentsMousePressEvent contentsMousePressEvent {
			add		{ EventList.Add 	("contentsMousePressEvent", value); }
			remove	{ EventList.Remove	("contentsMousePressEvent", value); }
		}
		protected static event ContentsMouseReleaseEvent contentsMouseReleaseEvent {
			add		{ EventList.Add 	("contentsMouseReleaseEvent", value); }
			remove	{ EventList.Remove	("contentsMouseReleaseEvent", value); }
		}
		protected static event ContentsWheelEvent contentsWheelEvent {
			add		{ EventList.Add 	("contentsWheelEvent", value); }
			remove	{ EventList.Remove	("contentsWheelEvent", value); }
		}
		protected static event ContextMenuEvent contextMenuEvent {
			add		{ EventList.Add 	("contextMenuEvent", value); }
			remove	{ EventList.Remove	("contextMenuEvent", value); }
		}
		protected static event CustomEvent customEvent {
			add		{ EventList.Add 	("customEvent", value); }
			remove	{ EventList.Remove	("customEvent", value); }
		}
		protected static event DragEnterEvent dragEnterEvent {
			add		{ EventList.Add 	("dragEnterEvent", value); }
			remove	{ EventList.Remove	("dragEnterEvent", value); }
		}
		protected static event DragLeaveEvent dragLeaveEvent {
			add		{ EventList.Add 	("dragLeaveEvent", value); }
			remove	{ EventList.Remove	("dragLeaveEvent", value); }
		}
		protected static event DragMoveEvent dragMoveEvent {
			add		{ EventList.Add 	("dragMoveEvent", value); }
			remove	{ EventList.Remove	("dragMoveEvent", value); }
		}
		protected static event DropEvent dropEvent {
			add		{ EventList.Add 	("dropEvent", value); }
			remove	{ EventList.Remove	("dropEvent", value); }
		}
		protected static event EnterEvent enterEvent {
			add		{ EventList.Add 	("enterEvent", value); }
			remove	{ EventList.Remove	("enterEvent", value); }
		}
		protected static event FocusInEvent focusInEvent {
			add		{ EventList.Add 	("focusInEvent", value); }
			remove	{ EventList.Remove	("focusInEvent", value); }
		}
		protected static event FocusOutEvent focusOutEvent {
			add		{ EventList.Add 	("focusOutEvent", value); }
			remove	{ EventList.Remove	("focusOutEvent", value); }
		}
		protected static event HideEvent hideEvent {
			add		{ EventList.Add 	("hideEvent", value); }
			remove	{ EventList.Remove	("hideEvent", value); }
		}
		protected static event IMComposeEvent imComposeEvent {
			add		{ EventList.Add 	("imComposeEvent", value); }
			remove	{ EventList.Remove	("imComposeEvent", value); }
		}
		protected static event IMEndEvent imEndEvent {
			add		{ EventList.Add 	("imEndEvent", value); }
			remove	{ EventList.Remove	("imEndEvent", value); }
		}
		protected static event IMStartEvent imStartEvent {
			add		{ EventList.Add 	("imStartEvent", value); }
			remove	{ EventList.Remove	("imStartEvent", value); }
		}
		protected static event KeyPressEvent keyPressEvent {
			add		{ EventList.Add 	("keyPressEvent", value); }
			remove	{ EventList.Remove	("keyPressEvent", value); }
		}
		protected static event KeyReleaseEvent keyReleaseEvent {
			add		{ EventList.Add 	("keyReleaseEvent", value); }
			remove	{ EventList.Remove	("keyReleaseEvent", value); }
		}
		protected static event LeaveEvent leaveEvent {
			add		{ EventList.Add 	("leaveEvent", value); }
			remove	{ EventList.Remove	("leaveEvent", value); }
		}
		protected static event MouseDoubleClickEvent mouseDoubleClickEvent {
			add		{ EventList.Add 	("mouseDoubleClickEvent", value); }
			remove	{ EventList.Remove	("mouseDoubleClickEvent", value); }
		}
		protected static event MouseMoveEvent mouseMoveEvent {
			add		{ EventList.Add 	("mouseMoveEvent", value); }
			remove	{ EventList.Remove	("mouseMoveEvent", value); }
		}
		protected static event MousePressEvent mousePressEvent {
			add		{ EventList.Add 	("mousePressEvent", value); }
			remove	{ EventList.Remove	("mousePressEvent", value); }
		}
		protected static event MouseReleaseEvent mouseReleaseEvent {
			add		{ EventList.Add 	("mouseReleaseEvent", value); }
			remove	{ EventList.Remove	("mouseReleaseEvent", value); }
		}
		protected static event MoveEvent moveEvent {
			add		{ EventList.Add 	("moveEvent", value); }
			remove	{ EventList.Remove	("moveEvent", value); }
		}
		protected static event PaintEvent paintEvent {
			add		{ EventList.Add 	("paintEvent", value); }
			remove	{ EventList.Remove	("paintEvent", value); }
		}
		protected static event ResizeEvent resizeEvent {
			add		{ EventList.Add 	("resizeEvent", value); }
			remove	{ EventList.Remove	("resizeEvent", value); }
		}
		protected static event ShowEvent showEvent {
			add		{ EventList.Add 	("showEvent", value); }
			remove	{ EventList.Remove	("showEvent", value); }
		}
		protected static event TabletEvent tabletEvent {
			add		{ EventList.Add 	("tabletEvent", value); }
			remove	{ EventList.Remove	("tabletEvent", value); }
		}
		protected static event TimerEvent timerEvent {
			add		{ EventList.Add 	("timerEvent", value); }
			remove	{ EventList.Remove	("timerEvent", value); }
		}
		protected static event ViewportContextMenuEvent viewportContextMenuEvent {
			add		{ EventList.Add 	("viewportContextMenuEvent", value); }
			remove	{ EventList.Remove	("viewportContextMenuEvent", value); }
		}
		protected static event ViewportDragEnterEvent viewportDragEnterEvent {
			add		{ EventList.Add 	("viewportDragEnterEvent", value); }
			remove	{ EventList.Remove	("viewportDragEnterEvent", value); }
		}
		protected static event ViewportDragLeaveEvent viewportDragLeaveEvent {
			add		{ EventList.Add 	("viewportDragLeaveEvent", value); }
			remove	{ EventList.Remove	("viewportDragLeaveEvent", value); }
		}
		protected static event ViewportDragMoveEvent viewportDragMoveEvent {
			add		{ EventList.Add 	("viewportDragMoveEvent", value); }
			remove	{ EventList.Remove	("viewportDragMoveEvent", value); }
		}
		protected static event ViewportDropEvent viewportDropEvent {
			add		{ EventList.Add 	("viewportDropEvent", value); }
			remove	{ EventList.Remove	("viewportDropEvent", value); }
		}
		protected static event ViewportMouseDoubleClickEvent viewportMouseDoubleClickEvent {
			add		{ EventList.Add 	("viewportMouseDoubleClickEvent", value); }
			remove	{ EventList.Remove	("viewportMouseDoubleClickEvent", value); }
		}
		protected static event ViewportMouseMoveEvent viewportMouseMoveEvent {
			add		{ EventList.Add 	("viewportMouseMoveEvent", value); }
			remove	{ EventList.Remove	("viewportMouseMoveEvent", value); }
		}
		protected static event ViewportMousePressEvent viewportMousePressEvent {
			add		{ EventList.Add 	("viewportMousePressEvent", value); }
			remove	{ EventList.Remove	("viewportMousePressEvent", value); }
		}
		protected static event ViewportMouseReleaseEvent viewportMouseReleaseEvent {
			add		{ EventList.Add 	("viewportMouseReleaseEvent", value); }
			remove	{ EventList.Remove	("viewportMouseReleaseEvent", value); }
		}
		protected static event ViewportPaintEvent viewportPaintEvent {
			add		{ EventList.Add 	("viewportPaintEvent", value); }
			remove	{ EventList.Remove	("viewportPaintEvent", value); }
		}
		protected static event ViewportResizeEvent viewportResizeEvent {
			add		{ EventList.Add 	("viewportResizeEvent", value); }
			remove	{ EventList.Remove	("viewportResizeEvent", value); }
		}
		protected static event ViewportWheelEvent viewportWheelEvent {
			add		{ EventList.Add 	("viewportWheelEvent", value); }
			remove	{ EventList.Remove	("viewportWheelEvent", value); }
		}
		protected static event WheelEvent wheelEvent {
			add		{ EventList.Add 	("wheelEvent", value); }
			remove	{ EventList.Remove	("wheelEvent", value); }
		}

		// The local event delegates.
		protected delegate void ChildEvent (QChildEvent e);
		protected delegate void CloseEvent (QCloseEvent e);
		protected delegate void ContentsContextMenuEvent (QContextMenuEvent e);
		protected delegate void ContentsDragEnterEvent (QDragEnterEvent e);
		protected delegate void ContentsDragLeaveEvent (QDragLeaveEvent e);
		protected delegate void ContentsDragMoveEvent (QDragMoveEvent e);
		protected delegate void ContentsDropEvent (QDropEvent e);
		protected delegate void ContentsMouseDoubleClickEvent (QMouseEvent e);
		protected delegate void ContentsMouseMoveEvent (QMouseEvent e);
		protected delegate void ContentsMousePressEvent (QMouseEvent e);
		protected delegate void ContentsMouseReleaseEvent (QMouseEvent e);
		protected delegate void ContentsWheelEvent (QWheelEvent e);
		protected delegate void ContextMenuEvent (QContextMenuEvent e);
		protected delegate void CustomEvent (QCustomEvent e);
		protected delegate void DragEnterEvent (QDragEnterEvent e);
		protected delegate void DragLeaveEvent (QDragLeaveEvent e);
		protected delegate void DragMoveEvent (QDragMoveEvent e);
		protected delegate void DropEvent (QDropEvent e);
		protected delegate void EnterEvent (QEvent e);
		protected delegate void FocusInEvent (QFocusEvent e);
		protected delegate void FocusOutEvent (QFocusEvent e);
		protected delegate void HideEvent (QHideEvent e);
		protected delegate void IMComposeEvent (QIMEvent e);
		protected delegate void IMEndEvent (QIMEvent e);
		protected delegate void IMStartEvent (QIMEvent e);
		protected delegate void KeyPressEvent (QKeyEvent e);
		protected delegate void KeyReleaseEvent (QKeyEvent e);
		protected delegate void LeaveEvent (QEvent e);
		protected delegate void MouseDoubleClickEvent (QMouseEvent e);
		protected delegate void MouseMoveEvent (QMouseEvent e);
		protected delegate void MousePressEvent (QMouseEvent e);
		protected delegate void MouseReleaseEvent (QMouseEvent e);
		protected delegate void MoveEvent (QMoveEvent e);
		protected delegate void PaintEvent (QPaintEvent e);
		protected delegate void ResizeEvent (QResizeEvent e);
		protected delegate void ShowEvent (QShowEvent e);
		protected delegate void TabletEvent (QTabletEvent e);
		protected delegate void TimerEvent (QTimerEvent e);
		protected delegate void ViewportContextMenuEvent (QContextMenuEvent e);
		protected delegate void ViewportDragEnterEvent (QDragEnterEvent e);
		protected delegate void ViewportDragLeaveEvent (QDragLeaveEvent e);
		protected delegate void ViewportDragMoveEvent (QDragMoveEvent e);
		protected delegate void ViewportDropEvent (QDropEvent e);
		protected delegate void ViewportMouseDoubleClickEvent (QMouseEvent e);
		protected delegate void ViewportMouseMoveEvent (QMouseEvent e);
		protected delegate void ViewportMousePressEvent (QMouseEvent e);
		protected delegate void ViewportMouseReleaseEvent (QMouseEvent e);
		protected delegate void ViewportPaintEvent (QPaintEvent e);
		protected delegate void ViewportResizeEvent (QResizeEvent e);
		protected delegate void ViewportWheelEvent (QWheelEvent e);
		protected delegate void WheelEvent (QWheelEvent e);
	}


	// The global event delegates.
	public delegate void QChildHandler (QObject sender, QEventArgs e);
	public delegate void QDragEnterHandler (QObject sender, QEventArgs e);
	public delegate void QDropHandler (QObject sender, QEventArgs e);
	public delegate void QIMHandler (QObject sender, QEventArgs e);
	public delegate void QPaintHandler (QObject sender, QEventArgs e);
	public delegate void QTimerHandler (QObject sender, QEventArgs e);
	public delegate void QCloseHandler (QObject sender, QEventArgs e);
	public delegate void QDragLeaveHandler (QObject sender, QEventArgs e);
	public delegate void QEventHandler (QObject sender, QEventArgs e);
	public delegate void QKeyHandler (QObject sender, QEventArgs e);
	public delegate void QResizeHandler (QObject sender, QEventArgs e);
	public delegate void QWheelHandler (QObject sender, QEventArgs e);
	public delegate void QContextMenuHandler (QObject sender, QEventArgs e);
	public delegate void QDragMoveHandler (QObject sender, QEventArgs e);
	public delegate void QFocusHandler (QObject sender, QEventArgs e);
	public delegate void QMouseHandler (QObject sender, QEventArgs e);
	public delegate void QShowHandler (QObject sender, QEventArgs e);
	public delegate void QCustomHandler (QObject sender, QEventArgs e);
	public delegate void QDragResponseHandler (QObject sender, QEventArgs e);
	public delegate void QHideHandler (QObject sender, QEventArgs e);
	public delegate void QMoveHandler (QObject sender, QEventArgs e);
	public delegate void QTabletHandler (QObject sender, QEventArgs e);
}
