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

namespace Gst.RtspServerSharp {

	using System;
	using System.Runtime.InteropServices;

#region Autogenerated code
	[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
	internal delegate void RTSPMessageSentFuncNative(IntPtr user_data);

	internal class RTSPMessageSentFuncInvoker {

		RTSPMessageSentFuncNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

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

		internal RTSPMessageSentFuncInvoker (RTSPMessageSentFuncNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal RTSPMessageSentFuncInvoker (RTSPMessageSentFuncNative native_cb, IntPtr data) : this (native_cb, data, null) {}

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

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

		void InvokeNative ()
		{
			native_cb (__data);
		}
	}

	internal class RTSPMessageSentFuncWrapper {

		public void NativeCallback (IntPtr user_data)
		{
			try {
				managed ();
				if (release_on_call)
					gch.Free ();
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, false);
			}
		}

		bool release_on_call = false;
		GCHandle gch;

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

		internal RTSPMessageSentFuncNative NativeDelegate;
		Gst.RtspServer.RTSPMessageSentFunc managed;

		public RTSPMessageSentFuncWrapper (Gst.RtspServer.RTSPMessageSentFunc managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new RTSPMessageSentFuncNative (NativeCallback);
		}

		public static Gst.RtspServer.RTSPMessageSentFunc GetManagedDelegate (RTSPMessageSentFuncNative native)
		{
			if (native == null)
				return null;
			RTSPMessageSentFuncWrapper wrapper = (RTSPMessageSentFuncWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
