// 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 RTSPMessageSentFuncFullNative(IntPtr trans, IntPtr user_data);

	internal class RTSPMessageSentFuncFullInvoker {

		RTSPMessageSentFuncFullNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

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

		internal RTSPMessageSentFuncFullInvoker (RTSPMessageSentFuncFullNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal RTSPMessageSentFuncFullInvoker (RTSPMessageSentFuncFullNative native_cb, IntPtr data) : this (native_cb, data, null) {}

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

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

		void InvokeNative (Gst.RtspServer.RTSPStreamTransport trans)
		{
			native_cb (trans == null ? IntPtr.Zero : trans.Handle, __data);
		}
	}

	internal class RTSPMessageSentFuncFullWrapper {

		public void NativeCallback (IntPtr trans, IntPtr user_data)
		{
			try {
				managed (GLib.Object.GetObject(trans) as Gst.RtspServer.RTSPStreamTransport);
				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 RTSPMessageSentFuncFullNative NativeDelegate;
		Gst.RtspServer.RTSPMessageSentFuncFull managed;

		public RTSPMessageSentFuncFullWrapper (Gst.RtspServer.RTSPMessageSentFuncFull managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new RTSPMessageSentFuncFullNative (NativeCallback);
		}

		public static Gst.RtspServer.RTSPMessageSentFuncFull GetManagedDelegate (RTSPMessageSentFuncFullNative native)
		{
			if (native == null)
				return null;
			RTSPMessageSentFuncFullWrapper wrapper = (RTSPMessageSentFuncFullWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
