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

namespace Gst.ControllerSharp {

	using System;
	using System.Runtime.InteropServices;

#region Autogenerated code
	[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
	internal delegate void DirectControlBindingConvertValueNative(IntPtr self, double src_value, IntPtr dest_value);

	internal class DirectControlBindingConvertValueInvoker {

		DirectControlBindingConvertValueNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

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

		internal DirectControlBindingConvertValueInvoker (DirectControlBindingConvertValueNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal DirectControlBindingConvertValueInvoker (DirectControlBindingConvertValueNative native_cb, IntPtr data) : this (native_cb, data, null) {}

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

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

		void InvokeNative (Gst.Controller.DirectControlBinding self, double src_value, IntPtr dest_value)
		{
			native_cb (self == null ? IntPtr.Zero : self.Handle, src_value, dest_value);
		}
	}

	internal class DirectControlBindingConvertValueWrapper {

		public void NativeCallback (IntPtr self, double src_value, IntPtr dest_value)
		{
			try {
				managed (GLib.Object.GetObject(self) as Gst.Controller.DirectControlBinding, src_value, dest_value);
				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 DirectControlBindingConvertValueNative NativeDelegate;
		Gst.Controller.DirectControlBindingConvertValue managed;

		public DirectControlBindingConvertValueWrapper (Gst.Controller.DirectControlBindingConvertValue managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new DirectControlBindingConvertValueNative (NativeCallback);
		}

		public static Gst.Controller.DirectControlBindingConvertValue GetManagedDelegate (DirectControlBindingConvertValueNative native)
		{
			if (native == null)
				return null;
			DirectControlBindingConvertValueWrapper wrapper = (DirectControlBindingConvertValueWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
