// ok, not a very good test, but it will suffice for now.  Actually it doesn't really matter
// if we get it wrong, as we're not changing behaviour, only fixing a few visual oddities.
var has_problems_overlapping_selects = !!window.attachEvent && !window.opera;   
                                                                                
function domOnLoad(f)
{
    function binder() 
    {
        if (arguments.callee.done) return;
        arguments.callee.done = true;
        f();
    }

    /* for Mozilla/Opera9 */
    if (document.addEventListener) {
        document.addEventListener("DOMContentLoaded", binder, false);
    }

    // For IE 
    /*@cc_on @*/
    /*@if (@_win32)
        document.write("<script id='__ie_onload' defer='true' src='/blank.js'><\/script>");
        var script = document.getElementById("__ie_onload");
        script.onreadystatechange = function() {
            if (this.readyState == "complete") {
                binder(); // call the onload handler
            }
        };
    /*@end @*/

    // for Safari
    if (/WebKit/i.test(navigator.userAgent)) 
    {
        var _timer = setInterval(function() 
                {
                    if (/loaded|complete/.test(document.readyState)) 
                    {
                        clearInterval(_timer);
                        binder();
                    }
                }, 10);
    }

    // for other browsers
    if (window.attachEvent)
    {
        window.attachEvent("onload", binder);
    }
    else 
    {   // last try
        window.onload = binder;
    }
}


function hideOverlappingSelects(element)
{
    if (has_problems_overlapping_selects)
    {
        var elements_to_hide = document.getElementsByTagName('SELECT');
        for (var n = 0; n < elements_to_hide.length; ++n)  
        {
            elements_to_hide[n].style.visibility = 'hidden';
        }
    }
}

function hideOverlappingSelectsMouseOver()
{
    hideOverlappingSelects(this);
}

function showOverlappingSelects()
{
    if (has_problems_overlapping_selects && !disable_show_overlapping_selects)
    {
        var elements_to_hide = document.getElementsByTagName('SELECT');
        for (var n = 0; n < elements_to_hide.length; ++n)  
        {
            elements_to_hide[n].style.visibility = 'visible';
        }
    }
}


function install(descriptor)
{
    domOnLoad(function()
        {
            var parent = descriptor.parentElement ? document.getElementById(descriptor.parentElement) : document;
            var elems = getElementsByTagNames(parent, descriptor.tagName || 'div', descriptor.className);
            for(var elem in elems)
            {
                descriptor.init(elems[elem]);
            }        
        }
    );
}


function observeEvent(element, eventname, f)
{
    function bindEvent(event)    
    {   
        var e = event || window.event;
        if (!e.target) e.target = e.srcElement;
        if (e.target && e.target.nodeType == 3) // defeat Safari bug
            e.target = e.target.parentNode;        
        return f(e);    
    }
    if (element.addEventListener)
        return element.addEventListener(eventname, bindEvent, false);
    else if (element.attachEvent)
        return element.attachEvent("on" + eventname, bindEvent);
    else 
    {
        element["on" + eventname] = bindEvent;
        return bindEvent;
    }
}

function unobserveEvent(element, eventname, f)
{
    if (element.removeEventListener)
        element.removeEventListener(eventname, f, false);
    else if (element.removeEvent)
        element.detachEvent("on" + eventname, f);
    else 
        element["on" + eventname] = null;
}

function cancelBubble(e)
{
    if (!e) var e = window.event;
    e.cancelBubble = true;
    if (e.stopPropagation) e.stopPropagation();
}

function getElementsByTagNames(obj, list, className)
{
    if (!obj) var obj = document;
    var tagNames = typeof(list) == 'string' ? list.split(',') : list;
    var resultArray = [];
    var className = className && new RegExp('\\b' + className + '\\b');
    for (var tag in tagNames)
    {
        var tags = obj.getElementsByTagName(tagNames[tag]);
        for (var j=0; j<tags.length; j++)
        {
            if (!className || className.test(tags[j].className))
                resultArray.push(tags[j]);
        }
    }
    if (resultArray.length)
    {
        var testNode = resultArray[0];
        if (testNode.sourceIndex)
        {
            resultArray.sort(   function (a,b) 
                                {
                                    return a.sourceIndex - b.sourceIndex;
                                }
                            );
        }
        else if (testNode.compareDocumentPosition)
        {
            resultArray.sort(   function (a,b) 
                                {
                                    return 3 - (a.compareDocumentPosition(b) & 6);
                                }
                            );
        }
    }
    return resultArray;
}

function getChildrenByTagName(obj, tagName)
{
    var result = [];
    if (!obj.childNodes) return result;
    tagName = tagName.toLowerCase();
    for (var i = 0; i < obj.childNodes.length; ++i)
    {
        if (obj.childNodes[i].nodeName.toLowerCase() == tagName)
        {
            result.push(obj.childNodes[i]);
        }
    }
    return result;
}

function getElementsByTagNameI(parent, tagName)
{
    var elems = getElementsByTagNames(parent, tagName.toLowerCase());
    return elems.length > 0 ? elems : getElementsByTagNames(parent, tagName.toUpperCase());
}

// swap class 1 with class 2.
// class2 may be undefined
function toggleClassNames(element, class1, class2)
{
    if (element.className.indexOf(class1) != -1)
    {
        element.className = element.className.replace(class1, class2 || '');
    }
    else if (class2 != '')
    {
        element.className = element.className.replace(class2, class1);
    }               
    else
    {   // can't replace, because '' will match anything.
        element.className += (element.className == '' ? '' : ' ') + class1;
    }
}

// replace class1 with class2
function replaceClassName(element, class1, class2)
{
    element.className = element.className.replace(new RegExp('\\b' + class1 + '\\b'), class2);
}


function urlEncode(s)
{
    return s.replace(/ /g, "+");
}

function htmlSpecialChars(text)
{
    var htmlentities = {
            '&' : 'amp',        '>' : 'gt',        '<' : 'lt',        
            '£' : 'pound',    '\"' : 'quot',    '\'' : '#39'
    };
    for (var entity in htmlentities)
    {
        text = text.replace(new RegExp("/" + entity + "/"), "&" + htmlentities[entity] + ";");        
    }
    return text;
}

function purge(d) 
{
    var a = d.attributes, i, l, n;
    if (a) 
    {
        l = a.length;
        for (i = 0; i < l; i += 1) 
        {
            n = a[i].name;
            if (typeof d[n] === 'function') 
            {
                d[n] = null;
            }
        }
    }
    a = d.childNodes;
    if (a) 
    {
        l = a.length;
        for (i = 0; i < l; i += 1) 
        {
            purge(d.childNodes[i]);
        }
    }
}

/* functions for floating tooltips */
document.onmousemove = mouseMoved;

var visiblePopup = 0; //allows us to remember which tooltip is active

function mouseMoved()
{
	if(visiblePopup != 0)
	{
		document.getElementById(visiblePopup).style.left = get_mouse_x() + 'px';
		document.getElementById(visiblePopup).style.top = get_mouse_y() + 'px';
	}
}

function show_item( id )
{
	visiblePopup = id;
	mouseMoved();
	document.getElementById(id).style.display = "block";
}

function hide_item( id )
{
	visiblePopup = 0;
	document.getElementById(id).style.display = "none";
}

function get_mouse_x()
{
	return window.event.clientX - 200;
}

function get_mouse_y()
{
	return window.event.clientY - 100;
}
