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

		public Gst.Video.VideoTimeCodeConfig Config;
		public uint Hours;
		public uint Minutes;
		public uint Seconds;
		public uint Frames;
		public uint FieldCount;

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

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

		[DllImport("gstvideo-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern IntPtr gst_video_time_code_new(uint fps_n, uint fps_d, IntPtr latest_daily_jam, int flags, uint hours, uint minutes, uint seconds, uint frames, uint field_count);

		public static VideoTimeCode New(uint fps_n, uint fps_d, GLib.DateTime latest_daily_jam, Gst.Video.VideoTimeCodeFlags flags, uint hours, uint minutes, uint seconds, uint frames, uint field_count)
		{
			VideoTimeCode result = VideoTimeCode.New (gst_video_time_code_new(fps_n, fps_d, latest_daily_jam == null ? IntPtr.Zero : latest_daily_jam.Handle, (int) flags, hours, minutes, seconds, frames, field_count));
			return result;
		}

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

		public static VideoTimeCode NewEmpty()
		{
			VideoTimeCode result = VideoTimeCode.New (gst_video_time_code_new_empty());
			return result;
		}

		[DllImport("gstvideo-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern IntPtr gst_video_time_code_new_from_date_time(uint fps_n, uint fps_d, IntPtr dt, int flags, uint field_count);

		public static VideoTimeCode NewFromDateTime(uint fps_n, uint fps_d, GLib.DateTime dt, Gst.Video.VideoTimeCodeFlags flags, uint field_count)
		{
			VideoTimeCode result = VideoTimeCode.New (gst_video_time_code_new_from_date_time(fps_n, fps_d, dt == null ? IntPtr.Zero : dt.Handle, (int) flags, field_count));
			return result;
		}

		[DllImport("gstvideo-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern IntPtr gst_video_time_code_new_from_date_time_full(uint fps_n, uint fps_d, IntPtr dt, int flags, uint field_count);

		public static VideoTimeCode NewFromDateTimeFull(uint fps_n, uint fps_d, GLib.DateTime dt, Gst.Video.VideoTimeCodeFlags flags, uint field_count)
		{
			VideoTimeCode result = VideoTimeCode.New (gst_video_time_code_new_from_date_time_full(fps_n, fps_d, dt == null ? IntPtr.Zero : dt.Handle, (int) flags, field_count));
			return result;
		}

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

		public static VideoTimeCode NewFromString(string tc_str)
		{
			IntPtr native_tc_str = GLib.Marshaller.StringToPtrGStrdup (tc_str);
			VideoTimeCode result = VideoTimeCode.New (gst_video_time_code_new_from_string(native_tc_str));
			GLib.Marshaller.Free (native_tc_str);
			return result;
		}

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

		public static GLib.GType GType { 
			get {
				IntPtr raw_ret = gst_video_time_code_get_type();
				GLib.GType ret = new GLib.GType(raw_ret);
				return ret;
			}
		}

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

		public void AddFrames(long frames) {
			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_time_code_add_frames(this_as_native, frames);
			ReadNative (this_as_native, ref this);
			System.Runtime.InteropServices.Marshal.FreeHGlobal (this_as_native);
		}

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

		public Gst.Video.VideoTimeCode AddInterval(Gst.Video.VideoTimeCodeInterval tc_inter) {
			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);
			IntPtr native_tc_inter = GLib.Marshaller.StructureToPtrAlloc (tc_inter);
			IntPtr raw_ret = gst_video_time_code_add_interval(this_as_native, native_tc_inter);
			Gst.Video.VideoTimeCode ret = Gst.Video.VideoTimeCode.New (raw_ret);
			ReadNative (this_as_native, ref this);
			System.Runtime.InteropServices.Marshal.FreeHGlobal (this_as_native);
			Marshal.FreeHGlobal (native_tc_inter);
			return ret;
		}

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

		public void Clear() {
			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_time_code_clear(this_as_native);
			ReadNative (this_as_native, ref this);
			System.Runtime.InteropServices.Marshal.FreeHGlobal (this_as_native);
		}

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

		public int Compare(Gst.Video.VideoTimeCode tc2) {
			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);
			IntPtr native_tc2 = GLib.Marshaller.StructureToPtrAlloc (tc2);
			int raw_ret = gst_video_time_code_compare(this_as_native, native_tc2);
			int ret = raw_ret;
			ReadNative (this_as_native, ref this);
			System.Runtime.InteropServices.Marshal.FreeHGlobal (this_as_native);
			Marshal.FreeHGlobal (native_tc2);
			return ret;
		}

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

		public ulong FramesSinceDailyJam() {
			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);
			ulong raw_ret = gst_video_time_code_frames_since_daily_jam(this_as_native);
			ulong ret = raw_ret;
			ReadNative (this_as_native, ref this);
			System.Runtime.InteropServices.Marshal.FreeHGlobal (this_as_native);
			return ret;
		}

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

		public void IncrementFrame() {
			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_time_code_increment_frame(this_as_native);
			ReadNative (this_as_native, ref this);
			System.Runtime.InteropServices.Marshal.FreeHGlobal (this_as_native);
		}

		[DllImport("gstvideo-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_video_time_code_init(IntPtr raw, uint fps_n, uint fps_d, IntPtr latest_daily_jam, int flags, uint hours, uint minutes, uint seconds, uint frames, uint field_count);

		public void Init(uint fps_n, uint fps_d, GLib.DateTime latest_daily_jam, Gst.Video.VideoTimeCodeFlags flags, uint hours, uint minutes, uint seconds, uint frames, uint field_count) {
			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_time_code_init(this_as_native, fps_n, fps_d, latest_daily_jam == null ? IntPtr.Zero : latest_daily_jam.Handle, (int) flags, hours, minutes, seconds, frames, field_count);
			ReadNative (this_as_native, ref this);
			System.Runtime.InteropServices.Marshal.FreeHGlobal (this_as_native);
		}

		public void Init(uint fps_n, uint fps_d, Gst.Video.VideoTimeCodeFlags flags, uint hours, uint minutes, uint seconds, uint frames, uint field_count) {
			Init (fps_n, fps_d, null, flags, hours, minutes, seconds, frames, field_count);
		}

		[DllImport("gstvideo-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_video_time_code_init_from_date_time(IntPtr raw, uint fps_n, uint fps_d, IntPtr dt, int flags, uint field_count);

		public void InitFromDateTime(uint fps_n, uint fps_d, GLib.DateTime dt, Gst.Video.VideoTimeCodeFlags flags, uint field_count) {
			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_time_code_init_from_date_time(this_as_native, fps_n, fps_d, dt == null ? IntPtr.Zero : dt.Handle, (int) flags, field_count);
			ReadNative (this_as_native, ref this);
			System.Runtime.InteropServices.Marshal.FreeHGlobal (this_as_native);
		}

		[DllImport("gstvideo-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_video_time_code_init_from_date_time_full(IntPtr raw, uint fps_n, uint fps_d, IntPtr dt, int flags, uint field_count);

		public bool InitFromDateTimeFull(uint fps_n, uint fps_d, GLib.DateTime dt, Gst.Video.VideoTimeCodeFlags flags, uint field_count) {
			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);
			bool raw_ret = gst_video_time_code_init_from_date_time_full(this_as_native, fps_n, fps_d, dt == null ? IntPtr.Zero : dt.Handle, (int) flags, field_count);
			bool ret = raw_ret;
			ReadNative (this_as_native, ref this);
			System.Runtime.InteropServices.Marshal.FreeHGlobal (this_as_native);
			return ret;
		}

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

		public bool IsValid { 
			get {
				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);
				bool raw_ret = gst_video_time_code_is_valid(this_as_native);
				bool ret = raw_ret;
				ReadNative (this_as_native, ref this);
				System.Runtime.InteropServices.Marshal.FreeHGlobal (this_as_native);
				return ret;
			}
		}

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

		public ulong NsecSinceDailyJam() {
			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);
			ulong raw_ret = gst_video_time_code_nsec_since_daily_jam(this_as_native);
			ulong ret = raw_ret;
			ReadNative (this_as_native, ref this);
			System.Runtime.InteropServices.Marshal.FreeHGlobal (this_as_native);
			return ret;
		}

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

		public GLib.DateTime ToDateTime() {
			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);
			IntPtr raw_ret = gst_video_time_code_to_date_time(this_as_native);
			GLib.DateTime ret = new GLib.DateTime(raw_ret);
			ReadNative (this_as_native, ref this);
			System.Runtime.InteropServices.Marshal.FreeHGlobal (this_as_native);
			return ret;
		}

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

		public override string ToString() {
			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);
			IntPtr raw_ret = gst_video_time_code_to_string(this_as_native);
			string ret = GLib.Marshaller.PtrToStringGFree(raw_ret);
			ReadNative (this_as_native, ref this);
			System.Runtime.InteropServices.Marshal.FreeHGlobal (this_as_native);
			return ret;
		}

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

		public bool Equals (VideoTimeCode other)
		{
			return true && Config.Equals (other.Config) && Hours.Equals (other.Hours) && Minutes.Equals (other.Minutes) && Seconds.Equals (other.Seconds) && Frames.Equals (other.Frames) && FieldCount.Equals (other.FieldCount);
		}

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

		public override int GetHashCode ()
		{
			return this.GetType ().FullName.GetHashCode () ^ Config.GetHashCode () ^ Hours.GetHashCode () ^ Minutes.GetHashCode () ^ Seconds.GetHashCode () ^ Frames.GetHashCode () ^ FieldCount.GetHashCode ();
		}

		public static explicit operator GLib.Value (Gst.Video.VideoTimeCode boxed)
		{
			GLib.Value val = GLib.Value.Empty;
			val.Init (Gst.Video.VideoTimeCode.GType);
			val.Val = boxed;
			return val;
		}

		public static explicit operator Gst.Video.VideoTimeCode (GLib.Value val)
		{
			return (Gst.Video.VideoTimeCode) val.Val;
		}
#endregion
	}
}
