//Attaches an event handler to a DOM element
function addEvent(element, eventname, func, use_capture)
{
        if (element.addEventListener)
        {
                element.addEventListener(eventname, func, use_capture);
                return true;
        }
        else if (element.attachEvent)
        {
                var r=element.attachEvent('on'+eventname, func);
                return r;
        }
        else
        {
                element['on'+eventname]=func;
                return true;
        }

        return false;
}

function removeEvent(element, eventname, func, use_capture)
{
        if (element.removeEventListener)
        {
                element.removeEventListener(eventname, func, use_capture);
                return true;
        }
        else if (element.detachEvent)
        {
                var r=element.detachEvent('on'+eventname, func);
                return r;
        }
        else
        {
                element['on'+eventname]=null;
                return true;
        }

        return false;
}

function getEventSource(e)
{
	if (window.event && window.event.srcElement)
		return window.event.srcElement;
	else if (e && e.target)
		return e.target;
}

function findPosX(obj)
{
        var curleft = 0;
        if (obj.offsetParent)
        {
                while (obj.offsetParent)
                {
                        curleft += obj.offsetLeft
                        obj = obj.offsetParent;
                }
        }
        else if (obj.x)
                curleft += obj.x;
        return curleft;
}

function findPosY(obj)
{
        var curtop = 0;
        if (obj.offsetParent)
        {
                while (obj.offsetParent)
                {
                        curtop += obj.offsetTop;
			if (obj.scrollTop)
				curtop-=obj.scrollTop;
                        obj = obj.offsetParent;
                }
        }
        else if (obj.y)
                curtop += obj.y;
        return curtop;
}

function inClass(el, cls)
{
	if (el.nodeType != 1)
		return false;
        var elclass=el.getAttribute('class');
        if (!elclass)
                elclass=el.getAttribute('className');

        return (' '+elclass+' ').indexOf(' '+cls+' ') != -1;
}

function getParentIndex(el)
{
        var parent=el.parentNode;

        for (var i=0; i < parent.childNodes.length; i++)
        {
                if (el == parent.childNodes[i])
                        return i;
        }

        return -1;
}

function dump_dom(el)
{
	if (el.nodeType == 1)
	{
		dump("&lt;"+el.nodeName+"&gt;<div style=\"padding-left: 20px\">");
		for(var i=0; i<el.childNodes.length; i++)
		{
			dump_dom(el.childNodes[i]);
		}
		dump("</div>&lt;/"+el.nodeName+"&gt;");
	}
	if (el.nodeType == 3)
		dump(el.nodeValue);
}

function getChildElementsByTagName(el, tagname)
{
	var ces=new Array();

	for (var i=0; i < el.childNodes.length; i++)
	{
		c=el.childNodes[i];

		if (c.nodeType == 1 && c.nodeName.toLowerCase() == tagname.toLowerCase())
		{
			ces[ces.length]=c;
		}
	}

	return ces;
}

function ascendDOM(e, target)
{
	while (e.nodeName.toLowerCase() != target)
	{
		if (e == document.documentElement)
			return null;
		e=e.parentNode;
	}
	return e;
}

function map(arr, fn)
{
	var ret=new Array();
	for (var i=0; i < arr.length; i++)
	{
		ret[i]=fn(arr[i]);
	}

	return ret;
}

function XMLHTTPGET(url)
{
	if (window.XMLHttpRequest) { // Mozilla, Safari, ...
	    http_request = new XMLHttpRequest();
	} else if (window.ActiveXObject) { // IE
		var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
		xmlDoc.async="false";
		xmlDoc.validateOnParse="false";
		xmlDoc.load(url);
		if (xmlDoc.documentElement == null)
		{
			    var parseErrorText = "XML Parsing Error: " + xmlDoc.parseError.reason + 
				"\nLocation: " + xmlDoc.parseError.url + 
				"\nLine Number " + xmlDoc.parseError.line + ", Column " + 
				xmlDoc.parseError.linepos + 
				":\n" + xmlDoc.parseError.srcText +
				"\n";
			    for(var i = 0;  i < xmlDoc.parseError.linepos;i++){
				parseErrorText += "-";
			    };
			    parseErrorText +=  "^\n";

			alert(parseErrorText);
		}
		return xmlDoc;
//	    http_request = new ActiveXObject("Microsoft.XMLHTTP");
	}

	http_request.open('GET', url, false);
	if (http_request.overrideMimeType)
		http_request.overrideMimeType('text/xml');
	http_request.send(null);

	return http_request.responseXML;
}

function getElementById(doc, id)
{
	var docel=doc.documentElement;
	
	var nodes=[docel];

	while (nodes.length > 0)
	{
		var head=nodes.shift();

		if (head.getAttribute('id') == id)
			return head;
			
		if (head.childNodes.length > 0)
		{
			for (var i=0; i < head.childNodes.length; i++)
				if (head.childNodes[i].nodeType == 1)
					nodes.push(head.childNodes[i]);
		}
	}

	return null;
}

function myImportNode(doc, node)
{
	if (node.nodeType == 1)
	{
		var el=doc.createElement(node.nodeName);

		for (var i=0; i < node.attributes.length; i++)
		{
			var attval=node.attributes[i];
			if (attval.name == 'class')
			{
				if (attval.value)
				{
					//also set className for IE
					el.className=node.getAttribute('class');
				}
			}
			
			if (node.getAttribute(attval.name))
				el.setAttribute(attval.name, node.getAttribute(attval.name));
		}

		for (var i=0; i < node.childNodes.length; i++)
		{
			var n=node.childNodes[i];
			var imported=myImportNode(doc, n);
			if (imported)
				el.appendChild(imported);
		}

		return el;
	}
	else if (node.nodeType == 3)
	{
		return doc.createTextNode(node.nodeValue);
	}
	else return doc.createTextNode('');
	
	return null;
}
