// This file was generated by the Gtk# code generator.
// Any changes made will be lost if regenerated.

namespace GstSharp {

	using System;
	using System.Runtime.InteropServices;

#region Autogenerated code
	[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
	internal delegate bool PadEventFunctionNative(IntPtr pad, IntPtr parent, IntPtr evnt);

	internal class PadEventFunctionInvoker {

		PadEventFunctionNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

		~PadEventFunctionInvoker ()
		{
			if (__notify == null)
				return;
			__notify (__data);
		}

		internal PadEventFunctionInvoker (PadEventFunctionNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal PadEventFunctionInvoker (PadEventFunctionNative native_cb, IntPtr data) : this (native_cb, data, null) {}

		internal PadEventFunctionInvoker (PadEventFunctionNative native_cb, IntPtr data, GLib.DestroyNotify notify)
		{
			this.native_cb = native_cb;
			__data = data;
			__notify = notify;
		}

		internal Gst.PadEventFunction Handler {
			get {
				return new Gst.PadEventFunction(InvokeNative);
			}
		}

		bool InvokeNative (Gst.Pad pad, Gst.Object parent, Gst.Event evnt)
		{
			evnt.Owned = false;
			bool __result = native_cb (pad == null ? IntPtr.Zero : pad.Handle, parent == null ? IntPtr.Zero : parent.Handle, evnt == null ? IntPtr.Zero : evnt.Handle);
			return __result;
		}
	}

	internal class PadEventFunctionWrapper {

		public bool NativeCallback (IntPtr pad, IntPtr parent, IntPtr evnt)
		{
			try {
				bool __ret = managed (GLib.Object.GetObject(pad) as Gst.Pad, GLib.Object.GetObject(parent) as Gst.Object, evnt == IntPtr.Zero ? null : (Gst.Event) GLib.Opaque.GetOpaque (evnt, typeof (Gst.Event), true));
				if (release_on_call)
					gch.Free ();
				return __ret;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, false);
				return false;
			}
		}

		bool release_on_call = false;
		GCHandle gch;

		public void PersistUntilCalled ()
		{
			release_on_call = true;
			gch = GCHandle.Alloc (this);
		}

		internal PadEventFunctionNative NativeDelegate;
		Gst.PadEventFunction managed;

		public PadEventFunctionWrapper (Gst.PadEventFunction managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new PadEventFunctionNative (NativeCallback);
		}

		public static Gst.PadEventFunction GetManagedDelegate (PadEventFunctionNative native)
		{
			if (native == null)
				return null;
			PadEventFunctionWrapper wrapper = (PadEventFunctionWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
