// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 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 TQApplication.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 TQParent {
			get { return qparent; }
		}

		public ArrayList TQChildren {
			get { return qchildren; }
		}

		// A dummy constructor for inherited classes
		internal QtSupport (TQNull 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 TQAssert (bool value)
		{
			if (!value) throw new ApplicationException ("Assertion failed");
		}

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

		internal bool IsTQObject ()
		{
			return GetType ().IsSubclassOf (typeof (TQObject));
		}

		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 TQ_SIGNAL (string signal)
		{
			return "2"+
				Regex.Replace (signal, @"\s*\(\s*\)", "()");
			

		}

		public static string TQ_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;
				TQAssert (! 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 TQObject 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 TQEventList eventList = new TQEventList ();

		[DllImport("libtqtsharp", 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 TQEventList EventList {
  			get { return eventList; }
		}

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

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

			try
			{
				if ((ev = (TQEvent)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 TQEvent;
				}

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

				// Notify local event handlers second.
				if ((array = EventList.TQEventHandlers (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 TQChildHandler childHandler {
			add		{ EventList.Add 	("TQChildEvent", value); }
			remove	{ EventList.Remove	("TQChildEvent", value); }
		}
		public static event TQDragEnterHandler dragEnterHandler {
			add		{ EventList.Add 	("TQDragEnterEvent", value); }
			remove	{ EventList.Remove	("TQDragEnterEvent", value); }
		}
		public static event TQDropHandler dropHandler {
			add		{ EventList.Add 	("TQDropEvent", value); }
			remove	{ EventList.Remove	("TQDropEvent", value); }
		}
		public static event TQIMHandler imHandler {
			add		{ EventList.Add 	("TQIMEvent", value); }
			remove	{ EventList.Remove	("TQIMEvent", value); }
		}
		public static event TQPaintHandler paintHandler {
			add		{ EventList.Add 	("TQPaintEvent", value); }
			remove	{ EventList.Remove	("TQPaintEvent", value); }
		}
		public static event TQTimerHandler timerHandler {
			add		{ EventList.Add 	("TQTimerEvent", value); }
			remove	{ EventList.Remove	("TQTimerEvent", value); }
		}
		public static event TQCloseHandler closeHandler {
			add		{ EventList.Add 	("TQCloseEvent", value); }
			remove	{ EventList.Remove	("TQCloseEvent", value); }
		}
		public static event TQDragLeaveHandler dragLeaveHandler {
			add		{ EventList.Add 	("TQDragLeaveEvent", value); }
			remove	{ EventList.Remove	("TQDragLeaveEvent", value); }
		}
		public static event TQEventHandler eventHandler {
			add		{ EventList.Add 	("TQEventEvent", value); }
			remove	{ EventList.Remove	("TQEventEvent", value); }
		}
		public static event TQKeyHandler keyHandler {
			add		{ EventList.Add 	("TQKeyEvent", value); }
			remove	{ EventList.Remove	("TQKeyEvent", value); }
		}
		public static event TQResizeHandler resizeHandler {
			add		{ EventList.Add 	("TQResizeEvent", value); }
			remove	{ EventList.Remove	("TQResizeEvent", value); }
		}
		public static event TQWheelHandler wheelHandler {
			add		{ EventList.Add 	("TQWheelEvent", value); }
			remove	{ EventList.Remove	("TQWheelEvent", value); }
		}
		public static event TQContextMenuHandler contextMenuHandler {
			add		{ EventList.Add 	("TQContextMenuEvent", value); }
			remove	{ EventList.Remove	("TQContextMenuEvent", value); }
		}
		public static event TQDragMoveHandler dragMoveHandler {
			add		{ EventList.Add 	("TQDragMoveEvent", value); }
			remove	{ EventList.Remove	("TQDragMoveEvent", value); }
		}
		public static event TQFocusHandler focusHandler {
			add		{ EventList.Add 	("TQFocusEvent", value); }
			remove	{ EventList.Remove	("TQFocusEvent", value); }
		}
		public static event TQMouseHandler mouseHandler {
			add		{ EventList.Add 	("TQMouseEvent", value); }
			remove	{ EventList.Remove	("TQMouseEvent", value); }
		}
		public static event TQShowHandler showHandler {
			add		{ EventList.Add 	("TQShowEvent", value); }
			remove	{ EventList.Remove	("TQShowEvent", value); }
		}
		public static event TQCustomHandler customHandler {
			add		{ EventList.Add 	("TQCustomEvent", value); }
			remove	{ EventList.Remove	("TQCustomEvent", value); }
		}
		public static event TQDragResponseHandler dragResponseHandler {
			add		{ EventList.Add 	("TQDragResponseEvent", value); }
			remove	{ EventList.Remove	("TQDragResponseEvent", value); }
		}
		public static event TQHideHandler hideHandler {
			add		{ EventList.Add 	("TQHideEvent", value); }
			remove	{ EventList.Remove	("TQHideEvent", value); }
		}
		public static event TQMoveHandler moveHandler {
			add		{ EventList.Add 	("TQMoveEvent", value); }
			remove	{ EventList.Remove	("TQMoveEvent", value); }
		}
		public static event TQTabletHandler tabletHandler {
			add		{ EventList.Add 	("TQTabletEvent", value); }
			remove	{ EventList.Remove	("TQTabletEvent", 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 (TQChildEvent e);
		protected delegate void CloseEvent (TQCloseEvent e);
		protected delegate void ContentsContextMenuEvent (TQContextMenuEvent e);
		protected delegate void ContentsDragEnterEvent (TQDragEnterEvent e);
		protected delegate void ContentsDragLeaveEvent (TQDragLeaveEvent e);
		protected delegate void ContentsDragMoveEvent (TQDragMoveEvent e);
		protected delegate void ContentsDropEvent (TQDropEvent e);
		protected delegate void ContentsMouseDoubleClickEvent (TQMouseEvent e);
		protected delegate void ContentsMouseMoveEvent (TQMouseEvent e);
		protected delegate void ContentsMousePressEvent (TQMouseEvent e);
		protected delegate void ContentsMouseReleaseEvent (TQMouseEvent e);
		protected delegate void ContentsWheelEvent (TQWheelEvent e);
		protected delegate void ContextMenuEvent (TQContextMenuEvent e);
		protected delegate void CustomEvent (TQCustomEvent e);
		protected delegate void DragEnterEvent (TQDragEnterEvent e);
		protected delegate void DragLeaveEvent (TQDragLeaveEvent e);
		protected delegate void DragMoveEvent (TQDragMoveEvent e);
		protected delegate void DropEvent (TQDropEvent e);
		protected delegate void EnterEvent (TQEvent e);
		protected delegate void FocusInEvent (TQFocusEvent e);
		protected delegate void FocusOutEvent (TQFocusEvent e);
		protected delegate void HideEvent (TQHideEvent e);
		protected delegate void IMComposeEvent (TQIMEvent e);
		protected delegate void IMEndEvent (TQIMEvent e);
		protected delegate void IMStartEvent (TQIMEvent e);
		protected delegate void KeyPressEvent (TQKeyEvent e);
		protected delegate void KeyReleaseEvent (TQKeyEvent e);
		protected delegate void LeaveEvent (TQEvent e);
		protected delegate void MouseDoubleClickEvent (TQMouseEvent e);
		protected delegate void MouseMoveEvent (TQMouseEvent e);
		protected delegate void MousePressEvent (TQMouseEvent e);
		protected delegate void MouseReleaseEvent (TQMouseEvent e);
		protected delegate void MoveEvent (TQMoveEvent e);
		protected delegate void PaintEvent (TQPaintEvent e);
		protected delegate void ResizeEvent (TQResizeEvent e);
		protected delegate void ShowEvent (TQShowEvent e);
		protected delegate void TabletEvent (TQTabletEvent e);
		protected delegate void TimerEvent (TQTimerEvent e);
		protected delegate void ViewportContextMenuEvent (TQContextMenuEvent e);
		protected delegate void ViewportDragEnterEvent (TQDragEnterEvent e);
		protected delegate void ViewportDragLeaveEvent (TQDragLeaveEvent e);
		protected delegate void ViewportDragMoveEvent (TQDragMoveEvent e);
		protected delegate void ViewportDropEvent (TQDropEvent e);
		protected delegate void ViewportMouseDoubleClickEvent (TQMouseEvent e);
		protected delegate void ViewportMouseMoveEvent (TQMouseEvent e);
		protected delegate void ViewportMousePressEvent (TQMouseEvent e);
		protected delegate void ViewportMouseReleaseEvent (TQMouseEvent e);
		protected delegate void ViewportPaintEvent (TQPaintEvent e);
		protected delegate void ViewportResizeEvent (TQResizeEvent e);
		protected delegate void ViewportWheelEvent (TQWheelEvent e);
		protected delegate void WheelEvent (TQWheelEvent e);
	}


	// The global event delegates.
	public delegate void TQChildHandler (TQObject sender, TQEventArgs e);
	public delegate void TQDragEnterHandler (TQObject sender, TQEventArgs e);
	public delegate void TQDropHandler (TQObject sender, TQEventArgs e);
	public delegate void TQIMHandler (TQObject sender, TQEventArgs e);
	public delegate void TQPaintHandler (TQObject sender, TQEventArgs e);
	public delegate void TQTimerHandler (TQObject sender, TQEventArgs e);
	public delegate void TQCloseHandler (TQObject sender, TQEventArgs e);
	public delegate void TQDragLeaveHandler (TQObject sender, TQEventArgs e);
	public delegate void TQEventHandler (TQObject sender, TQEventArgs e);
	public delegate void TQKeyHandler (TQObject sender, TQEventArgs e);
	public delegate void TQResizeHandler (TQObject sender, TQEventArgs e);
	public delegate void TQWheelHandler (TQObject sender, TQEventArgs e);
	public delegate void TQContextMenuHandler (TQObject sender, TQEventArgs e);
	public delegate void TQDragMoveHandler (TQObject sender, TQEventArgs e);
	public delegate void TQFocusHandler (TQObject sender, TQEventArgs e);
	public delegate void TQMouseHandler (TQObject sender, TQEventArgs e);
	public delegate void TQShowHandler (TQObject sender, TQEventArgs e);
	public delegate void TQCustomHandler (TQObject sender, TQEventArgs e);
	public delegate void TQDragResponseHandler (TQObject sender, TQEventArgs e);
	public delegate void TQHideHandler (TQObject sender, TQEventArgs e);
	public delegate void TQMoveHandler (TQObject sender, TQEventArgs e);
	public delegate void TQTabletHandler (TQObject sender, TQEventArgs e);
}
