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

namespace Gst.NetSharp {

	using System;
	using System.Runtime.InteropServices;

#region Autogenerated code
	[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
	internal delegate bool PtpStatisticsCallbackNative(byte domain, IntPtr stats, IntPtr user_data);

	internal class PtpStatisticsCallbackInvoker {

		PtpStatisticsCallbackNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

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

		internal PtpStatisticsCallbackInvoker (PtpStatisticsCallbackNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal PtpStatisticsCallbackInvoker (PtpStatisticsCallbackNative native_cb, IntPtr data) : this (native_cb, data, null) {}

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

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

		bool InvokeNative (byte domain, Gst.Structure stats)
		{
			bool __result = native_cb (domain, stats == null ? IntPtr.Zero : stats.Handle, __data);
			return __result;
		}
	}

	internal class PtpStatisticsCallbackWrapper {

		public bool NativeCallback (byte domain, IntPtr stats, IntPtr user_data)
		{
			try {
				bool __ret = managed (domain, stats == IntPtr.Zero ? null : (Gst.Structure) GLib.Opaque.GetOpaque (stats, typeof (Gst.Structure), false));
				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 PtpStatisticsCallbackNative NativeDelegate;
		Gst.Net.PtpStatisticsCallback managed;

		public PtpStatisticsCallbackWrapper (Gst.Net.PtpStatisticsCallback managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new PtpStatisticsCallbackNative (NativeCallback);
		}

		public static Gst.Net.PtpStatisticsCallback GetManagedDelegate (PtpStatisticsCallbackNative native)
		{
			if (native == null)
				return null;
			PtpStatisticsCallbackWrapper wrapper = (PtpStatisticsCallbackWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
