// QtSignal.cs - Signal/slot connection support for Qt#
//
// Copyright (C) 2002  Nick Zigarovich (nick@chemlab.org)
//
// 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.
//
// TODO
// o See about eliminating huge ConnectSignalTo* DisconnectSignalFrom* methods;
//   want to make methods for each connection case that deal with QtSignal and
//   QtSlot instances directly.
//

namespace Qt {
	using System;
	using System.Collections;
	using System.Runtime.InteropServices;
	using System.Reflection;

	internal class QtSignal: TQObject, IDisposable {
		internal static bool traceConnects;

		static QtSignal ()
		{
			traceConnects = false;
		}

		private TQObject sender;
		private string signal;
		private string name;
		private string args;
		private ArrayList slots;
		private ArrayList signals;

		public string Identifier {
			get { return MakeSigId(sender, signal); }
		}

		public TQObject Sender {
			get { return sender; }
		}

		public string Signal {
			get { return signal; }
		}

		public string Name {
			get { return name; }
		}

		public string Args {
			get { return args; }
		}

		public string MangledArgs {
			get { return MangleArgs(Args); }
		}

		public ArrayList Signals {
			get { return signals; }
		}

		public ArrayList Slots {
			get { return slots; }
		}

		public QtSignal (TQObject sender, string signal): base (NoSignalInit.Instance)
		{
			this.sender = sender;
			this.signal = signal;
			string[] sigspl = signal.Split(new char[] {'('});
			name = sigspl[0];
			args = "(" + sigspl[1];
			slots = new ArrayList();
			signals = new ArrayList();
		}

		[DllImport("libqtc", CharSet=CharSet.Ansi)]
		private static extern void qt_del_QObject (IntPtr obj);
		internal override void Delete ()
		{
			if (deleted) return;

			qt_del_QObject (rawObject);
			deleted = true;
		}

		public bool IsCSharpSignal()
		{
			return sender.CsSignalMap.Contains(signal);
		}

		internal static bool Connect(TQObject sender, string signal, TQObject receiver, string slot)
		{
			if (IsSlot(signal)) {
				return false;
				// throw new ArgumentException("Received a slot where a signal was expected");
			}

			if (IsSignal(slot))
				return ConnectSignalToSignal(sender, NormalizeParam(signal), receiver, NormalizeParam(slot));
			else
				return ConnectSignalToSlot(sender, NormalizeParam(signal), receiver, NormalizeParam(slot));
		}

		private static bool ConnectSignalToSlot(TQObject sender, string signal, TQObject receiver, string slot)
		{
			QtSignal sigobj;
			QtSlot slotobj = new QtSlot(receiver, slot);

			if (traceConnects)
				ErrMsg ("ConnectSignalToSlot: ({0}) {1}, {2}, ({3}) {4}, {5}", sender.RawObject, sender, signal,
																				receiver.RawObject, receiver, slot);

			// Connect C# signal to...
			if (sender.CsSignalMap.Contains(signal)) {
				sigobj = sender.CsSignalMap[signal];

				// ...a C# slot
				if (slotobj.IsCSharpSlot) {
					if (sigobj.Slots.Contains(slotobj))
						return false;

					sigobj.Slots.Add(slotobj);
					return true;
				}
				// ...a C++ slot
				else {
					// C++ slots are C# methods, so we should never get here.
					throw new ArgumentException(receiver+" has no slot '"+slot+"'");
				}
			}
			// Connect C++ signal to...
			else {
				// ...a C# slot
				if (slotobj.IsCSharpSlot) {
					string id = MakeSigId(sender, signal);

					if (!sender.CppSignalMap.Contains(id))
						sigobj = sender.CppSignalMap[id] = new QtSignal(sender, signal);
					else {
						sigobj = sender.CppSignalMap[id];

						if (sigobj.Slots.Contains(slotobj))
						 	return false;
					}

					Delegate del;
					string realsignal;

					switch (slotobj.Args) {
					case "()":
						del = Delegate.CreateDelegate (typeof (del_void), receiver, slotobj.Name);
						slotobj.WrapperPtr = csharp_connect_void (sender.RawObject, TQT_SIGNAL (signal), receiver.RawObject, del);
						break;
					case "(bool)":
						del = Delegate.CreateDelegate (typeof (del_bool), receiver, slotobj.Name);
						slotobj.WrapperPtr = csharp_connect_bool (sender.RawObject, TQT_SIGNAL (signal), receiver.RawObject, del);
						break;
					case "(short)":
						del = Delegate.CreateDelegate (typeof (del_short), receiver, slotobj.Name);
						slotobj.WrapperPtr = csharp_connect_short (sender.RawObject, TQT_SIGNAL (signal), receiver.RawObject, del);
						break;
					case "(int)":
						del = Delegate.CreateDelegate (typeof (del_int), receiver, slotobj.Name);
						slotobj.WrapperPtr = csharp_connect_int (sender.RawObject, TQT_SIGNAL (signal), receiver.RawObject, del);
						break;
					case "(long)":
						del = Delegate.CreateDelegate (typeof (del_long), receiver, slotobj.Name);
						slotobj.WrapperPtr = csharp_connect_long (sender.RawObject, TQT_SIGNAL (signal), receiver.RawObject, del);
						break;
					case "(float)":
						del = Delegate.CreateDelegate (typeof (del_float), receiver, slotobj.Name);
						slotobj.WrapperPtr = csharp_connect_float (sender.RawObject, TQT_SIGNAL (signal), receiver.RawObject, del);
						break;
					case "(double)":
						del = Delegate.CreateDelegate (typeof (del_double), receiver, slotobj.Name);
						slotobj.WrapperPtr = csharp_connect_double (sender.RawObject, TQT_SIGNAL (signal), receiver.RawObject, del);
						break;
					case "(TQString)":
						realsignal = sigobj.Name + "(const TQString&)";
						Console.WriteLine("Connecting signal, sigobj.Name = {0}, realsignal = {1}",
							sigobj.Name, realsignal);
						del = Delegate.CreateDelegate (typeof (del_QString), slotobj, "SlotBridge_QString");
						slotobj.WrapperPtr = csharp_connect_QString (sender.RawObject, TQT_SIGNAL (realsignal), receiver.RawObject, del);
						break;						
					case "(TQDockWindow)":
						realsignal = sigobj.Name + "(TQDockWindow*)";
						del = Delegate.CreateDelegate (typeof (del_QDockWindow), slotobj, "SlotBridge_QDockWindow");
						slotobj.WrapperPtr = csharp_connect_QDockWindow (sender.RawObject, TQT_SIGNAL (realsignal), receiver.RawObject, del);
						break;
					case "(TQDropEvent)":
						realsignal = sigobj.Name + "(TQDropEvent*)";
						del = Delegate.CreateDelegate (typeof (del_QDropEvent), slotobj, "SlotBridge_QDropEvent");
						slotobj.WrapperPtr = csharp_connect_QDropEvent (sender.RawObject, TQT_SIGNAL (realsignal), receiver.RawObject, del);
						break;
					case "(TQDropEvent,TQListViewItem)":
						realsignal = sigobj.Name + "(TQDropEvent*,TQListViewItem*)";
						del = Delegate.CreateDelegate (typeof (del_QDropEventTQListViewItem), slotobj, "SlotBridge_QDropEventTQListViewItem");
						slotobj.WrapperPtr = csharp_connect_QDropEventTQListViewItem (sender.RawObject, TQT_SIGNAL (realsignal), receiver.RawObject, del);
						break;
					case "(TQIconViewItem)":
						realsignal = sigobj.Name + "(TQIconViewItem*)";
						del = Delegate.CreateDelegate (typeof (del_QIconViewItem), slotobj, "SlotBridge_QIconViewItem");
						slotobj.WrapperPtr = csharp_connect_QIconViewItem (sender.RawObject, TQT_SIGNAL (realsignal), receiver.RawObject, del);
						break;
					case "(TQListBoxItem)":
						realsignal = sigobj.Name + "(TQListBoxItem*)";
						del = Delegate.CreateDelegate (typeof (del_QListBoxItem), slotobj, "SlotBridge_QListBoxItem");
						slotobj.WrapperPtr = csharp_connect_QListBoxItem (sender.RawObject, TQT_SIGNAL (realsignal), receiver.RawObject, del);
						break;
					case "(TQListViewItem)":
						realsignal = sigobj.Name + "(TQListViewItem*)";
						del = Delegate.CreateDelegate (typeof (del_QListViewItem), slotobj, "SlotBridge_QListViewItem");
						slotobj.WrapperPtr = csharp_connect_QListViewItem (sender.RawObject, TQT_SIGNAL (realsignal), receiver.RawObject, del);
						break;
					case "(TQListViewItem,TQListViewItem)":
						realsignal = sigobj.Name + "(TQListViewItem*,TQListViewItem*)";
						del = Delegate.CreateDelegate (typeof (del_QListViewItemTQListViewItem), slotobj, "SlotBridge_QListViewItemTQListViewItem");
						slotobj.WrapperPtr = csharp_connect_QListViewItemTQListViewItem (sender.RawObject, TQT_SIGNAL (realsignal), receiver.RawObject, del);
						break;
					case "(TQListViewItem,TQListViewItem,TQListViewItem)":
						realsignal = sigobj.Name + "(TQListViewItem*,TQListViewItem*,TQListViewItem*)";
						del = Delegate.CreateDelegate (typeof (del_QListViewItemTQListViewItemTQListViewItem), slotobj, "SlotBridge_QListViewItemTQListViewItemTQListViewItem");
						slotobj.WrapperPtr = csharp_connect_QListViewItemTQListViewItemTQListViewItem (sender.RawObject, TQT_SIGNAL (realsignal), receiver.RawObject, del);
						break;
					case "(TQNetworkOperation)":
						realsignal = sigobj.Name + "(TQNetworkOperation*)";
						del = Delegate.CreateDelegate (typeof (del_QNetworkOperation), slotobj, "SlotBridge_QNetworkOperation");
						slotobj.WrapperPtr = csharp_connect_QNetworkOperation (sender.RawObject, TQT_SIGNAL (realsignal), receiver.RawObject, del);
						break;
					case "(TQObject)":
						realsignal = sigobj.Name + "(TQObject*)";
						del = Delegate.CreateDelegate (typeof (del_QObject), slotobj, "SlotBridge_QObject");
						slotobj.WrapperPtr = csharp_connect_QObject (sender.RawObject, TQT_SIGNAL (realsignal), receiver.RawObject, del);
						break;
					case "(TQToolBar)":
						realsignal = sigobj.Name + "(TQToolBar*)";
						del = Delegate.CreateDelegate (typeof (del_QToolBar), slotobj, "SlotBridge_QToolBar");
						slotobj.WrapperPtr = csharp_connect_QToolBar (sender.RawObject, TQT_SIGNAL (realsignal), receiver.RawObject, del);
						break;
					case "(TQWidget)":
						realsignal = sigobj.Name + "(TQWidget*)";
						del = Delegate.CreateDelegate (typeof (del_QWidget), slotobj, "SlotBridge_QWidget");
						slotobj.WrapperPtr = csharp_connect_QWidget (sender.RawObject, TQT_SIGNAL (realsignal), receiver.RawObject, del);
						break;
					case "(int,TQIconViewItem)":
						realsignal = sigobj.Name + "(int,TQIconViewItem*)";
						del = Delegate.CreateDelegate (typeof (del_intTQIconViewItem), slotobj, "SlotBridge_intTQIconViewItem");
						slotobj.WrapperPtr = csharp_connect_intTQIconViewItem (sender.RawObject, TQT_SIGNAL (realsignal), receiver.RawObject, del);
						break;
					case "(int,TQListBoxItem)":
						realsignal = sigobj.Name + "(int,TQListBoxItem*)";
						del = Delegate.CreateDelegate (typeof (del_intTQListBoxItem), slotobj, "SlotBridge_intTQListBoxItem");
						slotobj.WrapperPtr = csharp_connect_intTQListBoxItem (sender.RawObject, TQT_SIGNAL (realsignal), receiver.RawObject, del);
						break;
					case "(int,bool)":
						del = Delegate.CreateDelegate (typeof (del_intbool), receiver, slotobj.Name);
						slotobj.WrapperPtr = csharp_connect_intbool (sender.RawObject, TQT_SIGNAL (signal), receiver.RawObject, del);
						break;
					case "(int,int)":
						del = Delegate.CreateDelegate (typeof (del_intint), receiver, slotobj.Name);
						slotobj.WrapperPtr = csharp_connect_intint (sender.RawObject, TQT_SIGNAL (signal), receiver.RawObject, del);
						break;
					case "(int,int,int)":
						del = Delegate.CreateDelegate (typeof (del_intintint), receiver, slotobj.Name);
						slotobj.WrapperPtr = csharp_connect_intintint (sender.RawObject, TQT_SIGNAL (signal), receiver.RawObject, del);
						break;
					default:
						throw new ArgumentException ("Unsupported method prototype for C++ signal -> C# slot connection: " + slotobj.Args);
					}

					if (slotobj.WrapperPtr == IntPtr.Zero)
						return false;

					slotobj.Callback = del;

					sigobj.Slots.Add(slotobj);
					return true;
				}
				// ...a C++ slot. C++ slots are C# methods, so we should never get here.
				else {
					throw new ArgumentException(receiver+" has no slot '"+slot+"'");
					// return qt_QObject_connect1(sender.RawObject, TQT_SIGNAL(signal), receiver.RawObject, TQT_SLOT(slot));
				}
			}
		}

		private static bool ConnectSignalToSignal(TQObject sender, string signal, TQObject receiver, string target)
		{
			if (traceConnects)
				ErrMsg ("ConnectSignalToSlot: ({0}) {1}, {2}, ({3}) {4}, {5}", sender.RawObject, sender, signal,
																				receiver.RawObject, receiver, target);

			// Connect C# signal to...
			if (sender.CsSignalMap.Contains(signal)) {
				QtSignal sigobj = sender.CsSignalMap[signal];

				// ...a C# signal
				if (receiver.CsSignalMap.Contains(target)) {
					QtSignal targetobj = receiver.CsSignalMap[target];

					if (sigobj.Signals.Contains(targetobj))
						return false;

					sigobj.Signals.Add(targetobj);
					return true;
				}
				// ...a C++ signal
				else
					throw new NotImplementedException("C# signal <-> C++ signal connections not supported yet");
			}
			// Connect C++ signal to...
			else {
				// ...a C# signal
				if (receiver.CsSignalMap.Contains(target)) {
					QtSignal targetobj = receiver.CsSignalMap[target];
					string args = targetobj.Args;
					string mangle = MangleArgs(args);

					// HACK Wrap target signal in a slot and connect the slot to the sender.
					return Connect(sender, TQT_SIGNAL(signal), targetobj, TQT_SLOT("Emit_"+mangle+args));
				}
				// ...a C++ signal
				else
					return qt_QObject_connect1(sender.RawObject, TQT_SIGNAL(signal), receiver.RawObject, TQT_SIGNAL(target));
			}
		}

		internal static bool Disconnect(TQObject sender, string signal, TQObject receiver, string slot)
		{
			if (signal == null && receiver == null && slot == null)
				return DisconnectAll(sender);
			else if (receiver == null && slot == null)
				return DisconnectSignal(sender, NormalizeParam(signal));
			else if (signal == null && slot == null)
				return DisconnectReceiver(sender, receiver);
			else if (slot == null)
				return DisconnectSignalFromReceiver(sender, NormalizeParam(signal), receiver);
			else if (IsSlot(signal))
				throw new ArgumentException ("Expected a signal where a slot was found.");
			else if (IsSignal(slot))
				return DisconnectSignalFromSignal(sender, NormalizeParam(signal), receiver, NormalizeParam(slot));
			else
				return DisconnectSignalFromSlot(sender, NormalizeParam(signal), receiver, NormalizeParam(slot));
		}

		private static bool DisconnectSignalFromSlot(TQObject sender, string signal, TQObject receiver, string slot)
		{
			if (traceConnects)
				ErrMsg ("DisconnectSignalFromSlot: ({0}) {1}, {2}, ({3}) {4}, {5}", sender.RawObject, sender, signal,
																					receiver.RawObject, receiver, slot);

			QtSignal sigobj;
			QtSlot slotobj = new QtSlot(receiver, slot);

			// Disconnect C# signal from...
			if (sender.CsSignalMap.Contains(signal)) {
				sigobj = sender.CsSignalMap[signal];

				// ...a C# slot
				if (slotobj.IsCSharpSlot) {
					if (!sigobj.Slots.Contains(slotobj))
						return false;

					sigobj.Slots.Remove(slotobj);
					return true;
				}
				// ...a C++ slot
				else {
					// C++ slots are C# methods, so we should never get here.
					throw new ArgumentException(receiver+" has no slot '"+slot+"'");
				}
			}
			// Disconnect C++ signal from...
			else {
				// ...a C# slot
				if (slotobj.IsCSharpSlot) {
					string id = MakeSigId(sender, signal);
					if (!sender.CppSignalMap.Contains(id))
						return false;

					sigobj = sender.CppSignalMap[id];
					bool found = false;
					foreach (QtSlot sobj in sigobj.Slots) {
						if (slotobj.Equals(sobj)) {
							found = true;
							qt_del_QObject(sobj.WrapperPtr);
							sigobj.Slots.Remove(sobj);
							break;
						}
					}

					if (sigobj.Slots.Count == 0)
						sender.CppSignalMap.Remove(id);

					return found;
				}
				// ...a C++ slot. C++ slots are C# methods, so we should never get here.
				else {
					throw new ArgumentException(receiver+" has no slot '"+slot+"'");
					// return qt_QObject_disconnect2(sender.RawObject, TQT_SIGNAL(signal), receiver.RawObject, TQT_SLOT(slot));
				}
			}
		}

		private static bool DisconnectSignalFromSignal(TQObject sender, string signal, TQObject receiver, string target)
		{
			if (traceConnects)
				ErrMsg ("DisconnectSignalFromSignal: ({0}) {1}, {2}, ({3}) {4}, {5}", sender.RawObject, sender, signal,
																						receiver.RawObject, receiver, target);

			QtSignal sigobj;

			// Disconnect C# signal from...
			if (sender.CsSignalMap.Contains(signal)) {
				sigobj = sender.CsSignalMap[signal];

				// ...a C# signal
				if (receiver.CsSignalMap.Contains(target)) {
					QtSignal targetobj = receiver.CsSignalMap[target];
					if (!sigobj.Signals.Contains(targetobj))
						return false;

					sigobj.Signals.Remove(targetobj);
					return true;
				}
				// ...a C++ signal
				else {
					throw new NotImplementedException("C# signal <-> C++ signal (dis)connections not supported yet");
				}
			}
			// Disconnect C++ signal from...
			else {
				sigobj = new QtSignal(sender, signal);

				// ...a C# signal
				if (receiver.CsSignalMap.Contains(target)) {
					QtSignal targetobj = receiver.CsSignalMap[target];
					string args = "(" + target.Split(new char[] {'('})[1];
					return Disconnect(sender, TQT_SIGNAL(signal), targetobj, TQT_SLOT("emit_"+args));
				}
				// ...a C++ signal
				else {
					return qt_QObject_disconnect2(sender.RawObject, TQT_SIGNAL(signal), receiver.RawObject, TQT_SLOT(target));
				}
			}
		}

		private static bool DisconnectAll(TQObject sender)
		{
			if (traceConnects)
				ErrMsg ("DisconnectAll: ({0}) {1}", sender.RawObject, sender);

			IDictionaryEnumerator cse = sender.CsSignalMap.GetEnumerator();
			IDictionaryEnumerator cppe = sender.CppSignalMap.GetEnumerator();

			ArrayList signals = new ArrayList ();

			foreach (IDictionaryEnumerator de in new IDictionaryEnumerator[] { cse, cppe })
				while (de.MoveNext())
					signals.Add (de.Value);

			foreach (QtSignal signal in signals)
				foreach (QtSlot slot in new ArrayList (signal.Slots))
					Disconnect (sender, TQT_SIGNAL (signal.Signal), slot.Receiver, TQT_SLOT (slot.Slot));

			return true;
		}

		private static bool DisconnectReceiver(TQObject sender, TQObject receiver)
		{
			if (traceConnects)
				ErrMsg ("DisconnectReceiver: ({0}) {1}, ({2}) {3}", sender.RawObject, sender, receiver.RawObject, receiver);

			IDictionaryEnumerator cse = sender.CsSignalMap.GetEnumerator();
			IDictionaryEnumerator cppe = sender.CppSignalMap.GetEnumerator();

			ArrayList signals = new ArrayList ();

			foreach (IDictionaryEnumerator de in new IDictionaryEnumerator[] { cse, cppe })
				while (de.MoveNext ())
					signals.Add (de.Value);

			foreach (QtSignal signal in signals)
				foreach (QtSlot slot in new ArrayList (signal.Slots))
					Disconnect (signal.Sender, TQT_SIGNAL (signal.Name), receiver, TQT_SLOT (slot.Name));

			return true;
		}

		private static bool DisconnectSignal(TQObject sender, string signal)
		{
			if (traceConnects)
				ErrMsg ("DisconnectSignal: ({0}) {1}, {2}", sender.RawObject, sender, signal);

			foreach (QtSignalMap map in new QtSignalMap[] { sender.CsSignalMap, sender.CppSignalMap }) {
				QtSignal sig = map[signal];
				if (sig != null) {
					foreach (QtSlot slot in new ArrayList (sig.Slots))
						Disconnect (sender, TQT_SIGNAL(signal), slot.Receiver, TQT_SLOT(slot.Slot));
				}
			}

			return true;
		}

		private static bool DisconnectSignalFromReceiver (TQObject sender, string signal, TQObject receiver)
		{
			if (traceConnects)
				ErrMsg ("DisconnectSignalFromReceiver: ({0}) {1}, {2}, ({3}), {4}", sender.RawObject, sender,
																			signal, receiver.RawObject, receiver);

			foreach (QtSignalMap map in new QtSignalMap[] { sender.CsSignalMap, sender.CppSignalMap }) {
				QtSignal sig = map[signal];
				if (sig != null) {
					foreach (QtSlot slot in new ArrayList (sig.Slots))
						if (slot.Receiver == receiver)
							Disconnect (sender, signal, receiver, TQT_SLOT (slot.Name));
				}
			}

			return true;
		}

		private static string MangleArgs(string args)
		{
			// FIXME Char.Equals and Char.CompareTo don't seem to work on Mono.
			string result = args.Replace ("(", "");
			result = result.Replace (")", "");
			result = result.Replace (" ", "");
			result = result.Replace ("unsigned ", "u");
			result = result.Replace ("byte", "char");
			return result.Replace (",", "");

			/*
			char[] evict = {'(', ')', ',', ' '};
			char[] result = new char[args.Length];
			int newlen = 0;

			foreach (char c in args.ToCharArray()) {
				foreach (char cx in evict) {
					if (c.Equals(cx)) continue;
				}
				result[newlen] = c;
				newlen++;
			}

			return new String(result);
			*/
		}

		private static string MakeSigId(TQObject sender, string signal)
		{
			return sender.RawObject.ToString()+signal;
		}

		internal static string NormalizeParam(string param)
		{
			string ret = param;
			if (param.StartsWith("1") || param.StartsWith("2"))
				ret = param.Substring(1);
			return ret;

		}

		private static bool IsSignal(string name)
		{
			return name.StartsWith("2");
		}

		private static bool IsSlot(string name)
		{
			return name.StartsWith("1");
		}

		public void DumpConnections()
		{
			ErrMsg ("{0}::{1} Signal Information:", sender, signal);

			ErrMsg ("-------- Slot Connections --------");
			if (Slots.Count == 0)
				ErrMsg ("--> No slot connections.");
			else {
				foreach (QtSlot slot in slots) {
					ErrMsg ("--> ({0}) {1}::{2}", slot.Receiver.RawObject, slot.Receiver, slot.Slot);
				}
			}

			ErrMsg ("------- Signal Connections -------");
			if (Signals.Count == 0)
				ErrMsg ("--> No signal connections.");
			else {
				foreach (QtSignal sig in signals) {
					ErrMsg ("--> ({0}) {1}::{2}", sig.Sender.RawObject, sig.Sender, sig.Signal);
				}
			}
		}

		public void Emit(object[] args)
		{
			foreach (QtSlot slot in slots)
				slot.Invoke(args);

			foreach (QtSignal signal in signals) {
				signal.Emit(args);
			}
		}

		public void Emit_void ()
		{
			Emit (new object[0]);
		}
		
		public void Emit_bool (bool value0)
		{
			Emit (new object[] { value0 });
		}
		
		public void Emit_short (short value0)
		{
			Emit (new object[] { value0 });
		}
		
		public void Emit_int (int value0)
		{
			Emit (new object[] { value0 });
		}
		
		public void Emit_long (long value0)
		{
			Emit (new object[] { value0 });
		}
		
		public void Emit_float (float value0)
		{
			Emit (new object[] { value0 });
		}
		
		public void Emit_double (double value0)
		{
			Emit (new object[] { value0 });
		}
		
		public void Emit_QDockWindow (IntPtr value0)
		{
			Emit (new object[] { value0 });
		}
		
		public void Emit_QDropEvent (IntPtr value0)
		{
			Emit (new object[] { value0 });
		}
		
		public void Emit_QDropEventTQListViewItem (IntPtr value0, IntPtr value1)
		{
			Emit (new object[] { value0, value1 });
		}
		
		public void Emit_QIconViewItem (IntPtr value0)
		{
			Emit (new object[] { value0 });
		}
		
		public void Emit_QListBoxItem (IntPtr value0)
		{
			Emit (new object[] { value0 });
		}
		
		public void Emit_QListViewItem (IntPtr value0)
		{
			Emit (new object[] { value0 });
		}
		
		public void Emit_QListViewItemTQListViewItem (IntPtr value0, IntPtr value1)
		{
			Emit (new object[] { value0, value1 });
		}
		
		public void Emit_QListViewItemTQListViewItemTQListViewItem (IntPtr value0, IntPtr value1, IntPtr value2)
		{
			Emit (new object[] { value0, value1, value2 });
		}
		
		public void Emit_QNetworkOperation (IntPtr value0)
		{
			Emit (new object[] { value0 });
		}
		
		public void Emit_QObject (IntPtr value0)
		{
			Emit (new object[] { value0 });
		}
		
		public void Emit_QToolBar (IntPtr value0)
		{
			Emit (new object[] { value0 });
		}
		
		public void Emit_QWidget (IntPtr value0)
		{
			Emit (new object[] { value0 });
		}
		
		public void Emit_intTQIconViewItem (int value0, IntPtr value1)
		{
			Emit (new object[] { value0, value1 });
		}
		
		public void Emit_intTQListBoxItem (int value0, IntPtr value1)
		{
			Emit (new object[] { value0, value1 });
		}
		
		public void Emit_intbool (int value0, bool value1)
		{
			Emit (new object[] { value0, value1 });
		}
		
		public void Emit_intint (int value0, int value1)
		{
			Emit (new object[] { value0, value1 });
		}
		
		public void Emit_intintint (int value0, int value1, int value2)
		{
			Emit (new object[] { value0, value1, value2 });
		}

		[DllImport("libqtc", CharSet=CharSet.Ansi)]
		private static extern bool qt_QObject_connect1 (IntPtr sender, string signal, IntPtr receiver, string member);

		[DllImport("libqtc", CharSet=CharSet.Ansi)]
		private static extern bool qt_QObject_disconnect2 (IntPtr sender, string signal, IntPtr receiver, string member);

		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_void (IntPtr sender, string signal, IntPtr receiver, Delegate cb);
		
		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_bool (IntPtr sender, string signal, IntPtr receiver, Delegate cb);
		
		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_short (IntPtr sender, string signal, IntPtr receiver, Delegate cb);
		
		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_int (IntPtr sender, string signal, IntPtr receiver, Delegate cb);
		
		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_long (IntPtr sender, string signal, IntPtr receiver, Delegate cb);
		
		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_float (IntPtr sender, string signal, IntPtr receiver, Delegate cb);
		
		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_double (IntPtr sender, string signal, IntPtr receiver, Delegate cb);
		
		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_QString (IntPtr sender, string signal, IntPtr receiver, Delegate cb);
	
		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_QDockWindow (IntPtr sender, string signal, IntPtr receiver, Delegate cb);
		
		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_QDropEvent (IntPtr sender, string signal, IntPtr receiver, Delegate cb);
		
		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_QDropEventTQListViewItem (IntPtr sender, string signal, IntPtr receiver, Delegate cb);
		
		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_QIconViewItem (IntPtr sender, string signal, IntPtr receiver, Delegate cb);
		
		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_QListBoxItem (IntPtr sender, string signal, IntPtr receiver, Delegate cb);
		
		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_QListViewItem (IntPtr sender, string signal, IntPtr receiver, Delegate cb);
		
		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_QListViewItemTQListViewItem (IntPtr sender, string signal, IntPtr receiver, Delegate cb);
		
		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_QListViewItemTQListViewItemTQListViewItem (IntPtr sender, string signal, IntPtr receiver, Delegate cb);
		
		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_QNetworkOperation (IntPtr sender, string signal, IntPtr receiver, Delegate cb);

		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_QObject (IntPtr sender, string signal, IntPtr receiver, Delegate cb);

		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_QToolBar (IntPtr sender, string signal, IntPtr receiver, Delegate cb);

		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_QWidget (IntPtr sender, string signal, IntPtr receiver, Delegate cb);

		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_intTQIconViewItem (IntPtr sender, string signal, IntPtr receiver, Delegate cb);

		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_intTQListBoxItem (IntPtr sender, string signal, IntPtr receiver, Delegate cb);

		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_intbool (IntPtr sender, string signal, IntPtr receiver, Delegate cb);

		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_intint (IntPtr sender, string signal, IntPtr receiver, Delegate cb);

		[DllImport("libqtsharp", CharSet=CharSet.Ansi)]
		private static extern IntPtr csharp_connect_intintint (IntPtr sender, string signal, IntPtr receiver, Delegate cb);

		public delegate void del_void ();
		public delegate void del_bool (bool value0);
		public delegate void del_short (short value0);
		public delegate void del_int (int value0);
		public delegate void del_long (long value0);
		public delegate void del_float (float value0);
		public delegate void del_double (double value0);
		public delegate void del_QString (IntPtr value0);
		public delegate void del_QDockWindow (IntPtr value0);
		public delegate void del_QDropEvent (IntPtr value0);
		public delegate void del_QDropEventTQListViewItem (IntPtr value0, IntPtr value1);
		public delegate void del_QIconViewItem (IntPtr value0);
		public delegate void del_QListBoxItem (IntPtr value0);
		public delegate void del_QListViewItem (IntPtr value0);
		public delegate void del_QListViewItemTQListViewItem (IntPtr value0, IntPtr value1);
		public delegate void del_QListViewItemTQListViewItemTQListViewItem (IntPtr value0, IntPtr value1, IntPtr value2);
		public delegate void del_QNetworkOperation (IntPtr value0);
		public delegate void del_QObject (IntPtr value0);
		public delegate void del_QToolBar (IntPtr value0);
		public delegate void del_QWidget (IntPtr value0);
		public delegate void del_intTQIconViewItem (int value0, IntPtr value1);
		public delegate void del_intTQListBoxItem (int value0, IntPtr value1);
		public delegate void del_intbool (int value0, bool value1);
		public delegate void del_intint (int value0, int value1);
		public delegate void del_intintint (int value0, int value1, int value2);
	}
}
