// 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 bool ControlSourceGetValueArrayNative(IntPtr self, ulong timestamp, ulong interval, uint n_values, double values);

	internal class ControlSourceGetValueArrayInvoker {

		ControlSourceGetValueArrayNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

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

		internal ControlSourceGetValueArrayInvoker (ControlSourceGetValueArrayNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal ControlSourceGetValueArrayInvoker (ControlSourceGetValueArrayNative native_cb, IntPtr data) : this (native_cb, data, null) {}

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

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

		bool InvokeNative (Gst.ControlSource self, ulong timestamp, ulong interval, uint n_values, double values)
		{
			bool __result = native_cb (self == null ? IntPtr.Zero : self.Handle, timestamp, interval, n_values, values);
			return __result;
		}
	}

	internal class ControlSourceGetValueArrayWrapper {

		public bool NativeCallback (IntPtr self, ulong timestamp, ulong interval, uint n_values, double values)
		{
			try {
				bool __ret = managed (GLib.Object.GetObject(self) as Gst.ControlSource, timestamp, interval, n_values, values);
				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 ControlSourceGetValueArrayNative NativeDelegate;
		Gst.ControlSourceGetValueArray managed;

		public ControlSourceGetValueArrayWrapper (Gst.ControlSourceGetValueArray managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new ControlSourceGetValueArrayNative (NativeCallback);
		}

		public static Gst.ControlSourceGetValueArray GetManagedDelegate (ControlSourceGetValueArrayNative native)
		{
			if (native == null)
				return null;
			ControlSourceGetValueArrayWrapper wrapper = (ControlSourceGetValueArrayWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
