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

namespace Gst.BaseSharp {

	using System;
	using System.Runtime.InteropServices;

#region Autogenerated code
	[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
	internal delegate bool DataQueueCheckFullFunctionNative(IntPtr queue, uint visible, uint bytes, ulong time, IntPtr checkdata);

	internal class DataQueueCheckFullFunctionInvoker {

		DataQueueCheckFullFunctionNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

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

		internal DataQueueCheckFullFunctionInvoker (DataQueueCheckFullFunctionNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal DataQueueCheckFullFunctionInvoker (DataQueueCheckFullFunctionNative native_cb, IntPtr data) : this (native_cb, data, null) {}

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

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

		bool InvokeNative (Gst.Base.DataQueue queue, uint visible, uint bytes, ulong time, IntPtr checkdata)
		{
			bool __result = native_cb (queue == null ? IntPtr.Zero : queue.Handle, visible, bytes, time, __data);
			return __result;
		}
	}

	internal class DataQueueCheckFullFunctionWrapper {

		public bool NativeCallback (IntPtr queue, uint visible, uint bytes, ulong time, IntPtr checkdata)
		{
			try {
				bool __ret = managed (GLib.Object.GetObject(queue) as Gst.Base.DataQueue, visible, bytes, time, checkdata);
				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 DataQueueCheckFullFunctionNative NativeDelegate;
		Gst.Base.DataQueueCheckFullFunction managed;

		public DataQueueCheckFullFunctionWrapper (Gst.Base.DataQueueCheckFullFunction managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new DataQueueCheckFullFunctionNative (NativeCallback);
		}

		public static Gst.Base.DataQueueCheckFullFunction GetManagedDelegate (DataQueueCheckFullFunctionNative native)
		{
			if (native == null)
				return null;
			DataQueueCheckFullFunctionWrapper wrapper = (DataQueueCheckFullFunctionWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
