// This file was generated by the Gtk# code generator.
// Changed to use strings instead of GParamSpecs

namespace Gst.Interfaces {

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

	public partial class PropertyProbeAdapter : Gst.GLib.GInterfaceAdapter, Gst.Interfaces.PropertyProbe {

		[StructLayout (LayoutKind.Sequential)]
		struct GstPropertyProbeInterface {
			IntPtr ProbeNeeded;
			public GetPropertiesNativeDelegate GetProperties;
			public NeedsProbeNativeDelegate NeedsProbe;
			public ProbePropertyNativeDelegate ProbeProperty;
			public GetValuesNativeDelegate GetValues;
			[MarshalAs (UnmanagedType.ByValArray, SizeConst=4)]
			public IntPtr[] GstReserved;
		}

		static GstPropertyProbeInterface iface;

		static PropertyProbeAdapter ()
		{
			Gst.GLib.GType.Register (_gtype, typeof(PropertyProbeAdapter));
			iface.GetProperties = new GetPropertiesNativeDelegate (GetProperties_cb);
			iface.NeedsProbe = new NeedsProbeNativeDelegate (NeedsProbe_cb);
			iface.ProbeProperty = new ProbePropertyNativeDelegate (ProbeProperty_cb);
			iface.GetValues = new GetValuesNativeDelegate (GetValues_cb);
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate IntPtr GetPropertiesNativeDelegate (IntPtr inst);

		[DllImport("libglib-2.0-0.dll")]
		static extern IntPtr g_object_class_find_property (IntPtr gclass, IntPtr name);

		static IntPtr GetProperties_cb (IntPtr inst)
		{
			try {
				PropertyProbeImplementor __obj = Gst.GLib.Object.GetObject (inst, false) as PropertyProbeImplementor;

				string[] properties = __obj.Properties;
				Gst.GLib.List properties_list = new Gst.GLib.List (typeof (IntPtr));
				IntPtr gclass = Marshal.ReadIntPtr (inst);
				foreach (string prop in properties) {
					IntPtr name = Gst.GLib.Marshaller.StringToPtrGStrdup (prop);
					IntPtr pspec = g_object_class_find_property (gclass, name);
					Gst.GLib.Marshaller.Free (name);
					if (pspec != IntPtr.Zero)
						properties_list.Prepend (pspec);
				}

				/* FIXME: We leak the list! */
				return properties_list.Handle;
			} catch (Exception e) {
				Gst.GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate bool NeedsProbeNativeDelegate (IntPtr inst, uint prop_id, IntPtr pspec);

		static bool NeedsProbe_cb (IntPtr inst, uint prop_id, IntPtr pspec)
		{
			try {
				PropertyProbeImplementor __obj = Gst.GLib.Object.GetObject (inst, false) as PropertyProbeImplementor;
				Gst.PropertyInfo pi = new Gst.PropertyInfo (pspec);
				bool __result = __obj.NeedsProbe (pi.Name);
				return __result;
			} catch (Exception e) {
				Gst.GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate void ProbePropertyNativeDelegate (IntPtr inst, uint prop_id, IntPtr pspec);

		static void ProbeProperty_cb (IntPtr inst, uint prop_id, IntPtr pspec)
		{
			try {
				PropertyProbeImplementor __obj = Gst.GLib.Object.GetObject (inst, false) as PropertyProbeImplementor;
				Gst.PropertyInfo pi = new Gst.PropertyInfo (pspec);
				__obj.ProbeProperty (pi.Name);
			} catch (Exception e) {
				Gst.GLib.ExceptionManager.RaiseUnhandledException (e, false);
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate IntPtr GetValuesNativeDelegate (IntPtr inst, uint prop_id, IntPtr pspec);

		static IntPtr GetValues_cb (IntPtr inst, uint prop_id, IntPtr pspec)
		{
			try {
				PropertyProbeImplementor __obj = Gst.GLib.Object.GetObject (inst, false) as PropertyProbeImplementor;
				Gst.PropertyInfo pi = new Gst.PropertyInfo (pspec);
				object[] values = __obj.GetValues (pi.Name);
				Gst.GLib.ValueArray va = new Gst.GLib.ValueArray ((uint) values.Length);

				foreach (object v in values)
					va.Append (new Gst.GLib.Value (v));
				return va.Handle;
			} catch (Exception e) {
				Gst.GLib.ExceptionManager.RaiseUnhandledException (e, false);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		static int class_offset = 2 * IntPtr.Size;

		static void Initialize (IntPtr ptr, IntPtr data)
		{
			IntPtr ifaceptr = new IntPtr (ptr.ToInt64 () + class_offset);
			GstPropertyProbeInterface native_iface = (GstPropertyProbeInterface) Marshal.PtrToStructure (ifaceptr, typeof (GstPropertyProbeInterface));
			native_iface.GetProperties = iface.GetProperties;
			native_iface.NeedsProbe = iface.NeedsProbe;
			native_iface.ProbeProperty = iface.ProbeProperty;
			native_iface.GetValues = iface.GetValues;
			Marshal.StructureToPtr (native_iface, ifaceptr, false);
			GCHandle gch = (GCHandle) data;
			gch.Free ();
		}

		Gst.GLib.Object implementor;

		public PropertyProbeAdapter ()
		{
			InitHandler = new Gst.GLib.GInterfaceInitHandler (Initialize);
		}

		public PropertyProbeAdapter (PropertyProbeImplementor implementor)
		{
			if (implementor == null)
				throw new ArgumentNullException ("implementor");
			else if (!(implementor is Gst.GLib.Object))
				throw new ArgumentException ("implementor must be a subclass of Gst.GLib.Object");
			this.implementor = implementor as Gst.GLib.Object;
		}

		public PropertyProbeAdapter (IntPtr handle)
		{
			if (!_gtype.IsInstance (handle))
				throw new ArgumentException ("The gobject doesn't implement the GInterface of this adapter", "handle");
			implementor = Gst.GLib.Object.GetObject (handle);
		}

		[DllImport("libgstinterfaces-0.10.dll")]
		static extern IntPtr gst_property_probe_get_type();

		private static Gst.GLib.GType _gtype = new Gst.GLib.GType (gst_property_probe_get_type ());

		public override Gst.GLib.GType GType {
			get {
				return _gtype;
			}
		}

		public override IntPtr Handle {
			get {
				return implementor.Handle;
			}
		}

		public IntPtr OwnedHandle {
			get {
				return implementor.OwnedHandle;
			}
		}

		public static PropertyProbe GetObject (IntPtr handle, bool owned)
		{
			Gst.GLib.Object obj = Gst.GLib.Object.GetObject (handle, owned);
			return GetObject (obj);
		}

		public static PropertyProbe GetObject (Gst.GLib.Object obj)
		{
			if (obj == null)
				return null;
			else if (obj is PropertyProbeImplementor)
				return new PropertyProbeAdapter (obj as PropertyProbeImplementor);
			else if (obj as PropertyProbe == null)
				return new PropertyProbeAdapter (obj.Handle);
			else
				return obj as PropertyProbe;
		}

		public PropertyProbeImplementor Implementor {
			get {
				return implementor as PropertyProbeImplementor;
			}
		}
		

		[Gst.GLib.Signal("probe-needed")]
		public event Gst.Interfaces.ProbeNeededHandler ProbeNeeded {
			add {
				Gst.GLib.Signal sig = Gst.GLib.Signal.Lookup (Gst.GLib.Object.GetObject (Handle), "probe-needed", typeof (Gst.Interfaces.ProbeNeededArgs));
				sig.AddDelegate (value);
			}
			remove {
				Gst.GLib.Signal sig = Gst.GLib.Signal.Lookup (Gst.GLib.Object.GetObject (Handle), "probe-needed", typeof (Gst.Interfaces.ProbeNeededArgs));
				sig.RemoveDelegate (value);
			}
		}

		[DllImport("libgstinterfaces-0.10.dll")]
		static extern bool gst_property_probe_needs_probe_name(IntPtr raw, IntPtr name);

		public bool NeedsProbe(string name) {
			IntPtr native_name = Gst.GLib.Marshaller.StringToPtrGStrdup (name);
			bool raw_ret = gst_property_probe_needs_probe_name(Handle, native_name);
			bool ret = raw_ret;
			Gst.GLib.Marshaller.Free (native_name);
			return ret;
		}

		[DllImport("libgstinterfaces-0.10.dll")]
		static extern void gst_property_probe_probe_property_name(IntPtr raw, IntPtr name);

		public void Probe(string name) {
			IntPtr native_name = Gst.GLib.Marshaller.StringToPtrGStrdup (name);
			gst_property_probe_probe_property_name(Handle, native_name);
			Gst.GLib.Marshaller.Free (native_name);
		}

		[DllImport("libgstinterfaces-0.10.dll")]
		static extern IntPtr gst_property_probe_get_properties(IntPtr raw);

		public string[] Properties { 
			get {
				IntPtr raw_ret = gst_property_probe_get_properties(Handle);
				if (raw_ret == IntPtr.Zero)
					return new string[] {};

				Gst.GLib.List raw_ret_list = new Gst.GLib.List(raw_ret, typeof (IntPtr));
				ArrayList ret = new ArrayList ();

				foreach (IntPtr pspec in raw_ret_list) {
					Gst.PropertyInfo pi = new Gst.PropertyInfo (pspec);
					ret.Add (pi.Name);
				}

				return (string[]) ret.ToArray (typeof (string));
			}
		}

		[DllImport("libgstinterfaces-0.10.dll")]
		static extern IntPtr gst_property_probe_get_values_name (IntPtr raw, IntPtr name);

		public object[] GetValues (string name) {
			IntPtr raw_name = Gst.GLib.Marshaller.StringToPtrGStrdup (name);
			IntPtr raw_ret = gst_property_probe_get_values_name (Handle, raw_name);
			Gst.GLib.Marshaller.Free (raw_name);
			if (raw_ret == IntPtr.Zero)
				return new object[] {};

			Gst.GLib.ValueArray va = new Gst.GLib.ValueArray (raw_ret);
			ArrayList ret = new ArrayList ();
			foreach (Gst.GLib.Value v in va)
			  ret.Add ((object) v.Val);

			va.Dispose ();

			return (object[]) ret.ToArray (typeof (object));		
		}

		[DllImport("libgstinterfaces-0.10.dll")]
		static extern IntPtr gst_property_probe_probe_and_get_values_name (IntPtr raw, IntPtr name);

		public object[] ProbeAndGetValues (string name) {
			IntPtr raw_name = Gst.GLib.Marshaller.StringToPtrGStrdup (name);
			IntPtr raw_ret = gst_property_probe_probe_and_get_values_name (Handle, raw_name);
			Gst.GLib.Marshaller.Free (raw_name);
			if (raw_ret == IntPtr.Zero)
				return new object[] {};

			Gst.GLib.ValueArray va = new Gst.GLib.ValueArray (raw_ret);
			ArrayList ret = new ArrayList ();
			foreach (Gst.GLib.Value v in va)
			  ret.Add ((object) v.Val);

			va.Dispose ();

			return (object[]) ret.ToArray (typeof (object));		
		}
	}
}