// 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 CreateTrackElementFuncNative(IntPtr clip, int type);

	internal class CreateTrackElementFuncInvoker {

		CreateTrackElementFuncNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

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

		internal CreateTrackElementFuncInvoker (CreateTrackElementFuncNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal CreateTrackElementFuncInvoker (CreateTrackElementFuncNative native_cb, IntPtr data) : this (native_cb, data, null) {}

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

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

		GES.TrackElement InvokeNative (GES.Clip clip, GES.TrackType type)
		{
			GES.TrackElement __result = GLib.Object.GetObject(native_cb (clip == null ? IntPtr.Zero : clip.Handle, (int) type)) as GES.TrackElement;
			return __result;
		}
	}

	internal class CreateTrackElementFuncWrapper {

		public IntPtr NativeCallback (IntPtr clip, int type)
		{
			try {
				GES.TrackElement __ret = managed (GLib.Object.GetObject(clip) as GES.Clip, (GES.TrackType) type);
				if (release_on_call)
					gch.Free ();
				return __ret == null ? IntPtr.Zero : __ret.Handle;
			} 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 CreateTrackElementFuncNative NativeDelegate;
		GES.CreateTrackElementFunc managed;

		public CreateTrackElementFuncWrapper (GES.CreateTrackElementFunc managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new CreateTrackElementFuncNative (NativeCallback);
		}

		public static GES.CreateTrackElementFunc GetManagedDelegate (CreateTrackElementFuncNative native)
		{
			if (native == null)
				return null;
			CreateTrackElementFuncWrapper wrapper = (CreateTrackElementFuncWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
