/**
 * @library
 * SOE Platform - DOM utility class.
 * @class DOM
 * @requires
 * @author Scott Clarke, Sean White
 */
var DOM={

/** DOM.clearContent -
	Removes all child nodes from an HTML Element.
	@method
	@param {HTMLElement} el The Element whose contents you want to clear
	@return void
*/
clearContent : function(el) {
	// first clone the object, without it’s child elements.
	nEl = el.cloneNode(false);
	// Pop the new element in before the old one.
	el.parentNode.insertBefore(nEl,el);
	// Now get rid of the one that has all that icky content
	el.parentNode.removeChild(el);
},

/** DOM.DOMgetHTML -
	DOC HERE
	@method
	@param {HTMLElement} el
	@return String
	@details 
	TODO: We should remove all event handlers/listeners from contents before
	clearing them to provide an easy fix for IE Memory Leaks.
*/
DOMgetHTML : function(el) {
	// No problem if it’s a text node
    if (el.nodeType == 3) return el.nodeValue;
    var txt = new Array(),i=0;

	// If there is more to it, then let’s gather it all.
   	while(el.childNodes[i]) {
		txt[txt.length] = DOMgetHTML(el.childNodes[i]);
		i++;
	}
	// return the array as a string
	return txt.join("");
},


/** DOM.toggle -
	Flips the value of <var>el</var>.style.display between "none" and "".
	@method
	@param {HTMLElement} el
	@return void
*/
toggle: function(obj) {
	var el = document.getElementById(obj);
	if ( el.style.display != 'none' ) {
		el.style.display = 'none';
	}
	else {
		el.style.display = '';
	}
},

/** DOM.insertAfter -
	Inserts <var>node</var> inside <var>parent</var>, just after <var>referenceNode</var>.
	@method
	@param {HTMLElement} parent
	@param {HTMLElement} node
	@param {HTMLElement} referenceNode
	@return void
*/
insertAfter : function(parent, node, referenceNode) {
	parent.insertBefore(node, referenceNode.nextSibling);
},

/** DOM.getElementsByClass -
	Returns an Array of all HTMLElements having className=<var>searchClass</var>.
	@method
	@param {String} searchClass
	@param {HTMLElement} node If omitted, the entire document.body is searched.
	@param {String} tag If provided, only searches elements of the given <var>tag</var>.
	@Return Array
*/
getElementsByClass : function(searchClass,node,tag) {
	var classElements = new Array();
	if ( node == null )
		node = document;
	if ( tag == null )
		tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp('(^|\\s)'+searchClass+'(\\s|$)');
	for (i = 0, j = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
},

/** DOM.getElementsByClass -
	Returns the first ancestor of <var>ele</var> which has className=<var>parentClassName</var>.
	@method
	@param {HTMLElement} ele
	@param {String} parentClassName
	@Return HTMLElement
*/
getParentByClass : function(ele,parentClassName) {
	parNode=$(ele);
	while(parNode.className != parentClassName) {
		if(!parNode.parentNode) return;
		parNode=parNode.parentNode;
	}
	return parNode;
}, 

/** DOM.changeCss -
	Overrides current values of css class value for a specified element
	@method
	@param {String} theClass
	@param {HTMLElement} element
	@param {String} value
	@Return void
*/
changeCss: function(theClass,element,value) 
{
	 var cssRules;
	 //changes between cssrules(ie) and rules(ff)
	 if (document.all) {cssRules = 'rules';}
	 else if (document.getElementById) {cssRules = 'cssRules';}
	// alert(cssRules);
	  var cssr=document.styleSheets.length;
	 for (var S = 0; S < cssr; S++)
	 {		
	 	  var cssl=document.styleSheets[S][cssRules].length;
		  for (var R = 0; R < cssl; R++) 
		  {
		  		//alert(document.styleSheets[S][cssRules][R].selectorText);
			   if (document.styleSheets[S][cssRules][R].selectorText == theClass) 
			   {
			    document.styleSheets[S][cssRules][R].style[element] = value;
			   }
		  }
	 }	
}




}


/**
 * Automates Dragging of UI elements around a Web Page.
 * @courtesy ???
 * @return Object
 */
var Drag = {

	obj : null,

/** Drag.init -
	Enables an HTMLElement to be dragged using a mouse.  Courtesy of <a href="http://webapp.youngpup.net/?request=/articles/dom-drag-and-you.xml">youngpup.net</a>.
	@method
	@param {HTMLElement} o The Element you'd like to be draggable.
	@param {HTMLElement} oRoot (Optional) Ancestor of Element to be used as the draggable area.
	@param {Integer} minX
	@param {Integer} maxX
	@param {Integer} minY
	@param {Integer} maxY
	@param {Boolean} bSwapHorzRef
	@param {Boolean} bSwapVertRef
	@param {Boolean} fXMapper
	@param {Boolean} fYMapper
	@return void
	@details
	See <a href="http://webapp.youngpup.net/?request=/articles/dom-drag-and-you.xml">http://webapp.youngpup.net/?request=/articles/dom-drag-and-you.xml</a>
*/
	init : function(o, oRoot, minX, maxX, minY, maxY, bSwapHorzRef, bSwapVertRef, fXMapper, fYMapper)
	{
		o.onmousedown	= Drag.start;

		o.hmode			= bSwapHorzRef ? false : true ;
		o.vmode			= bSwapVertRef ? false : true ;

		o.root = oRoot && oRoot != null ? oRoot : o ;

		if (o.hmode  && isNaN(parseInt(o.root.style.left  ))) o.root.style.left   = "0px";
		if (o.vmode  && isNaN(parseInt(o.root.style.top   ))) o.root.style.top    = "0px";
		if (!o.hmode && isNaN(parseInt(o.root.style.right ))) o.root.style.right  = "0px";
		if (!o.vmode && isNaN(parseInt(o.root.style.bottom))) o.root.style.bottom = "0px";

		o.minX	= typeof minX != 'undefined' ? minX : null;
		o.minY	= typeof minY != 'undefined' ? minY : null;
		o.maxX	= typeof maxX != 'undefined' ? maxX : null;
		o.maxY	= typeof maxY != 'undefined' ? maxY : null;

		o.xMapper = fXMapper ? fXMapper : null;
		o.yMapper = fYMapper ? fYMapper : null;

		o.root.onDragStart	= new Function();
		o.root.onDragEnd	= new Function();
		o.root.onDrag		= new Function();
	},

	start : function(e)
	{
		
		var o = Drag.obj = this;
		e = Drag.fixE(e);
		var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
		var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
		o.root.onDragStart(x, y);

		o.lastMouseX	= e.clientX;
		o.lastMouseY	= e.clientY;

		if (o.hmode) {
			if (o.minX != null)	o.minMouseX	= e.clientX - x + o.minX;
			if (o.maxX != null)	o.maxMouseX	= o.minMouseX + o.maxX - o.minX;
		} else {
			if (o.minX != null) o.maxMouseX = -o.minX + e.clientX + x;
			if (o.maxX != null) o.minMouseX = -o.maxX + e.clientX + x;
		}

		if (o.vmode) {
			if (o.minY != null)	o.minMouseY	= e.clientY - y + o.minY;
			if (o.maxY != null)	o.maxMouseY	= o.minMouseY + o.maxY - o.minY;
		} else {
			if (o.minY != null) o.maxMouseY = -o.minY + e.clientY + y;
			if (o.maxY != null) o.minMouseY = -o.maxY + e.clientY + y;
		}

		document.onmousemove	= Drag.drag;
		document.onmouseup		= Drag.end;

		return false;
	},

	drag : function(e)
	{
		e = Drag.fixE(e);
		var o = Drag.obj;

		var ey	= e.clientY;
		var ex	= e.clientX;
		var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
		var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
		var nx, ny;

		if (o.minX != null) ex = o.hmode ? Math.max(ex, o.minMouseX) : Math.min(ex, o.maxMouseX);
		if (o.maxX != null) ex = o.hmode ? Math.min(ex, o.maxMouseX) : Math.max(ex, o.minMouseX);
		if (o.minY != null) ey = o.vmode ? Math.max(ey, o.minMouseY) : Math.min(ey, o.maxMouseY);
		if (o.maxY != null) ey = o.vmode ? Math.min(ey, o.maxMouseY) : Math.max(ey, o.minMouseY);

		nx = x + ((ex - o.lastMouseX) * (o.hmode ? 1 : -1));
		ny = y + ((ey - o.lastMouseY) * (o.vmode ? 1 : -1));

		if (o.xMapper)		nx = o.xMapper(y)
		else if (o.yMapper)	ny = o.yMapper(x)

		Drag.obj.root.style[o.hmode ? "left" : "right"] = nx + "px";
		Drag.obj.root.style[o.vmode ? "top" : "bottom"] = ny + "px";
		Drag.obj.lastMouseX	= ex;
		Drag.obj.lastMouseY	= ey;

		Drag.obj.root.onDrag(nx, ny);
		return false;
	},

	end : function()
	{
		document.onmousemove = null;
		document.onmouseup   = null;
		Drag.obj.root.onDragEnd(	parseInt(Drag.obj.root.style[Drag.obj.hmode ? "left" : "right"]), 
									parseInt(Drag.obj.root.style[Drag.obj.vmode ? "top" : "bottom"]));
		Drag.obj = null;
	},

	fixE : function(e)
	{
		if (typeof e == 'undefined') e = window.event;
		if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
		if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;
		return e;
	}
};