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

	internal class PadIterIntLinkFunctionInvoker {

		PadIterIntLinkFunctionNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

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

		internal PadIterIntLinkFunctionInvoker (PadIterIntLinkFunctionNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal PadIterIntLinkFunctionInvoker (PadIterIntLinkFunctionNative native_cb, IntPtr data) : this (native_cb, data, null) {}

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

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

		Gst.Iterator InvokeNative (Gst.Pad pad, Gst.Object parent)
		{
			Gst.Iterator __result = native_cb (pad == null ? IntPtr.Zero : pad.Handle, parent == null ? IntPtr.Zero : parent.Handle) == IntPtr.Zero ? null : (Gst.Iterator) GLib.Opaque.GetOpaque (native_cb (pad == null ? IntPtr.Zero : pad.Handle, parent == null ? IntPtr.Zero : parent.Handle), typeof (Gst.Iterator), true);
			return __result;
		}
	}

	internal class PadIterIntLinkFunctionWrapper {

		public IntPtr NativeCallback (IntPtr pad, IntPtr parent)
		{
			try {
				Gst.Iterator __ret = managed (GLib.Object.GetObject(pad) as Gst.Pad, GLib.Object.GetObject(parent) as Gst.Object);
				if (release_on_call)
					gch.Free ();
				return __ret == null ? IntPtr.Zero : __ret.OwnedCopy;
			} 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 PadIterIntLinkFunctionNative NativeDelegate;
		Gst.PadIterIntLinkFunction managed;

		public PadIterIntLinkFunctionWrapper (Gst.PadIterIntLinkFunction managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new PadIterIntLinkFunctionNative (NativeCallback);
		}

		public static Gst.PadIterIntLinkFunction GetManagedDelegate (PadIterIntLinkFunctionNative native)
		{
			if (native == null)
				return null;
			PadIterIntLinkFunctionWrapper wrapper = (PadIterIntLinkFunctionWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
