// 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 VideoAlignment : IEquatable<VideoAlignment> {

		public uint PaddingTop;
		public uint PaddingBottom;
		public uint PaddingLeft;
		public uint PaddingRight;
		[MarshalAs (UnmanagedType.ByValArray, SizeConst=4)]
		public uint[] StrideAlign;

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

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

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

		public void Reset() {
			IntPtr this_as_native = System.Runtime.InteropServices.Marshal.AllocHGlobal (System.Runtime.InteropServices.Marshal.SizeOf (this));
			System.Runtime.InteropServices.Marshal.StructureToPtr (this, this_as_native, false);
			gst_video_alignment_reset(this_as_native);
			ReadNative (this_as_native, ref this);
			System.Runtime.InteropServices.Marshal.FreeHGlobal (this_as_native);
		}

		static void ReadNative (IntPtr native, ref Gst.Video.VideoAlignment target)
		{
			target = New (native);
		}

		public bool Equals (VideoAlignment other)
		{
			return true && PaddingTop.Equals (other.PaddingTop) && PaddingBottom.Equals (other.PaddingBottom) && PaddingLeft.Equals (other.PaddingLeft) && PaddingRight.Equals (other.PaddingRight) && StrideAlign.Equals (other.StrideAlign);
		}

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

		public override int GetHashCode ()
		{
			return this.GetType ().FullName.GetHashCode () ^ PaddingTop.GetHashCode () ^ PaddingBottom.GetHashCode () ^ PaddingLeft.GetHashCode () ^ PaddingRight.GetHashCode () ^ StrideAlign.GetHashCode ();
		}

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