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

namespace Gst.Video {

	using System;
	using System.Collections;
	using System.Collections.Generic;
	using System.Runtime.InteropServices;

#region Autogenerated code
	[StructLayout(LayoutKind.Sequential)]
	public partial struct VideoCodecAlphaMeta : IEquatable<VideoCodecAlphaMeta> {

		public Gst.Meta Meta;
		private IntPtr _buffer;
		public Gst.Buffer Buffer {
			get {
				return _buffer == IntPtr.Zero ? null : (Gst.Buffer) GLib.Opaque.GetOpaque (_buffer, typeof (Gst.Buffer), false);
			}
			set {
				_buffer = value == null ? IntPtr.Zero : value.Handle;
			}
		}

		public static Gst.Video.VideoCodecAlphaMeta Zero = new Gst.Video.VideoCodecAlphaMeta ();

		public static Gst.Video.VideoCodecAlphaMeta New(IntPtr raw) {
			if (raw == IntPtr.Zero)
				return Gst.Video.VideoCodecAlphaMeta.Zero;
			return (Gst.Video.VideoCodecAlphaMeta) Marshal.PtrToStructure (raw, typeof (Gst.Video.VideoCodecAlphaMeta));
		}

		[DllImport("gstvideo-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern IntPtr gst_video_codec_alpha_meta_get_info();

		public static Gst.MetaInfo Info { 
			get {
				IntPtr raw_ret = gst_video_codec_alpha_meta_get_info();
				Gst.MetaInfo ret = Gst.MetaInfo.New (raw_ret);
				return ret;
			}
		}

		public bool Equals (VideoCodecAlphaMeta other)
		{
			return true && Meta.Equals (other.Meta) && Buffer.Equals (other.Buffer);
		}

		public override bool Equals (object other)
		{
			return other is VideoCodecAlphaMeta && Equals ((VideoCodecAlphaMeta) other);
		}

		public override int GetHashCode ()
		{
			return this.GetType ().FullName.GetHashCode () ^ Meta.GetHashCode () ^ Buffer.GetHashCode ();
		}

		private static GLib.GType GType {
			get { return GLib.GType.Pointer; }
		}
#endregion
	}
}
