/**
 * Returns the absolute position of the DOM element by walking the tree
 * @param Object elem - DOM element
 * @return Object - Point (x,y)
 */
function GetElementPosition(elem) {
	var x = 0, y = 0;
	do {
		x += elem.offsetLeft + (elem.clientLeft || 0);
		y += elem.offsetTop + (elem.clientTop || 0);
	} while (elem = elem.offsetParent);
		
	return {x: x, y: y};
} // GetElementPosition()

/**
 * Returns whether an element is in the list of children of a parent
 * @param Object elem - the child DOM element in question
 * @param Object aParent - the parent DOM element
 * @return Boolean - true if elem is a child of parent (or the parent itself)
 */
function IsChild(elem,aParent) {
	if ((aParent == null) || (elem == null)) return false;
	
	do {
		if (elem == aParent) return true;
	} while (elem = elem.parentNode);
	
	return false;
} // IsChild()

/**
 * Returns whether any node in the hierarchy have the given class name
 * @param Object elem - the DOM element parent
 * @param String cName - the class name
 * @return Boolean - true if a parent has the given class name
 */
function ParentHasClassName(elem,cName) {
	if (elem == null) return false;
	
	do {
		if (elem.className == cName) return true;
	} while (elem = elem.parentNode);
	
	return false;
} // ParentHasClassName()

/**
 * Hides or shows the given element
 * @param String elemID - DOM element id
 * @param Boolean isShow - true => show, false => hide
 * @param Boolean isBlock - true => "block", false => "inline"
 * 
 */
function ShowHideWithStyle(elemID,isShow,isBlock) {
	var elem = document.getElementById(elemID);
	if (elem == null) return;
	
	var val = "none";
	if (isShow)
		val = (isBlock) ? "block" : "inline";
	elem.style.display = val;
} // ShowHideWithStyle()

function ShowHideElementInline(elemID,show) {ShowHideWithStyle(elemID,show,false);}
function ShowHideElement(elemID,show) {ShowHideWithStyle(elemID,show,true);}

/**
 * Toggles the display property for block elements based on their existing state
 * @param String elemID - DOM element ID
 */
function ToggleElement(elemID) {
	var elem = document.getElementById(elemID);
	if (elem == null) return;
	ShowHideWithStyle(elemID,(elem.style.display == "none"),true);
} // ToggleElement()

/**
 * Selects the text in the given field; does not check to see if the element is 
 * a valid text element
 * @param String textID - DOM element ID
 */
function SelectText(textID) {
	if (textID == "") return;
	var elem = document.getElementById(textID);
	if (elem == null) return;	
	elem.focus();
	elem.select();
} // SelectText()

/**
 * Returns the text content for the given element; different browsers handle this differently so
 * we have to use multiple checks to see if we can get something
 * 
 * @param Object elem - the DOM element to check
 * @return String - the content between the enclosing tags (includes HTML as well)
 */
function GetTextContent(elem) {
	elemText = "";
	
	if (typeof elem.textContent == 'string')
		elemText = elem.textContent;				// FF2, Saf3
	else if (typeof elem.innerHTML == 'string')
		elemText = elem.innerHTML;					// does anyone use this for xml trees?
	else if (typeof elem.xml == 'string')
		elemText = elem.xml.replace(/<[^>]+>/g,'');	// IE from xml docs
	else if (typeof elem.nodeValue == 'string')
		elemText = elem.nodeValue;
	else {
		if (elem.firstChild != null)				// Saf2 wants us to go down another level
			GetTextContent(elem.firstChild);
		else {
			// dump to server log for debugging
			/*
			var elemInfo = "Elem Info:\n";
			for(var propname in elem)
			    elemInfo += propname + ": " + elem[propname] + "\n"
			LogErrorToServer("Unable to find xml " + elemInfo,0,0);
			*/
		}
	}
	
	return (elemText);
} // GetTextContent()

function DOMGetElem(id) {return document.getElementById(id);}


/*
 * Adds a generic element to the page
 * 
 * @param string tag - HTML tag type
 * @param string cName - CSS class name
 * @param string text - inner HTML
 * @return Object - the DOM element
 */
function DOMAddElem(tag,cName,text) {
	var elem = document.createElement(tag);
	if (typeof(cName) != 'undefined' && cName != "")
		elem.className = cName;
	if (typeof(text) != 'undefined' && text != "")
		elem.innerHTML = text;
	return elem;
} // DOMAddElem()

function DOMAddDiv(cName,text) {return DOMAddElem("div",cName,text);}
function DOMAddSpan(cName,text) {return DOMAddElem("span",cName,text);}
function DOMAddCell(cName,text) {return DOMAddElem("td",cName,text);}
function DOMAddText(text) {return document.createTextNode(text);}
function DOMAddTextarea(id, name, cols, rows) {
	var elem = DOMAddElem("textarea");
	elem.id = id;
	elem.name = name;
	elem.cols = cols;
	elem.rows = rows;
	
	return elem;
}
function DOMAddBreak() {return document.createElement("br");}


/*
 * Adds a div element with an Id to the page
 * 
 * @param string tag - HTML tag type
 * @param string cName - CSS class name
 * @param string text - inner HTML
 * @return Object - the DOM element
 */
function DOMAddDivWithId(id,cName,text) {
	var elem = document.createElement("div");
	if (typeof(id) != 'undefined' && id !="")
		elem.id = id;
	if (typeof(cName) != 'undefined' && cName != "")
		elem.className = cName;
	if (typeof(text) != 'undefined' && text != "")
		elem.innerHTML = text;
	return elem;
} // DOMAddElem()

/*
 * Add a row of b tags to make the rounded top
 */
function DOMAddRoundedBoxTop() {
	var top = DOMAddElem("b","ytop");
	
	top.appendChild(DOMAddElem("b", "yb1"));
	top.appendChild(DOMAddElem("b", "yb2"));
	top.appendChild(DOMAddElem("b", "yb3"));
	top.appendChild(DOMAddElem("b", "yb4"));
	top.appendChild(DOMAddElem("b", "yb5"));
	
	return top;
}

/*
 * Add a row of b tags to make the rounded bottom
 */
function DOMAddRoundedBoxBottom() {
	var bottom = DOMAddElem("b","ybottom");
	
	bottom.appendChild(DOMAddElem("b", "yb5"));
	bottom.appendChild(DOMAddElem("b", "yb4"));
	bottom.appendChild(DOMAddElem("b", "yb3"));
	bottom.appendChild(DOMAddElem("b", "yb2"));
	bottom.appendChild(DOMAddElem("b", "yb1"));
	
	return bottom;
}

/*
 * Adds a table row of cells to the page
 * 
 * @param Array cells - a list of table cell elements to add
 * @return Object - the DOM element
 */
function DOMAddRow(cells) {
	var elem = document.createElement('tr');
	for (var i = 0;i < cells.length;i++)
		elem.appendChild(cells[i]);
	return elem;
} // DOMAddRow()

/**
 * Adds a Table & Tbody to the dom
 */
function DOMAddTable() {
	var elem = document.createElement('table');
	elem.cellSpacing = elem.cellPadding = elem.border = "0";
	elem.appendChild(document.createElement('tbody'));
	return elem;
} // DOMAddTable()

/*
 * Adds a link <a> to the page; if no link is given
 * it sets it to a void link
 * 
 * @param string cName - CSS class name
 * @param string href - html link
 * @param string text - inner HTML
 * @return Object - the DOM element
 */
function DOMAddLink(cName,href,text,title) {
	var elem = DOMAddElem("a",cName,text);
	elem.href = "javascript:void(0)";
	if (typeof(title) != 'undefined' && title != "") {
	    elem.setAttribute("title",title);
    }
	if (href != "") elem.href = href;
	return elem;
} // DOMAddLink()

/*
 * Adds an img to the page; always sets border to 0 as
 * it's very rare we would ever want an image with the 
 * browser-defined border style
 * 
 * @param string width - image width
 * @param string height - image Height
 * @param string src - image source
 * @return Object - the DOM element
 */
function DOMAddImg(width,height,src) {
	var elem = document.createElement('img');
	
	elem.src = src;
	elem.border = "0";
	if (width > 0) elem.width = width;
	if (height > 0) elem.height = height;
	return elem;
} // DOMAddImg()

/*
 * Adds an img to the page; always sets border to 0 as
 * it's very rare we would ever want an image with the 
 * browser-defined border style
 * 
 * @param string width - image width
 * @param string height - image Height
 * @param string src - image source
 * @return Object - the DOM element
 */
function DOMAddImg2(width,height,src,toolTip) {
	var elem = document.createElement('img');
	
	elem.src = src;
	elem.border = "0";
	if (width > 0) elem.width = width;
	if (height > 0) elem.height = height;

	if (toolTip != null) elem.title = toolTip;

	return elem;
} // DOMAddImg()




/*
 * Adds an linked-image to the page (e.g. icon)
 * 
 * @param string cName - link class Name
 * @param string href - html link
 * @param string width - image width
 * @param string height - image Height
 * @param string src - image source
 * @return Object - the DOM element
 */
function DOMAddImgLink(cName,href,width,height,src) {
	var elem = DOMAddLink(cName,href,"");
	var imgElem = DOMAddImg(width,height,src);
	elem.appendChild(imgElem);
	return elem;
} // DOMAddImgLink()

/*
 * Adds an linked-image to the page (e.g. icon)
 * 
 * @param string cName - link class Name
 * @param string href - html link
 * @param string width - image width
 * @param string height - image Height
 * @param string src - image source
 * @return Object - the DOM element
 */
function DOMAddImgLinkWithID(cName,href,width,height,src,id) {
	var elem = DOMAddLink(cName,href,"");
	elem.id = id;
	var imgElem = DOMAddImg(width,height,src);
	elem.appendChild(imgElem);
	return elem;
} // DOMAddImgLink()

/**
 * Adds an input element to the page
 * @param String iType - input element type (e.g. file, button, etc.)
 * @param String iName - name of the input element
 * @param String iVal - default value of the element
 * @return Object - DOM element
 */
function DOMAddInput(iType,iName,iVal) {
	var elem = DOMAddElem("input","","");
	elem.type = iType;
	elem.name = iName;
	elem.value = iVal;
	return elem;
} // DOMaddInput()

/**
 * Returns the document node for the iframe
 * courtesy of Apple: http://developer.apple.com/internet/webcontent/iframe.html
 * @param Object iFrame - DOM element
 */
function DOMGetIFrameDoc(iFrame) {
	if (iFrame.contentDocument) return iFrame.contentDocument; 			// NS6, FF
	if (iFrame.contentWindow) return iFrame.contentWindow.document;		// IE5.5/6
	if (iFrame.document) return iFrame.document;	
	return null;
} // DOMGetIFrameDoc()


/**
 * Adds an element to an iframe
 * @param Object elem - DOM element to add
 * @param Object iFrame - DOM element of parent iframe
 */
function DOMAddToIFrame(elem, iFrame) {
	var idoc = DOMGetIFrameDoc;
	if (idoc != null) 
		idoc.body.appendChild(elem);
} // DOMAddToIFrame()


/**
 * 
 */
function GetRefToDiv( divId, oDoc ) {
    if( !oDoc )  oDoc = document;

    if( document.layer ) {
        if( oDoc.layers[ divId ] )
            return oDoc.layers[ divId ];
        else
        {
            var ref;
            for( var x = 0; x < oDoc.layers.length; x++ )
            {
                ref = GetRefToDiv( divId, oDoc.layers[ x ].document );
                if( ref )
                    return ref;
            }
        }
    }

    if( document.getElementById )
        return document.getElementById( divId );
    if( document.all )
        return document.all[ divId ];

    return false;
} // GetRefToDiv

/**
 * 
 */
function WriteDivHTML( name, newHTML )
{
    var id = GetRefToDiv( name );
    if( !id )
        return false;
    else
    {
        if( typeof( id.innerHTML ) != 'undefined' )
        {
            id.innerHTML = newHTML;
            return true;
        }
        else if( id.document && id.document != window.document )
        {
            id.document.open();
            id.document.write( newHTML );
            id.document.close();
            return true;
        }
        else if( window.frames && window.frames.length && window.frames[ id ] )
        {
            var frameId = window.frames[ id ].window;
            frameId.document.open();
            frameId.document.write( newHTML );
            frameId.document.close();
            return true;
        }
    }

    return false;
}
/* 
 * 
 * Removes a node child element for the document. 
 * @param Object parentElem parent DOM element contain object to delete
 * @param Object oDel       child DOM element to delete 
 *
 */
function DOMRemoveElement(parentElem, childElem) {
 	var oParent = document.getElementById(parentElem), oChild;
 	if (oParent) {
 		oChild = document.getElementById(childElem);
 		if (oChild) {
 			oParent.removeChild(oChild);
 			return true;
 		}
 	}
 	return false;
}