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

namespace Gst.VideoSharp {

	using System;
	using System.Runtime.InteropServices;

#region Autogenerated code
	[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
	internal delegate bool VideoGLTextureUploadNative(IntPtr meta, uint texture_id);

	internal class VideoGLTextureUploadInvoker {

		VideoGLTextureUploadNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

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

		internal VideoGLTextureUploadInvoker (VideoGLTextureUploadNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal VideoGLTextureUploadInvoker (VideoGLTextureUploadNative native_cb, IntPtr data) : this (native_cb, data, null) {}

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

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

		bool InvokeNative (Gst.Video.VideoGLTextureUploadMeta meta, uint texture_id)
		{
			IntPtr native_meta = GLib.Marshaller.StructureToPtrAlloc (meta);
			bool __result = native_cb (native_meta, texture_id);
			Marshal.FreeHGlobal (native_meta);
			return __result;
		}
	}

	internal class VideoGLTextureUploadWrapper {

		public bool NativeCallback (IntPtr meta, uint texture_id)
		{
			try {
				bool __ret = managed (Gst.Video.VideoGLTextureUploadMeta.New (meta), texture_id);
				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 VideoGLTextureUploadNative NativeDelegate;
		Gst.Video.VideoGLTextureUpload managed;

		public VideoGLTextureUploadWrapper (Gst.Video.VideoGLTextureUpload managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new VideoGLTextureUploadNative (NativeCallback);
		}

		public static Gst.Video.VideoGLTextureUpload GetManagedDelegate (VideoGLTextureUploadNative native)
		{
			if (native == null)
				return null;
			VideoGLTextureUploadWrapper wrapper = (VideoGLTextureUploadWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
