// Gtk.Object.custom - Gtk Object class customizations
//
// Author: Mike Kestner <mkestner@novell.com>
//
// Copyright (c) 2002-2003 Mike Kestner
// Copyright (c) 2007 Novell, Inc.
//
// This code is inserted after the automatically generated code.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 2 of the Lesser GNU General 
// Public License as published by the Free Software Foundation.
//
// 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser 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.

		static Hashtable destroy_handlers;
		static Hashtable DestroyHandlers {
			get {
				if (destroy_handlers == null)
					destroy_handlers = new Hashtable ();
				return destroy_handlers;
			}
		}

		private static void OverrideDestroyed (GLib.GType gtype)
		{
			// Do Nothing.  We don't want to hook into the native vtable.
			// We will manually invoke the VM on signal invocation. The signal
			// always raises before the default handler because this signal
			// is RUN_CLEANUP.
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gtk.Object), ConnectionMethod="OverrideDestroyed")]
		protected virtual void OnDestroyed ()
		{
			if (DestroyHandlers.Contains (Handle)) {
				EventHandler handler = (EventHandler) DestroyHandlers [Handle];
				handler (this, EventArgs.Empty);
				DestroyHandlers.Remove (Handle);
			}
		}

		[GLib.Signal("destroy")]
		public event EventHandler Destroyed {
			add {
				EventHandler handler = (EventHandler) DestroyHandlers [Handle];
				DestroyHandlers [Handle] = Delegate.Combine (handler, value);
			}
			remove {
				EventHandler handler = (EventHandler) DestroyHandlers [Handle];
				handler = (EventHandler) Delegate.Remove (handler, value);
				if (handler != null)
					DestroyHandlers [Handle] = handler;
				else
					DestroyHandlers.Remove (Handle);
			}
		}

		event EventHandler InternalDestroyed {
			add {
				GLib.Signal sig = GLib.Signal.Lookup (this, "destroy");
				sig.AddDelegate (value);
			}
			remove {
				GLib.Signal sig = GLib.Signal.Lookup (this, "destroy");
				sig.RemoveDelegate (value);
			}
		}

		static void NativeDestroy (object o, EventArgs args)
		{
			Gtk.Object obj = o as Gtk.Object;
			if (obj == null)
				return;
			obj.OnDestroyed ();
		}
		
		static EventHandler native_destroy_handler;
		static EventHandler NativeDestroyHandler {
			get {
				if (native_destroy_handler == null)
					native_destroy_handler = new EventHandler (NativeDestroy);
				return native_destroy_handler;
			}
		}

		protected override void CreateNativeObject (string[] names, GLib.Value[] vals)
		{
			base.CreateNativeObject (names, vals);
		}

		public override void Dispose ()
		{
			if (Handle == IntPtr.Zero)
				return;
			InternalDestroyed -= NativeDestroyHandler;
			base.Dispose ();
		}

		[DllImport("libgobject-2.0-0.dll")]
		private static extern void g_object_ref_sink (IntPtr raw);

		protected override IntPtr Raw {
			get {
				return base.Raw;
			}
			set {
				if (value != IntPtr.Zero)
					g_object_ref_sink (value);
				base.Raw = value;
				if (value != IntPtr.Zero)
					InternalDestroyed += NativeDestroyHandler;
			}
		}

		[DllImport("libgtk-win32-2.0-0.dll")]
		private static extern void gtk_object_destroy (IntPtr raw);

		public virtual void Destroy ()
		{
			if (Handle == IntPtr.Zero)
				return;
			gtk_object_destroy (Handle);
			InternalDestroyed -= NativeDestroyHandler;
		}

		[DllImport("gtksharpglue-2")]
		private static extern bool gtksharp_object_is_floating (IntPtr raw);

		[DllImport("gtksharpglue-2")]
		private static extern bool gtksharp_object_set_floating (IntPtr raw, bool val);

		public bool IsFloating {
			get {
				return gtksharp_object_is_floating (Handle);
			}
			set {
				gtksharp_object_set_floating (Handle, value);
			}
		}

