// 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 bool RTSPClientSendMessagesFuncNative(IntPtr client, IntPtr messages, uint n_messages, bool close, IntPtr user_data);

	internal class RTSPClientSendMessagesFuncInvoker {

		RTSPClientSendMessagesFuncNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

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

		internal RTSPClientSendMessagesFuncInvoker (RTSPClientSendMessagesFuncNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal RTSPClientSendMessagesFuncInvoker (RTSPClientSendMessagesFuncNative native_cb, IntPtr data) : this (native_cb, data, null) {}

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

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

		bool InvokeNative (Gst.RtspServer.RTSPClient client, Gst.Rtsp.RTSPMessage messages, uint n_messages, bool close)
		{
			IntPtr native_messages = GLib.Marshaller.StructureToPtrAlloc (messages);
			bool __result = native_cb (client == null ? IntPtr.Zero : client.Handle, native_messages, n_messages, close, __data);
			Marshal.FreeHGlobal (native_messages);
			return __result;
		}
	}

	internal class RTSPClientSendMessagesFuncWrapper {

		public bool NativeCallback (IntPtr client, IntPtr messages, uint n_messages, bool close, IntPtr user_data)
		{
			try {
				bool __ret = managed (GLib.Object.GetObject(client) as Gst.RtspServer.RTSPClient, Gst.Rtsp.RTSPMessage.New (messages), n_messages, close);
				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 RTSPClientSendMessagesFuncNative NativeDelegate;
		Gst.RtspServer.RTSPClientSendMessagesFunc managed;

		public RTSPClientSendMessagesFuncWrapper (Gst.RtspServer.RTSPClientSendMessagesFunc managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new RTSPClientSendMessagesFuncNative (NativeCallback);
		}

		public static Gst.RtspServer.RTSPClientSendMessagesFunc GetManagedDelegate (RTSPClientSendMessagesFuncNative native)
		{
			if (native == null)
				return null;
			RTSPClientSendMessagesFuncWrapper wrapper = (RTSPClientSendMessagesFuncWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
