context: // GtkSharp.Generation.Parameters.cs - The Parameters Generation Class.
  //
  // Author: Mike Kestner <mkestner@speakeasy.net>
  //
  // Copyright (c) 2001-2003 Mike Kestner
  // Copyright (c) 2004 Novell, Inc.
  //
  // This program is free software; you can redistribute it and/or
  // modify it under the terms of version 2 of the 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
  // General Public License for more details.
  //
  // You should have received a copy of the GNU 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.
  
  
  namespace GtkSharp.Generation {
  
  	using System;
  	using System.Collections;
  	using System.Xml;
  
  	public class Parameter {
  
  		private XmlElement elem;
  
  		public Parameter (XmlElement e)
  		{
  			elem = e;
  		}
  
  		string call_name;
  		public string CallName {
  			get {
  				if (call_name == null)
  					return Name;
  				else
  					return call_name;
  			}
  			set {
  				call_name = value;
  			}
  		}
  
  		public string CType {
  			get {
  				string type = elem.GetAttribute("type");
  				if (type == "void*")
  					type = "gpointer";
  				return type;
  			}
  		}
  
  		public string CSType {
  			get {
  				string cstype = SymbolTable.Table.GetCSType( elem.GetAttribute("type"));
  				if (cstype == "void")
  					cstype = "System.IntPtr";
  				if (IsArray) {
  					if (IsParams)
  						cstype = "params " + cstype;
  					cstype += "[]";
  					cstype = cstype.Replace ("ref ", "");
  				}
  				return cstype;
  			}
  		}
  
  		public IGeneratable Generatable {
  			get {
  				return SymbolTable.Table[CType];
  			}
  		}
  
  		public bool IsArray {
  			get {
  				return elem.GetAttributeAsBoolean ("array") || elem.GetAttributeAsBoolean ("null_term_array");
  			}
  		}
  
  		public bool IsEllipsis {
  			get {
  				return elem.GetAttributeAsBoolean ("ellipsis");
  			}
  		}
  
  		internal bool IsOptional {
  			get {
  				return elem.GetAttributeAsBoolean ("allow-none");
  			}
  		}
  
  		bool is_count;
  		bool is_count_set;
  		public bool IsCount {
  			get {
  				if (is_count_set)
  					return is_count;
  				
  				if (Name.StartsWith("n_"))
  					switch (CSType) {
  					case "int":
  					case "uint":
  					case "long":
  					case "ulong":
  					case "short":
  					case "ushort":
  						return true;
  					default:
  						return false;
  					}
  				else
  					return false;
  			}
  			set {
  				is_count_set = true;
  				is_count = value;
  			}
  		}
  
  		public bool IsDestroyNotify {
  			get {
  				return CType == "GDestroyNotify";
  			}
  		}
  
  		public bool IsLength {
  			get {
  				if (Name.EndsWith("len") || Name.EndsWith("length"))
  					switch (CSType) {
  					case "int":
  					case "uint":
  					case "long":
  					case "ulong":
  					case "short":
  					case "ushort":
  						return true;
  					default:
  						return false;
  					}
  				else
  					return false;
  			}
  		}
  
  		public bool IsParams {
  			get {
  				return elem.HasAttribute("params");
  			}
  		}
  
  		public bool IsString {
  			get {
  				return (CSType == "string");
  			}
  		}
  
  		public bool IsUserData {
  			get {
  				return CSType == "IntPtr" && (Name.EndsWith ("data") || Name.EndsWith ("data_or_owner"));
  			}
  		}
  
  		public virtual string MarshalType {
  			get {
  				string type = SymbolTable.Table.GetMarshalType( elem.GetAttribute("type"));
  				if (type == "void" || Generatable is IManualMarshaler)
  					type = "IntPtr";
  				if (IsArray) {
  					type += "[]";
  					type = type.Replace ("ref ", "");
  				}
  				return type;
  			}
  		}
  
  		public string Name {
  			get {
  				return SymbolTable.Table.MangleName (elem.GetAttribute("name"));
  			}
  		}
  
  		public bool IsOwnable {
  			get {
  				return this.Generatable is OwnableGen;
  			}
  		}
  
  		public bool Owned {
  			get {
  				return elem.GetAttribute ("owned") == "true";
  			}
  		}
  
  		public virtual string NativeSignature {
  			get {
  				string sig = MarshalType + " " + Name;
  				if (PassAs != String.Empty)
  					sig = PassAs + " " + sig;
  				return sig;
  			}
  		}
  
  		public string PropertyName {
  			get {
  				return elem.GetAttribute("property_name");
  			}
  		}
  
  		string pass_as;
  
  		public string PassAs {
  			get {
  				if (pass_as != null)
  					return pass_as;
  
  				if (elem.HasAttribute ("pass_as"))
  					return elem.GetAttribute ("pass_as");
  
  				if (IsArray || CSType.EndsWith ("IntPtr"))
  					return "";
  
  				if (CType.EndsWith ("*") && (Generatable is SimpleGen || Generatable is EnumGen))
  					return "out";
  
  				return "";
  			}
  			set {
  				pass_as = value;
  			}
  		}
  
  		string scope;
  		public string Scope {
  			get {
  				if (scope == null)
  					scope = elem.GetAttribute ("scope");
  				return scope;
  			}
  			set {
  				scope = value;
  			}
  		}
  
  		int closure = -1;
  		public int Closure {
  			get {
  				if(closure == -1 && elem.HasAttribute ("closure"))
  					closure = int.Parse(elem.GetAttribute ("closure"));
  				return closure;
  			}
  			set {
  				closure = value;
  			}
  		}
  
  		int destroynotify = -1;
  		public int DestroyNotify {
  			get {
  				if (destroynotify == -1 && elem.HasAttribute ("destroy"))
  					destroynotify = int.Parse (elem.GetAttribute ("destroy"));
  				return destroynotify;
  			}
  			set {
  				destroynotify = value;
  			}
  		}
  
  		public bool IsHidden {
  			get {
  				return elem.GetAttributeAsBoolean ("hidden");
  			}
  		}
  
  		public virtual string[] Prepare {
  			get {
  				IGeneratable gen = Generatable;
  				if (gen is IManualMarshaler) {
  					string result = "IntPtr native_" + CallName;
  					if (PassAs != "out")
  						result += " = " + (gen as IManualMarshaler).AllocNative (CallName);
  					return new string [] { result + ";" };
  				} else if (PassAs == "out" && CSType != MarshalType) {
  					return new string [] { gen.MarshalType + " native_" + CallName + ";" };
  				} else if (PassAs == "ref" && CSType != MarshalType) {
  					return new string [] { gen.MarshalType + " native_" + CallName + " = (" + gen.MarshalType + ") " + CallName + ";" };
  				} else if (gen is OpaqueGen && Owned) {
  					return new string [] { CallName + ".Owned = false;" };
  				}
  
  				return new string [0];
  			}
  		}
  
  		public virtual string CallString {
  			get {
  				string call_parm;
  
  				IGeneratable gen = Generatable;
  				if (gen is CallbackGen)
  					return SymbolTable.Table.CallByName (CType, CallName + "_wrapper");
  				else if (PassAs != String.Empty) {
  					call_parm = PassAs + " ";
  					if (CSType != MarshalType)
  						call_parm += "native_";
  
gt: 					call_parm += CallName;