// Browser incompatibility workarounds
// From Eloquent JavaScript (http://eloquentjavascript.net)


if (typeof document.addEventListener == "function") {
    var registerEventHandler = function(node, event, handler) {
        node.addEventListener(event, handler, false);
    };
} else {
    var registerEventHandler = function(node, event, handler) {
        node.attachEvent("on" + event, handler);
    };
}



function unregisterEventHandler(node, event, handler) {
    if (typeof node.removeEventListener == "function") {
        node.removeEventListener(event, handler, false);
    } else {
        node.detachEvent("on" + event, handler);
    }
}



function normaliseEvent(event) {
    if (!event.stopPropagation) {
        event.stopPropagation = function() {this.cancelBubble = true;};
        event.preventDefault = function() {this.returnValue = false;};
    }
    if (!event.stop) {
        event.stop = function() {
            this.stopPropagation();
            this.preventDefault();
        };
    }

    if (event.srcElement && !event.target) {
        event.target = event.srcElement;
    }
    if ((event.toElement || event.fromElement) && !event.relatedTarget) {
        event.relatedTarget = event.toElement || event.fromElement;
    }
    if (event.clientX != undefined && event.pageX == undefined) {
        event.pageX = event.clientX + document.body.scrollLeft;
        event.pageY = event.clientY + document.body.scrollTop;
    }
    if (event.type == "keypress") {
        if (event.charCode === 0 || event.charCode == undefined) {
            event.character = String.fromCharCode(event.keyCode);
        } else {
            event.character = String.fromCharCode(event.charCode);
        }
    }
    return event;
}



function addHandler(node, type, handler) {
    function wrapHandler(event) {
        handler(normaliseEvent(event || window.event));
    }
    registerEventHandler(node, type, wrapHandler);
    return {node: node, type: type, handler: wrapHandler};
}



function removeHandler(object) {
    unregisterEventHandler(object.node, object.type, object.handler);
}



function getNodeText(node) {
    return node.innerText || node.textContent || node.text;
}

function setNodeText(node, text) {
    if (node.text != undefined) {
        node.text = text;
    } else if (node.textContent != undefined) {
        node.textContent = text;
    } else if (node.innerText != undefined) {
        node.innerText = text;
    } else {
        return false;
    }
    return true;
}

