context: // Copyright (c) 2011 Novell, Inc.
  //
  // This program is free software; you can redistribute it and/or
  // modify it under the terms of version 2 of the Lesser GNU General 
  // Public License as published by the Free Software Foundation.
  //
  // This program is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  // Lesser General Public License for more details.
  //
  // You should have received a copy of the GNU Lesser General Public
  // License along with this program; if not, write to the
  // Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  // Boston, MA 02111-1307, USA.
  
  using System;
  using System.Runtime.InteropServices;
  
  namespace GLib {
  
  	public class VariantType : IDisposable {
  
  		public static VariantType Boolean = new VariantType ("b");
  		public static VariantType Byte = new VariantType ("y");
  		public static VariantType Int16 = new VariantType ("n");
  		public static VariantType UInt16 = new VariantType ("q");
  		public static VariantType Int32 = new VariantType ("i");
  		public static VariantType Uint32 = new VariantType ("u");
  		public static VariantType Int64 = new VariantType ("x");
  		public static VariantType UInt64 = new VariantType ("t");
  		public static VariantType Double = new VariantType ("d");
  		public static VariantType String = new VariantType ("s");
  		public static VariantType Path = new VariantType ("o");
  		public static VariantType Signature = new VariantType ("g");
  		public static VariantType Variant = new VariantType ("v");
  		public static VariantType HandleType = new VariantType ("h");
  		public static VariantType Unit = new VariantType ("()");
  		public static VariantType Any = new VariantType ("*");
  		public static VariantType Basic = new VariantType ("?");
  		public static VariantType Maybe = new VariantType ("m*");
  		public static VariantType Array = new VariantType ("a*");
  		public static VariantType Tuple = new VariantType ("r");
  		public static VariantType DictEntry = new VariantType ("{?*}");
  		public static VariantType Dictionary = new VariantType ("a{?*}");
  		public static VariantType StringArray = new VariantType ("as");
  		public static VariantType ByteString = new VariantType ("ay");
  		public static VariantType ByteStringArray = new VariantType ("aay");
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern bool g_variant_type_string_is_valid (IntPtr type_string);
  
  		public static bool StringIsValid (string type_string)
  		{
  			IntPtr native = Marshaller.StringToPtrGStrdup (type_string);
  			bool ret = g_variant_type_string_is_valid (native);
  			Marshaller.Free (native);
  			return ret;
  		}
  
  		private VariantType () {}
  
  		IntPtr handle;
  		public IntPtr Handle {
  			get { return handle; }
  		}
  
  		// Docs say that GVariant is threadsafe.
  		~VariantType ()
  		{
  			Dispose (false);
  		}
  
  		public void Dispose ()
  		{
  			Dispose (true);
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern void g_variant_type_free (IntPtr handle);
  
  		void Dispose (bool disposing)
  		{
  			if (handle == IntPtr.Zero)
  				return;
  
  			g_variant_type_free (handle);
  			handle = IntPtr.Zero;
  			if (disposing)
  				GC.SuppressFinalize (this);
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern IntPtr g_variant_type_copy (IntPtr handle);
  
  		public VariantType (IntPtr handle)
  		{
  			this.handle = g_variant_type_copy (handle);
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern IntPtr g_variant_type_new (IntPtr type_name);
  
  		public VariantType (string type_string)
  		{
  			IntPtr native = Marshaller.StringToPtrGStrdup (type_string);
  			handle = g_variant_type_new (native);
  			Marshaller.Free (native);
  		}
  
  		public VariantType Copy ()
  		{
  			return new VariantType (Handle);
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern bool g_variant_type_equal (IntPtr a, IntPtr b);
  
  		public override bool Equals (object o)
  		{
  			return (o is VariantType) && g_variant_type_equal (Handle, (o as VariantType).Handle);
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern int g_variant_type_hash (IntPtr a);
  
  		public override int GetHashCode ()
  		{
  			return g_variant_type_hash (Handle);
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern IntPtr g_variant_type_peek_string (IntPtr a);
  
  		public override string ToString ()
  		{
  			return Marshaller.Utf8PtrToString (g_variant_type_peek_string (Handle));
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern bool g_variant_type_is_array (IntPtr type);
  
  		public bool IsArray {
  			get { return g_variant_type_is_array (Handle); }
  		}
  
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern bool g_variant_type_is_basic (IntPtr type);
  
  		public bool IsBasic {
  			get { return g_variant_type_is_basic (Handle); }
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern bool g_variant_type_is_container (IntPtr type);
  
  		public bool IsContainer {
  			get { return g_variant_type_is_container (Handle); }
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern bool g_variant_type_is_definite (IntPtr type);
  
  		public bool IsDefinite {
  			get { return g_variant_type_is_definite (Handle); }
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern bool g_variant_type_is_dict_entry (IntPtr type);
  
  		public bool IsDictionaryEntry {
  			get { return g_variant_type_is_dict_entry (Handle); }
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern bool g_variant_type_is_maybe (IntPtr type);
  
  		public bool IsMaybe {
  			get { return g_variant_type_is_maybe (Handle); }
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern bool g_variant_type_is_tuple (IntPtr type);
  
  		public bool IsTuple {
  			get { return g_variant_type_is_tuple (Handle); }
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern bool g_variant_type_is_variant (IntPtr type);
  
  		public bool IsVariant {
  			get { return g_variant_type_is_variant (Handle); }
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern bool g_variant_type_is_subtype_of (IntPtr type, IntPtr supertype);
  
  		public bool IsSubtypeOf (VariantType supertype)
  		{
  			return g_variant_type_is_subtype_of (Handle, supertype == null ? IntPtr.Zero : supertype.Handle);
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern IntPtr g_variant_type_element (IntPtr type);
  
  		public VariantType Element ()
  		{
  			return new VariantType (g_variant_type_element (Handle));
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern IntPtr g_variant_type_first (IntPtr type);
  
  		public VariantType First ()
  		{
  			return new VariantType (g_variant_type_first (Handle));
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern IntPtr g_variant_type_next (IntPtr type);
  
  		public VariantType Next ()
  		{
  			return new VariantType (g_variant_type_next (Handle));
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern IntPtr g_variant_type_n_items (IntPtr type);
  
  		public long NItems ()
  		{
  			return g_variant_type_n_items (Handle).ToInt64 ();
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern IntPtr g_variant_type_key (IntPtr type);
  
  		public VariantType Key ()
  		{
  			return new VariantType (g_variant_type_key (Handle));
  		}
  
  		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
  		static extern IntPtr g_variant_type_value (IntPtr type);
  
  		public VariantType Value ()
  		{
  
gt: 			return new VariantType (g_variant_type_value (Handle));