// QObject.cs - A Qt to C# binding.
//
// 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.
//
// Regenerated by Adam Treat on August 30 2002
//
// NOTES
// o Methods related to Qt reflection have been marked internal. Most of them
//   should eventually be throttled, and this file regenerated
// o Some event-related methods are also marked internal. I don't think we use
//   any of them, they can likely be throttled.
//
// TODO
// o Should use children() in object tree tracking for constructing
//   complete tree representations.

namespace Qt {

    using Qt;
    using System;
	using System.Collections;
    using System.Runtime.InteropServices;

	//[DeclareQtSignal ("ChildDestroyed(QObject)")]
    public class QObject : QtSupport, IDisposable {

		// Hold an instance of the QApplication object
		private static QApplication qapp;
		private QtSignalMap csSignalMap;
		private QtSignalMap cppSignalMap;

		public static QApplication qApp {
			get {return qapp;}
			set {qapp = value;}
		}

		internal QtSignalMap CsSignalMap {
			get { return csSignalMap; }
		}

		internal QtSignalMap CppSignalMap {
			get { return cppSignalMap; }
		}

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern IntPtr qt_new_QObject (IntPtr parent, string name);
        public QObject (QObject parent, string name) : this (QNull.Instance)
        {
			qparent = parent;

			if (qparent == null)
				parent = new QWidget (IntPtr.Zero);
			else
				qparent.AddChild (this);

			rawObject = qt_new_QObject (parent.RawObject, name);
            RegisterObject (this);
		}

        public QObject (QObject parent) : this (parent, "") {}

		internal QObject () : this (QNull.Instance) {}

        internal QObject (IntPtr ptr) : this (QNull.Instance)
        {
            rawObject = ptr;
            RegisterObject (this);
        }

		internal QObject (QNull dummy) : base (QNull.Instance)
		{
			InitSignals ();
		}

		// FIXME This ctor used only by QtSignal
		internal QObject (NoSignalInit dummy) : base (QNull.Instance)
		{
			rawObject = qt_new_QObject (IntPtr.Zero, "");
			RegisterObject (this);
		}

        ~QObject ()
        {
            Dispose(false);
        }

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

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

			if (disposeManaged) {
				disposed = true;

				UnregisterObject (this);

				if (qparent != null ) {
					if (qparent.Disposed)
						deleted = true;
					else
						qparent.RemoveChild (this);
				}

				Disconnect ();

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

				// UnregisterObject (); // FIXME
			}

			/*
			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 ();
		}

		[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;
		}

		private void InitSignals ()
		{
			csSignalMap = new QtSignalMap (this, "C# Signals");
			cppSignalMap = new QtSignalMap (this, "C++ Signals");

			object[] attrs = GetType ().GetCustomAttributes (typeof (DeclareQtSignalAttribute), true);

			foreach (DeclareQtSignalAttribute attr in attrs) {
				string signal = attr.SignalName;

				if (!CsSignalMap.Contains (signal))
					CsSignalMap[signal] = new QtSignal (this, signal);
			}
		}

		// [QtSlot]
		internal protected void NativeDestroyed ()
		{
			deleted = true;
			Dispose ();
		}

		public QObject QtCast()
		{
			string QtType = this.ClassName();
			Type newType = Type.GetType( "Qt." + QtType );
			object[] paramArray = { this.RawObject };
			return (QObject) Activator.CreateInstance( newType, paramArray );
		}

		public static bool Connect(QObject sender, string signal, QObject receiver, string slot)
		{
			return QtSignal.Connect(sender, signal, receiver, slot);
		}

		public bool Connect (QObject sender, string signal, string member)
		{
			return Connect (sender, signal, this, member);
		}

		public static bool Disconnect(QObject sender, string signal, QObject receiver, string slot)
		{
			return QtSignal.Disconnect(sender, signal, receiver, slot);
		}

		public bool Disconnect ()
		{
			return Disconnect (this, null, null, null);
		}

		public bool Disconnect (string signal, QObject receiver, string member)
		{
			return Disconnect(this, signal, receiver, member);
		}

		public bool Disconnect (QObject receiver, string slot)
		{
			return Disconnect (this, null, receiver, slot);
		}

		public void Emit (string signal, params object[] args)
		{
			string sig = signal.Replace (" ", "");

			if (CsSignalMap.Contains (sig))
				CsSignalMap[sig].Emit (args);
			else
				throw new ArgumentException (this+" does not emit requested signal '"+sig+"'");
		}

		public void DumpConnections()
		{
			ErrMsg ("** ({0}) {1}: Dumping '{2}' map.", rawObject, this, CsSignalMap.Name);
			CsSignalMap.DumpMap ();

			ErrMsg ("** ({0}) {1}: Dumping '{2}' map.", rawObject, this, CppSignalMap.Name);
			CppSignalMap.DumpMap ();
		}

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern string qt_QObject_className (IntPtr raw);
        public string ClassName ()
        {
            return qt_QObject_className (rawObject);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern IntPtr qt_QObject_tr (IntPtr raw, string arg1, string arg2);
        public string Tr (string arg1, string arg2)
        {
			QString qstr = new QString (qt_QObject_tr (rawObject, arg1, arg2));
			string str = qstr.Latin1 ();
			qstr.Dispose ();
			return str;
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern IntPtr qt_QObject_trUtf8 (IntPtr raw, string arg1, string arg2);
        public string TrUtf8 (string arg1, string arg2)
        {
			QString qstr = new QString (qt_QObject_trUtf8 (rawObject, arg1, arg2));
			string str = qstr.Latin1 ();
			qstr.Dispose ();
			return str;
		}

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern IntPtr qt_QObject_metaObject (IntPtr raw);
        public QMetaObject MetaObject ()
        {
            return (QMetaObject)LookupObject (qt_QObject_metaObject (rawObject), typeof(QMetaObject));
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern bool qt_QObject_event (IntPtr raw, IntPtr arg1);
        public bool Q_event (QEvent arg1)
        {
            return qt_QObject_event (rawObject, arg1.RawObject);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern bool qt_QObject_eventFilter (IntPtr raw, IntPtr arg1, IntPtr arg2);
        public bool EventFilter (QObject arg1, QEvent arg2)
        {
            return qt_QObject_eventFilter (rawObject, arg1.RawObject, arg2.RawObject);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern bool qt_QObject_isA (IntPtr raw, string arg1);
        public bool IsA (string arg1)
        {
            return qt_QObject_isA (rawObject, arg1);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern bool qt_QObject_inherits (IntPtr raw, string arg1);
        public bool Inherits (string arg1)
        {
            return qt_QObject_inherits (rawObject, arg1);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern string qt_QObject_name (IntPtr raw);
        public string Name ()
        {
            return qt_QObject_name (rawObject);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern string qt_QObject_name1 (IntPtr raw, string defaultName);
        public string Name (string defaultName)
        {
            return qt_QObject_name1 (rawObject, defaultName);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_setName (IntPtr raw, string name);
        public void SetName (string name)
        {
            qt_QObject_setName (rawObject, name);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern bool qt_QObject_isWidgetType (IntPtr raw);
        public bool IsWidgetType ()
        {
            return qt_QObject_isWidgetType (rawObject);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern bool qt_QObject_highPriority (IntPtr raw);
        public bool HighPriority ()
        {
            return qt_QObject_highPriority (rawObject);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern bool qt_QObject_signalsBlocked (IntPtr raw);
        public bool SignalsBlocked ()
        {
            return qt_QObject_signalsBlocked (rawObject);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_blockSignals (IntPtr raw, bool b);
        public void BlockSignals (bool b)
        {
            qt_QObject_blockSignals (rawObject, b);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern int qt_QObject_startTimer (IntPtr raw, int interval);
        public int StartTimer (int interval)
        {
            return qt_QObject_startTimer (rawObject, interval);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_killTimer (IntPtr raw, int identifier);
        public void KillTimer (int identifier)
        {
            qt_QObject_killTimer (rawObject, identifier);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_killTimers (IntPtr raw);
        public void KillTimers ()
        {
            qt_QObject_killTimers (rawObject);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern IntPtr qt_QObject_child (IntPtr raw, string objName, string inheritsClass, bool recursiveSearch);
        public QObject Child (string objName, string inheritsClass, bool recursiveSearch)
        {
			return (QObject)LookupObject (qt_QObject_child (rawObject, objName, inheritsClass, recursiveSearch), typeof(QObject));
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern IntPtr qt_QObject_children (IntPtr raw);
        public QObjectList Children ()
        {
            return (QObjectList)LookupObject (qt_QObject_children (rawObject), typeof(QObjectList));
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern IntPtr qt_QObject_queryList (IntPtr raw, string inheritsClass, string objName, bool regexpMatch, bool recursiveSearch);
        public QObjectList QueryList (string inheritsClass, string objName, bool regexpMatch, bool recursiveSearch)
        {
            return (QObjectList)LookupObject (qt_QObject_queryList (rawObject, inheritsClass, objName, regexpMatch, recursiveSearch), typeof(QObjectList));
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_insertChild (IntPtr raw, IntPtr arg1);
        public void InsertChild (QObject arg1)
        {
            qt_QObject_insertChild (rawObject, arg1.RawObject);
        }

        /*[DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_removeChild (IntPtr raw, IntPtr arg1);
        public void RemoveChild (QObject arg1)
        {
            qt_QObject_removeChild (rawObject, arg1.RawObject);
        }*/

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_installEventFilter (IntPtr raw, IntPtr arg1);
        public void InstallEventFilter (QObject arg1)
        {
            qt_QObject_installEventFilter (rawObject, arg1.RawObject);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_removeEventFilter (IntPtr raw, IntPtr arg1);
        public void RemoveEventFilter (QObject arg1)
        {
            qt_QObject_removeEventFilter (rawObject, arg1.RawObject);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_dumpObjectTree (IntPtr raw);
        public void DumpObjectTree ()
        {
            qt_QObject_dumpObjectTree (rawObject);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_dumpObjectInfo (IntPtr raw);
        public void DumpObjectInfo ()
        {
            qt_QObject_dumpObjectInfo (rawObject);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern bool qt_QObject_setProperty (IntPtr raw, string name, IntPtr value);
        public bool SetProperty (string name, QVariant value)
        {
            return qt_QObject_setProperty (rawObject, name, value.RawObject);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern IntPtr qt_QObject_property (IntPtr raw, string name);
        public QVariant Property (string name)
        {
            return (QVariant)LookupObject (qt_QObject_property (rawObject, name), typeof(QVariant));
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern IntPtr qt_QObject_parent (IntPtr raw);
        public QObject Parent ()
        {
            return (QObject)LookupObject (qt_QObject_parent (rawObject), typeof(QObject));
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_deleteLater (IntPtr raw);
        public void DeleteLater ()
        {
            qt_QObject_deleteLater (rawObject);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern IntPtr qt_QObject_objectTrees ();
        public static QObjectList ObjectTrees ()
        {
            return (QObjectList)LookupObject (qt_QObject_objectTrees (), typeof(QObjectList));
        }

		/*FIXME
        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_connectInternal (IntPtr sender, int signal_index, IntPtr receiver, int membcode, int member_index);
        public static void ConnectInternal (QObject sender, int signal_index, QObject receiver, int membcode, int member_index)
        {
            qt_QObject_connectInternal (sender.RawObject, signal_index, receiver.RawObject, membcode, member_index);
        }
		*/

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern bool qt_QObject_activate_filters (IntPtr raw, IntPtr arg1);
        protected bool Activate_filters (QEvent arg1)
        {
            return qt_QObject_activate_filters (rawObject, arg1.RawObject);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern IntPtr qt_QObject_receivers (IntPtr raw, string signal);
        protected QConnectionList Receivers (string signal)
        {
            return (QConnectionList)LookupObject (qt_QObject_receivers (rawObject, signal), typeof(QConnectionList));
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern IntPtr qt_QObject_receivers1 (IntPtr raw, int signal);
        protected QConnectionList Receivers (int signal)
        {
            return (QConnectionList)LookupObject (qt_QObject_receivers1 (rawObject, signal), typeof(QConnectionList));
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_activate_signal (IntPtr raw, int signal);
        protected void Activate_signal (int signal)
        {
            qt_QObject_activate_signal (rawObject, signal);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_activate_signal1 (IntPtr raw, int signal, int arg1);
        protected void Activate_signal (int signal, int arg1)
        {
            qt_QObject_activate_signal1 (rawObject, signal, arg1);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_activate_signal2 (IntPtr raw, int signal, double arg1);
        protected void Activate_signal (int signal, double arg1)
        {
            qt_QObject_activate_signal2 (rawObject, signal, arg1);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_activate_signal3 (IntPtr raw, int signal, IntPtr arg1);
        protected void Activate_signal (int signal, string arg1)
        {
            qt_QObject_activate_signal3 (rawObject, signal, new QString (arg1).RawObject);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_activate_signal_bool (IntPtr raw, int signal, bool arg1);
        protected void Activate_signal_bool (int signal, bool arg1)
        {
            qt_QObject_activate_signal_bool (rawObject, signal, arg1);
        }

		/*
        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_activate_signal4 (IntPtr raw, IntPtr clist, IntPtr o);
        protected void Activate_signal (QConnectionList clist, IntPtr o)
        {
            qt_QObject_activate_signal4 (rawObject, clist.RawObject, o);
        }
		*/

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern IntPtr qt_QObject_sender (IntPtr raw);
        protected QObject Sender ()
        {
            return (QObject)LookupObject (qt_QObject_sender (rawObject), typeof(QObject));
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_connectNotify (IntPtr raw, string signal);
        protected void ConnectNotify (string signal)
        {
            qt_QObject_connectNotify (rawObject, signal);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern void qt_QObject_disconnectNotify (IntPtr raw, string signal);
        protected void DisconnectNotify (string signal)
        {
            qt_QObject_disconnectNotify (rawObject, signal);
        }

        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern bool qt_QObject_checkConnectArgs (IntPtr raw, string signal, IntPtr receiver, string member);
        protected bool CheckConnectArgs (string signal, QObject receiver, string member)
        {
            return qt_QObject_checkConnectArgs (rawObject, signal, receiver.RawObject, member);
        }

		/*
        [DllImport("libqtc", CharSet=CharSet.Ansi)]
        private static extern IntPtr qt_QObject_normalizeSignalSlot (string signalSlot);
        protected static QCString NormalizeSignalSlot (string signalSlot)
        {
            return (QCString)LookupObject (qt_QObject_normalizeSignalSlot (signalSlot), typeof(QCString));
        }
		*/

        public QObject Child (string objName)
        {
            return Child(objName, null);
        }

        public QObject Child (string objName, string inheritsClass)
        {
            return Child(objName, inheritsClass, true);
        }

        public QObjectList QueryList ()
        {
            return QueryList("");
        }

        public QObjectList QueryList (string inheritsClass)
        {
            return QueryList(inheritsClass, "");
        }

        public QObjectList QueryList (string inheritsClass, string objName)
        {
            return QueryList(inheritsClass, objName, true);
        }

        public QObjectList QueryList (string inheritsClass, string objName, bool regexpMatch)
        {
            return QueryList(inheritsClass, objName, regexpMatch, true);
        }
    }

	// FIXME Used only by QtSignal
	internal class NoSignalInit
	{
		public static readonly NoSignalInit Instance = new NoSignalInit ();
	}
}
