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

namespace GESSharp {

	using System;
	using System.Runtime.InteropServices;

#region Autogenerated code
	[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
	internal delegate IntPtr ExtractableCheckIdNative(IntPtr type, IntPtr id, out IntPtr error);

	internal class ExtractableCheckIdInvoker {

		ExtractableCheckIdNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

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

		internal ExtractableCheckIdInvoker (ExtractableCheckIdNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal ExtractableCheckIdInvoker (ExtractableCheckIdNative native_cb, IntPtr data) : this (native_cb, data, null) {}

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

		internal GES.ExtractableCheckId Handler {
			get {
				return new GES.ExtractableCheckId(InvokeNative);
			}
		}

		string InvokeNative (GLib.GType type, string id)
		{
			IntPtr native_id = GLib.Marshaller.StringToPtrGStrdup (id);
			IntPtr error = IntPtr.Zero;
			string __result = GLib.Marshaller.PtrToStringGFree(native_cb (type.Val, native_id, out error));
			GLib.Marshaller.Free (native_id);
			return __result;
		}
	}

	internal class ExtractableCheckIdWrapper {

		public IntPtr NativeCallback (IntPtr type, IntPtr id, out IntPtr error)
		{
			error = IntPtr.Zero;

			try {
				string __ret = managed (new GLib.GType(type), GLib.Marshaller.Utf8PtrToString (id));
				if (release_on_call)
					gch.Free ();
				return GLib.Marshaller.StringToPtrGStrdup(__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 ExtractableCheckIdNative NativeDelegate;
		GES.ExtractableCheckId managed;

		public ExtractableCheckIdWrapper (GES.ExtractableCheckId managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new ExtractableCheckIdNative (NativeCallback);
		}

		public static GES.ExtractableCheckId GetManagedDelegate (ExtractableCheckIdNative native)
		{
			if (native == null)
				return null;
			ExtractableCheckIdWrapper wrapper = (ExtractableCheckIdWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
