// Prototype and MooTools do not play well together...
if ( !( window.MooTools == undefined ) )
{
    alert( 'Warning: MooTools has been loaded and may conflict with Prototype!' );
}


/**
 *  Prototype's current 'observe' function fails to deal with IE's lack of 'this' support in event handlers.
 *  See QuirksMode.org coding contest...
 */
Event._observeAndCache =  function(element, name, observer, useCapture) {
		if (!this.observers) this.observers = [];

		if (element.addEventListener) {
			this.observers.push([element, name, observer, useCapture]);
			element.addEventListener(name, observer, useCapture);
		} else if (element.attachEvent) {
			this.observers.push([element, name, observer, useCapture]);
			element["e"+name+observer] = observer;
			element[name+observer] = function() { element["e"+name+observer] (window.event); };
			element.attachEvent('on' + name, element[name+observer] );
		}
 };
 

function isEvent( obj ){
	return obj && 'undefined' != typeof Event && obj.eventPhase;
}

   	 
 /**
  *  Similarly, if the event object is not passed as a parameter, it should be retrieved from the
  *  window object.  
  */
 Event.element = function (eventObj) {
	var theTarget;
	
	if ( !eventObj ) var eventObj= window.event;
	
	if ( eventObj.target ) {
	   theTarget = eventObj.target;
	} else if ( eventObj.srcElement ) {
	   theTarget = eventObj.srcElement;
    }
	
	// defeat Safari bug
	if ( theTarget && theTarget.nodeType == 3 ) {
        theTarget = theTarget.parentNode;
    }
	
			
	return theTarget;    	 
 };




//http://blog.pothoven.net/2007/08/synthesizing-events-in-javascript.html
Event.trigger = function( targetElement, eventType )
{
    var event;
    targetElement = $(targetElement);
    
    if ( !targetElement ) return;
    
     // check for IE
     if ( window.ActiveXObject ) {
         event = document.createEventObject();
         targetElement.fireEvent("on"+eventType,event);
     } else {
         switch (eventType) {
             case "abort":
             case "blur":
             case "change":
             case "error":
             case "focus":
             case "load":
             case "reset":
             case "resize":
             case "scroll":
             case "select":
             case "submit":
             case "unload":
                 event = document.createEvent("HTMLEvents");
                 event.initEvent(eventType, "true", "true");
                 break;
             case "click":
             case "mousedown":
             case "mousemove":
             case "mouseout":
             case "mouseover":
             case "mouseup":
                 event = document.createEvent("MouseEvents");
                 event.initMouseEvent(eventType, true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
                 break;
         }
         targetElement.dispatchEvent(event);
     }
};




    	 
 /**
  *  The add() method is used for adding options to select lists.  However, browser 
  *  implementations are all over the map:
  *    - The W3C spec is selectNode.add(optionNode,optionNodeToInsertBefore)
  *    - Internet Explorer uses an index value as a second parameter (instead of an
  *      object)
  *    - Some browsers don't even support this option, so you may have to fall back
  *      on the appendChild() method.
  *  In any case, the method is redefined here so that all browsers will implement 
  *  the method according to the W3C specification.
  */
 Element.add = function(parentNode,nodeToAdd,nodeToInsertBefore) {
	/**
	 *  Ensure that parentNode is a 'select' element and nodeToAdd is an 'option'
	 *  element.
	 */
	if ((parentNode.nodeName.toLowerCase() == 'select') && (nodeToAdd.nodeName.toLowerCase() == 'option')) {
		// Try calling add() using the W3C spec...
		try {
			parentNode.add(nodeToAdd,nodeToInsertBefore);
		} catch (errorObj) {
		/**
		 *  Since it didn't work, we'll try the IE methodology next.  This requires
		 *  finding the index of nodeToInsertBefore, and passing that instead.
		 *  Further, since 'null' is a valid option for 'nodeToInsertBefore' we need
		 *  to test for that case.
		 */
			if (nodeToInsertBefore) {
				// get the position of nodeToInsertBefore within the parentNode's children.
				var index = parentNode.childNodes.indexOf(nodeToInsertBefore);
				if (index != -1) {
					parentNode.add(nodeToAdd,index);
				} else {
					throw(new Error('\'nodeToInsertBefore\' is not a child of \'parentNode\'!'));
					return false;
				}
			} else {
				// null was passed, so index is the number of options
				parentNode.add(nodeToAdd,parentNode.childNodes.length);
			}
		} // catch
		return true;
	} else {
		throw(new Error('\'parentNode\' must be a SELECT node and \'nodeToAdd\' must be an OPTION node!'));
		return false;
	}
 };




Element.deleteNodeAndChildren = function (node) {
	while(node.childNodes.length > 0) {
		Element.deleteNodeAndChildren(node.childNodes[0]);
	}
	node.parentNode.removeChild(node);
}



Element.setStyle = function(element, cssStyleText) {	
	// split the style text at ';'
	var lines = cssStyleText.split(';');
	
	// create a new associative array to hold the style's key/value pairs
	var styles = new Object();
	
	lines.each( function(cssExpression) {
		var key = (cssExpression.split(':')[0]);
		var value = (cssExpression.split(':')[1]);
		
		if (key && value) styles[key.trim()] = value.trim();
	});
	
	for (var name in styles) {
		element.style[name.camelize()] = styles[name];
	}
};




    	 
/**
 * http://www.arantius.com/article/dollar-e
 * http://www.thunderguy.com/semicolon/2005/05/23/setting-the-name-attribute-in-internet-explorer/
 * 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.
 */
$E = function (data) {
	var element;
	
	// Handle null parameter
	if ( !data ) return element;
	
	if ( typeof data == 'string' )
	{
		element = document.createTextNode( data );
	}
	
	else
	{
		if ( data.tag && ( typeof data.tag == 'string' ) )
		{
			//create the element
			// IE can't set the name of elements after they are created... 
			// So, try IE's way first (which will fail in most browsers) and then do it
			// the correct way...
            if ( data.tag && data.name ) {
				try { element = document.createElement('<'+data.tag+' name="'+data.name+'">'); } catch (e) { }
			}
			if ( !element ) {
				element = document.createElement( data.tag );
			}

		    // An OPTION node (for SELECT) should be able to take a 'text'
		    // attribute for the label, but IE seems to ignore this.
		    // Instead, the label needs to be added as a child text node.
		    // However, we also need to avoid setting the 'text' property
		    // as well, as this causes the label to appear twice!
            if ( ( data.tag == 'option' ) && data.text && ( typeof data.text == 'string' ) )
            {
                element.appendChild( document.createTextNode( data.text ) );
                delete( element.text );
            }

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


Object.extend(String.prototype, {
	reverse: function() {
		var revstr='';
		for (i = this.length-1; i>=0; i--) {
			revstr+=this.charAt(i);
		}
		return revstr;
	},
	
	trim: function(){
		if (this) {
			return this.replace(/^\s*(.*?)\s*$/,"$1");
		} else {
			return '';
		}
	}
	
});

