/**
 * 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.
 *
 * 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.
* @example	var element=$E({ tag:'div', className:'toolGroup', id:'toolGroup_1', children:{  tag:'div',  className:'roundBarTop',  children:[{  tag:'div', className:'leftEdge' },{ tag:'div', className:'rightEdge'},{ tag:'div', className:'heading', children:[{ tag:'a', className:'collapser' }, 'Group Heading' ] }] } });*/
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;
}

/**
 * encodeURL
 * This function returns the provided url string appended with a list of doubly encoded query string.
 * @param {String} url The url string the query sends to
 * @param {Array of String} queryArray The list of query to be encoded and attached to the url
 * @return {String} url Processed url ready to be sent
 */
 function encodeURL(url, queryArray) {
	if ('string'==typeof(queryArray) || 'number'==typeof(queryArray)) {
		url = url + '/' + encodeURIComponent(encodeURIComponent(queryArray));
	}
	else if ('object'==typeof(queryArray)) {
		queryArray.each(function(query) {
			url = url + '/' + encodeURIComponent(encodeURIComponent(query));
		});
	}
	return url;
 }
 
 /**
	* DefaultInput.setDefaultInput
	* @class This function watches on a specified text input element and set/unset its default value according to user's actions.
	* @param {String} value The default value for an input
	* @param{Object} input The input element defaultInput watches
	* @return set event handler for onFocus and onBlur events
	*/
var DefaultInput = {
	setFocus: function(event) {
		var input = Event.element(event);
		var curValue = input.value;
		var value = $A(arguments)[1];
		if (curValue==value)
			input.value = '';
	},
	
	setBlur: function(event) {
		var input = Event.element(event);
		var curValue = input.value;
		var value = $A(arguments)[1];
		if (curValue=='')
			input.value = value;
	},
	
	setDefaultInput: function(value, input) {
		var InputValue = new Object();
		InputValue.value = value;
		InputValue.input = input;
		InputValue.focusHandler = this.setFocus.bindAsEventListener(this, value);
		InputValue.blurHandler = this.setBlur.bindAsEventListener(this, value);
		
		$(input).value = value;
		Event.observe(input, 'focus', InputValue.focusHandler);
		Event.observe(input, 'blur', InputValue.blurHandler);
		return InputValue;
	},
	
	unsetDefaultInput: function(InputValue) {
		if (InputValue & InputValue.input) {
			InputValue.value = "";
			Event.stopObserving(InputValue.input, 'focus', InputValue.focusHandler);
			Event.stopObserving(InputValue.input, 'blur', InputValue.blurHandler);
		}
	}
 }
 
 /**
 * isDragging
 * This function returns yes only if one of the draggables is currently in dragging mode.
 * @param {Obj} draggables The list of all Draggables
 * @return {boolean} isDragging true only if one of the draggables is true
 */
 function isDragging(draggables) {
	var dragging = false;
	draggables.each(function(drag) {
		if (drag.dragging) {
			dragging = true;
		}
	});
	
	//alert("isDragging: "+dragging);
	return dragging;
 }