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

namespace Gst.Net {

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

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

		public Gst.Meta Meta;
		private IntPtr _message;
		public GLib.SocketControlMessage Message {
			get {
				return GLib.Object.GetObject(_message) as GLib.SocketControlMessage;
			}
			set {
				_message = value == null ? IntPtr.Zero : value.Handle;
			}
		}

		public static Gst.Net.NetControlMessageMeta Zero = new Gst.Net.NetControlMessageMeta ();

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

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

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

		public bool Equals (NetControlMessageMeta other)
		{
			return true && Meta.Equals (other.Meta) && Message.Equals (other.Message);
		}

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

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

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