// 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 PluginInitFullFuncNative(IntPtr plugin, IntPtr user_data);

	internal class PluginInitFullFuncInvoker {

		PluginInitFullFuncNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

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

		internal PluginInitFullFuncInvoker (PluginInitFullFuncNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal PluginInitFullFuncInvoker (PluginInitFullFuncNative native_cb, IntPtr data) : this (native_cb, data, null) {}

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

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

		bool InvokeNative (Gst.Plugin plugin)
		{
			bool __result = native_cb (plugin == null ? IntPtr.Zero : plugin.Handle, __data);
			return __result;
		}
	}

	internal class PluginInitFullFuncWrapper {

		public bool NativeCallback (IntPtr plugin, IntPtr user_data)
		{
			try {
				bool __ret = managed (GLib.Object.GetObject(plugin) as Gst.Plugin);
				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 PluginInitFullFuncNative NativeDelegate;
		Gst.PluginInitFullFunc managed;

		public PluginInitFullFuncWrapper (Gst.PluginInitFullFunc managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new PluginInitFullFuncNative (NativeCallback);
		}

		public static Gst.PluginInitFullFunc GetManagedDelegate (PluginInitFullFuncNative native)
		{
			if (native == null)
				return null;
			PluginInitFullFuncWrapper wrapper = (PluginInitFullFuncWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
