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

namespace GstSharp {

	using System;
	using System.Runtime.InteropServices;

#region Autogenerated code
	[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
	internal delegate int PadGetRangeFunctionNative(IntPtr pad, IntPtr parent, ulong offset, uint length, IntPtr buffer);

	internal class PadGetRangeFunctionInvoker {

		PadGetRangeFunctionNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

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

		internal PadGetRangeFunctionInvoker (PadGetRangeFunctionNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal PadGetRangeFunctionInvoker (PadGetRangeFunctionNative native_cb, IntPtr data) : this (native_cb, data, null) {}

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

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

		Gst.FlowReturn InvokeNative (Gst.Pad pad, Gst.Object parent, ulong offset, uint length, Gst.Buffer buffer)
		{
			Gst.FlowReturn __result = (Gst.FlowReturn) native_cb (pad == null ? IntPtr.Zero : pad.Handle, parent == null ? IntPtr.Zero : parent.Handle, offset, length, buffer == null ? IntPtr.Zero : buffer.Handle);
			return __result;
		}
	}

	internal class PadGetRangeFunctionWrapper {

		public int NativeCallback (IntPtr pad, IntPtr parent, ulong offset, uint length, IntPtr buffer)
		{
			try {
				Gst.FlowReturn __ret = managed (GLib.Object.GetObject(pad) as Gst.Pad, GLib.Object.GetObject(parent) as Gst.Object, offset, length, buffer == IntPtr.Zero ? null : (Gst.Buffer) GLib.Opaque.GetOpaque (buffer, typeof (Gst.Buffer), false));
				if (release_on_call)
					gch.Free ();
				return (int) __ret;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: Above call does not return.
				throw e;
			}
		}

		bool release_on_call = false;
		GCHandle gch;

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

		internal PadGetRangeFunctionNative NativeDelegate;
		Gst.PadGetRangeFunction managed;

		public PadGetRangeFunctionWrapper (Gst.PadGetRangeFunction managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new PadGetRangeFunctionNative (NativeCallback);
		}

		public static Gst.PadGetRangeFunction GetManagedDelegate (PadGetRangeFunctionNative native)
		{
			if (native == null)
				return null;
			PadGetRangeFunctionWrapper wrapper = (PadGetRangeFunctionWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
