// 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 int PadEventFullFunctionNative(IntPtr pad, IntPtr parent, IntPtr evnt);

	internal class PadEventFullFunctionInvoker {

		PadEventFullFunctionNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

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

		internal PadEventFullFunctionInvoker (PadEventFullFunctionNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal PadEventFullFunctionInvoker (PadEventFullFunctionNative native_cb, IntPtr data) : this (native_cb, data, null) {}

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

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

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

	internal class PadEventFullFunctionWrapper {

		public int NativeCallback (IntPtr pad, IntPtr parent, IntPtr evnt)
		{
			try {
				Gst.FlowReturn __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 (int) __ret;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: Above call does not return.
				throw e;
			}
		}

		bool release_on_call = false;
		GCHandle gch;

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

		internal PadEventFullFunctionNative NativeDelegate;
		Gst.PadEventFullFunction managed;

		public PadEventFullFunctionWrapper (Gst.PadEventFullFunction managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new PadEventFullFunctionNative (NativeCallback);
		}

		public static Gst.PadEventFullFunction GetManagedDelegate (PadEventFullFunctionNative native)
		{
			if (native == null)
				return null;
			PadEventFullFunctionWrapper wrapper = (PadEventFullFunctionWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
