/* 
	ADDITIONAL (CORE) PROTOTYPE FUNCTIONALITY
	@requires: prototype.js
*/

/*
document.createElement convenience wrapper

The data parameter is an object that must have the "tag" key, containing
a string with the tagname of the element to create.  It can optionally have
a "children" key which can be: a string, "data" object, or an array of "data"
objects to append to this element as children.  Any other key is taken as an
attribute to be applied to this tag.

Release homepage:
http://www.arantius.com/article/dollar+e

Available under an MIT license:
http://www.opensource.org/licenses/mit-license.php

@param {Object} data The data representing the element to create
@return {Element} The element created.
*/
function $E(data) {
	var el;
	if ('string'==typeof data) {
		el=document.createTextNode(data);
	} else {
		//create the element
		el=document.createElement(data.tag);
		delete(data.tag);

		//append the children
		if ('undefined'!=typeof data.children) {
			if ('string'==typeof data.children ||
				'undefined'==typeof data.children.length
			) {
				//strings and single elements
				el.appendChild($E(data.children));
			} else {
				//arrays of elements
				for (var i=0, child=null; 'undefined'!=typeof (child=data.children[i]); i++) {
					el.appendChild($E(child));
				}
			}
			delete(data.children);
		}

		//any other data is attributes
		for (attr in data) {
			el[attr]=data[attr];
		}
	}

	return el;
}

/*
Extends Prototype functionality of String Object
*/
Object.extend(String.prototype, {

	stripTags : function(include) {
		//if include is provided (string or array), then strip tags only strips out the defined tags in include
		//todo: think of good (working) regex that would allow excluding tags
		var extra;

		if (include) {
		    if (typeof include == 'object' && include.constructor == Array) {
		        extra = include.join('|');
		    } else if (typeof include == 'string') {
				extra = include;
			}
		}
		return this.replace(new RegExp('(<\\/?' + (extra ? '\\b(' + extra + ')\\b' : '') + '[^>]*>)', 'gi'), '');
	},

	trim: function(nbsp) {
		// if nbsp is set (true), then also removes non-breaking spaces (&nbsp;)
		return this.replace(new RegExp('^[\s'+(nbsp?'\xA0':'')+']+', 'g'),'').replace(new RegExp('[\s'+(nbsp?'\xA0':'')+']+$', 'g'),'');
	}

});

/*
Enchancement to HTML DOM, returns a parent of the child element. If a targetType is specified, then it will return the first instance of the
specified element type (eg DIV), otherwise, it simply returns the direct parent. targetTag may be a single string (eg 'DIV'), or an array of
potential elements (eg ['DIV', 'SPAN']), in this case, the first element found in the array is returned.
*/
function getParent(child, targetTag) {
	// locates a specific parent node for a given child node... if no targetTag is given, simply return the direct parent node
	// targetTag can be either a string, or an array, if an array, as soon as a match occurs, the node is returned
	if (child == null) { return null; }

	if (typeof targetTag == 'object' && targetTag.constructor == Array) { //array
		targetTag = targetTag.join('|');
	} else if (typeof targetTag == 'object' && !targetTag) { //null
		return child.parentNode;
	}

	if (child.nodeType == 1 && child.tagName.match(new RegExp('^('+targetTag+')$','i'))) { return child; }
	else { return getParent(child.parentNode, targetTag); }
}

