/*************************************************************
* MD_JS JavaScript Functions Library
* Copyright (c) 2008, Matt Doyle. All rights reserved.
* Code licensed under the BSD License:
* http://www.mattdoyle.net/javascript/MDJS/license.txt
* See examples at: http://www.mattdoyle.net/javascript/MDJS/
* Version: 1.1
**************************************************************/

/**
 * Determines if the provided object is an array.  This implementation is actually
 * derived from the Yahoo UI function.  @link http://developer.yahoo.com/yui
 * @param obj Object	The object to test
 * @returns Object		The original object
 */
var is_array = function(obj) { 	return typeof(obj.length) == "number" && isFinite(obj.length) && typeof(obj.splice) == "function"; };

/**
 * Returns the element if either a string or the object is provided.  Only provided in case $() is not available,
 * and is used in the other functions in this library. 
 * @param mixed element		The object or string ID of the object
 * @returns Object			The object element refers to
 */
var getEl = function(element) { return (typeof(element) == "string") ? document.getElementById(element) : element; };

/**
 * Alias for document.getElementById.  This function is common in several other libraries (such as Prototype), and
 * is only provided in case such a library is not installed.
 * @param mixed el		The object or string ID of the object
 * @returns Object		The element Object with the provided ID
 */
if( !window.$ )
var $ = function(element) { return getEl(element); };

/**
 * Alias for document.createElement()
 * @param string type	The type of element to create
 * @returns Object		The newly created element
 */
var $CE = function(type) { return document.createElement(type); };

/**
 * Alias for element.setAttribute().  Multiple attributes can be set by providing
 * an array of attributes and values.
 * @param mixed _el		String ID or Object reference to the element to set the attributes for
 * @param mixed attr	If a string it is the name of the attribute to set.  If it is an array
 *						it must be constructed so that it has an even number of elements, where
 *						the odd indexes are the attributes to be set and the even indexes are
 *						the values.  (e.g. ["name","elementName","value","theValue"]).  If an
 *						array is provided the third parameter is not used.
 * @param string val	The value to set the single attribute.  This parameter is not used if
 *						the second parameter is an array.
 *
 * @returns Object		The passed in element Object
 */
var $SA = function(_el, attr, val) {
	var el = getEl(_el);
	if(is_array(attr))
	{
		for(var i=0; i<attr.length; i+=2)
		{
			el.setAttribute(attr[i], attr[i+1]);
		}
	}
	else { el.setAttribute(attr, val); }
	return el;
};

/**
 * Alias for element.appendChild().  If multiple children elements are passed in as an array,
 * then they are all appended to the parent in the order in which they are indexed inside the
 * array.
 * @param mixed _parent		String ID or Object reference to the parent element in which to
 *							append the children.
 * @param mixed _children	String ID or Object of the child to append. If it is an array then
 *							all its elements (either Object references or String IDs) will be
 *							added to the parent in the order they are indexed.
 *
 * @returns Object		The parent element Object
 */
var $AC = function(_parent, _children) {
		var parent = getEl(_parent);
		if(is_array(_children))
		{
			for(var i=0; i<_children.length; i++)
			{
				parent.appendChild(getEl(_children[i]));
			}
		}
		else { parent.appendChild(getEl(_children)); }
		return parent;
	};

/**
 * Alias for element.innerHTML.  
 * @param mixed _el		String ID or Object reference to the element whose innerHTML is to be set.
 * @param string val	The value of the innerHTML.
 *
 * @returns Object		The passed in element Object.
 */
var $IH = function(_el, val) { 
	var el = getEl(_el);
	el.innerHTML = val; return el;
};

/**
 * Removes a child element from its parent.  
 * @param mixed _el		String ID or Object reference to the element to remove.
 *
 * @returns Object		The parent element Object of the removed element.
 */
var $RE = function(_el) {
	var el = getEl(_el);
	var parent = el.parentNode;
	parent.removeChild(el);
	return parent;
};

/**
 * Combines createElement and setAttribute so that elements can be created and their attributes
 * set at the same time.  Multiple elements can be created through this function.
 * @param mixed type	String value of the type of element to create or an Array of strings of
 *						elements to create.
 * @param mixed attrs	Optional.  If provided it must be an Array of attribute/value pairs such
 *						that each odd index is the attribute and the even index is the value. If
 *						multiple types are passed then this must be an Array of Arrays where each
 *						set of attributes must be the same index as the element to which they
 *						should be attached.  If an attribute name is "innerhtml" then the innerHTML
 *						of the element will be set to the provided value.
 * @param bool atp		Optional.  Can only be set if an Array of types is provided.  If set to
 *						true it will add all elements created to the first element type that is
 *						provided (the one with index 0). 
 *
 * @returns mixed		If only one type is created it will return the element reference to this
 *						type.  If multiple types are created they are returned as an array. 
 */
var $CESA = function(type, attrs, atp) {
	if(is_array(type))
	{
		var elements = new Array();
		atp = (atp == null) ? true : atp;
		for(var i=0; i<type.length; i++)
		{
			var el = document.createElement(type[i]);
			for(var j=0; j<attrs[i].length; j+=2)
			{
				if(attrs[i][j] == "innerhtml")
				{
					el.innerHTML = attrs[i][j+1];
				}
				else
				{
					el.setAttribute(attrs[i][j], attrs[i][j+1]);
				}
			}
			if(atp)
				if(i > 0)
					elements[0].appendChild(el);
			elements[i] = el;
		}
		return elements;
	}
	else
	{
		var el = document.createElement(type);
		for(var i=0; i<attrs.length; i+=2)
		{
			if(attrs[i] == "innerhtml")
				el.innerHTML = attrs[i+1];
			else
				el.setAttribute(attrs[i], attrs[i+1]);
		}
		return el;
	}
};