// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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 library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
//
// Author: John Leach
// Contact: john.leach@syger.it

// Create a namespace 'syger' to keep the Global Object clean
var syger = {

	/**
	 Introspects an object.
	
	 @param name the object name.
	 @param obj the object to introspect.
	 @param indent the indentation (optional, defaults to "").
	 @param levels the introspection nesting level (defaults to 1).
	 @returns a plain text analysis of the object.
	*/
	introspect : function (name, obj, indent, levels) {
		indent = indent || "";
		if (this.typeOf(levels) !== "number") levels = 1;
		var objType = this.typeOf(obj);
		var result = [indent, name, " ", objType, " :"].join('');
		if (objType === "object") {
		    if (levels > 0) {
			    indent = [indent, "  "].join('');
			    for (prop in obj) {
				    var prop = this.introspect(prop, obj[prop], indent, levels - 1);
				    result = [result, "\n", prop].join('');
			    }
			    return result;
		    }
		    else {
	            return [result, " ..."].join('');
	        }
		}
		else if (objType === "null") {
			return [result, " null"].join('');
		}
		return [result, " ", obj].join('');
	},
	
	/**
	 Checks the type of a given object.
	 
	 @param obj the object to check.
	 @returns one of; "boolean", "number", "string", "object",
	  "function", or "null".
	*/
	
	typeOf : function (obj) {
		type = typeof obj;
		return type === "object" && !obj ? "null" : type;
	},

	/**
	 Checks if a property of a specified object has the given type.
	 
	 @param obj the object to check.
	 @param name the property name.
	 @param type the property type (optional, default is "function").
	 @returns true if the property exists and has the specified type,
	  otherwise false.
	*/
	
	exists: function (obj, name, type) {
		type = type || "function";
		return (obj ? this.typeOf(obj[name]) : "null") === type;
	}
};
