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

namespace Gst {

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

#region Autogenerated code
	public partial class ValueArray : GLib.Opaque {

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

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

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_value_array_append_and_take_value(IntPtr value, IntPtr append_value);

		public static void AppendAndTakeValue(GLib.Value value, GLib.Value append_value) {
			IntPtr native_value = GLib.Marshaller.StructureToPtrAlloc (value);
			IntPtr native_append_value = GLib.Marshaller.StructureToPtrAlloc (append_value);
			gst_value_array_append_and_take_value(native_value, native_append_value);
			Marshal.FreeHGlobal (native_value);
			Marshal.FreeHGlobal (native_append_value);
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_value_array_append_value(IntPtr value, IntPtr append_value);

		public static void AppendValue(GLib.Value value, GLib.Value append_value) {
			IntPtr native_value = GLib.Marshaller.StructureToPtrAlloc (value);
			IntPtr native_append_value = GLib.Marshaller.StructureToPtrAlloc (append_value);
			gst_value_array_append_value(native_value, native_append_value);
			Marshal.FreeHGlobal (native_value);
			Marshal.FreeHGlobal (native_append_value);
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern uint gst_value_array_get_size(IntPtr value);

		public static uint GetSize(GLib.Value value) {
			IntPtr native_value = GLib.Marshaller.StructureToPtrAlloc (value);
			uint raw_ret = gst_value_array_get_size(native_value);
			uint ret = raw_ret;
			Marshal.FreeHGlobal (native_value);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern IntPtr gst_value_array_get_value(IntPtr value, uint index);

		public static GLib.Value GetValue(GLib.Value value, uint index) {
			IntPtr native_value = GLib.Marshaller.StructureToPtrAlloc (value);
			IntPtr raw_ret = gst_value_array_get_value(native_value, index);
			GLib.Value ret = (GLib.Value) Marshal.PtrToStructure (raw_ret, typeof (GLib.Value));
			Marshal.FreeHGlobal (native_value);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern IntPtr gst_value_array_init(IntPtr value, uint prealloc);

		public static GLib.Value Init(GLib.Value value, uint prealloc) {
			IntPtr native_value = GLib.Marshaller.StructureToPtrAlloc (value);
			IntPtr raw_ret = gst_value_array_init(native_value, prealloc);
			GLib.Value ret = (GLib.Value) Marshal.PtrToStructure (raw_ret, typeof (GLib.Value));
			Marshal.FreeHGlobal (native_value);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_value_array_prepend_value(IntPtr value, IntPtr prepend_value);

		public static void PrependValue(GLib.Value value, GLib.Value prepend_value) {
			IntPtr native_value = GLib.Marshaller.StructureToPtrAlloc (value);
			IntPtr native_prepend_value = GLib.Marshaller.StructureToPtrAlloc (prepend_value);
			gst_value_array_prepend_value(native_value, native_prepend_value);
			Marshal.FreeHGlobal (native_value);
			Marshal.FreeHGlobal (native_prepend_value);
		}

		public ValueArray(IntPtr raw) : base(raw) {}


		// Internal representation of the wrapped structure ABI.
		static GLib.AbiStruct _abi_info = null;
		static public GLib.AbiStruct abi_info {
			get {
				if (_abi_info == null)
					_abi_info = new GLib.AbiStruct (new List<GLib.AbiField>{ 
					});

				return _abi_info;
			}
		}


		// End of the ABI representation.

#endregion
	}
}
