// 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 void DataQueueFullCallbackNative(IntPtr queue, IntPtr checkdata);

	internal class DataQueueFullCallbackInvoker {

		DataQueueFullCallbackNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

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

		internal DataQueueFullCallbackInvoker (DataQueueFullCallbackNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal DataQueueFullCallbackInvoker (DataQueueFullCallbackNative native_cb, IntPtr data) : this (native_cb, data, null) {}

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

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

		void InvokeNative (Gst.Base.DataQueue queue, IntPtr checkdata)
		{
			native_cb (queue == null ? IntPtr.Zero : queue.Handle, __data);
		}
	}

	internal class DataQueueFullCallbackWrapper {

		public void NativeCallback (IntPtr queue, IntPtr checkdata)
		{
			try {
				managed (GLib.Object.GetObject(queue) as Gst.Base.DataQueue, checkdata);
				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 DataQueueFullCallbackNative NativeDelegate;
		Gst.Base.DataQueueFullCallback managed;

		public DataQueueFullCallbackWrapper (Gst.Base.DataQueueFullCallback managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new DataQueueFullCallbackNative (NativeCallback);
		}

		public static Gst.Base.DataQueueFullCallback GetManagedDelegate (DataQueueFullCallbackNative native)
		{
			if (native == null)
				return null;
			DataQueueFullCallbackWrapper wrapper = (DataQueueFullCallbackWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
