/*
 * General DOM utility stuff
 */

/* see rss.js for some example usages */

installPrototypes();

function installPrototypes ()
{
	// Safari doesn't have the HTMLDocument class in its global namespace
	try {
		htmlDocument = HTMLDocument.prototype;
	}
	catch (e) {
		htmlDocument = document.__proto__;
	}

	// Safari doesn't have the Element class in its global namespace
	try {
		element = Element.prototype;
	}
	catch (e) {
		var e = document.createElement("foo");
		element = e.__proto__;
	}

	if (htmlDocument) {
		htmlDocument.getElementsByClassName = function (eName, cName)
		{
			return domGetElementsByClassName(this, eName, cName);
		}
	}

	if (element) {
		element.toggleHide = function()
		{
			return domToggleHide(this);
		}

		element.getContent = function()
		{
			return domGetContent(this);
		}

		element.setContent = function(newContent)
		{
			return domSetContent(this, newContent);
		}

		element.getPosition = function()
		{
			return domElementGetPosition(this);
		}

		element.setPosition = function(x, y, z)
		{
			return domElementSetPosition(this, x, y, z);
		}
	}

}


function domGetElementsByClassName (root, eName, cName) {
	var elements = root.getElementsByTagName(eName);
	var targets = new Array;
	var n;

	for (n = 0; n < elements.length; n++) {
		if (elements[n].getAttribute("class") == cName)
			targets.push(elements[n]);
	}

	if (targets.length == 0)
		return null;
	return targets;
}


function domToggleHide(element)
{
	if (element.hideTarget)
		element = element.hideTarget;

	if (element.style.display == "")
		element.style.display = "none";
	else
		element.style.display = "";
}


/* Get the HTML content of an element */
function domGetContent(element) {
	try {
		if (element[innerHTML])
			return element.innerHTML;
	}
	catch (e) {
	}
	if (!element.childNodes)
		return "";
	if (!element.childNodes[0])
		return "";
	return element.childNodes[0].nodeValue;
}


/* Set the HTML content of an element */
function domSetContent(element, value) {
	element.innerHTML = value;
	if (!element.childNodes)
		return;
	if (!element.childNodes[0])
		return;
	element.childNodes[0].nodeValue = value;
}


// e.g.
// s = elementsWithAttribute(getElementsByTagName("div"), "class", "someClass")
function elementsWithAttribute(fullSet, attrName, attrValue)
{
	var limitSet = new Array;
	var attr;
	var n;

	for (n = 0; n < fullSet.length; n++) {
		attr = fullSet[n].getAttribute(attrName);
		if (attr && attr == attrValue)
			limitSet.push(fullSet[n]);
	}

	return limitSet;
}



function domEventGetPosition(event)
{
	var xyz = new Array;

	if (event.srcElement) {
		/* MSIE */
		xyz['x'] = event.x;
		xyz['y'] = event.y;
	}
	else {
		/* W3C */
		xyz['x'] = event.pageX;
		xyz['y'] = event.pageY;
	}
	xyz['z'] = 0;
	return xyz;
}


function domElementGetPosition(node)
{
	var xyz = new Array;

	if (node.style && node.style.pixelLeft) {
		/* MSIE */
		xyz['x'] = node.style.pixelLeft;
		xyz['y'] = node.style.pixelTop;
	}
	else {
		/* W3C */
		xyz['x'] = node.offsetLeft;
		xyz['y'] = node.offsetTop;
	}
	xyz['z'] = node.zIndex;
	return xyz;
}


function domElementSetPosition(node, x, y, z)
{
	node.style.position = 'absolute';
	if (x >= 0)
		node.style.left = x;
	if (y >= 0)
		node.style.top  = y;
	if (z >= 0)
		node.zIndex = z;
}


function domHighlight(node, txt)
{
	if (node.nodeType != Node.TEXT_NODE &&
	    node.nodeType != Node.CDATA_SECTION_NODE)
		return;

	var off = node.data.indexOf(txt);
	if (off >= 0) {
		log(txt + " found at " + off);
		var r = document.createRange();
		r.setStart(node, off);
		r.setEnd(node, off + txt.length);
		var n = document.createElement("u");
		r.surroundContents(n);
	}
}

var charMap = {
	'gt': "@",
	'lt': "<",
	'~': "end"
};

function mapCharNumeric(match, s1) {
	return String.fromCharCode(s1);
}

function mapCharNamed(match, s2) {
	return charMap[s2];
}

function fixHTMLEntities(rootNode, prefix)
{
	var n;
	for (n = 0; n < rootNode.childNodes.length; n++) {
		var myprefix = prefix + " " + n;
		var node = rootNode.childNodes[n];
		debug(myprefix + ": " + node + " node.nodeType = " + node.nodeType);
		if (node.nodeType == Node.TEXT_NODE ||
		    node.nodeType == Node.CDATA_SECTION_NODE) {
//domHighlight(node, "Mac");

			var txt = node.data;
			txt = txt.replace(/&#(\d+);/g, mapCharNumeric);
			txt = txt.replace(/<[^>]*>/g, "");
			txt = txt.replace(/&(\s+);/g, mapCharNamed);
			//node.replaceData(0, node.data.length, txt);
			node.data = txt;

		}
		else {
			fixHTMLEntities(node, myprefix);
		}
	}
}
