/*global window */
/*global escape */
/*global unescape */
/*global ActiveXObject */
/*global DOMParser */
/*global XSLTProcessor */

// Prototype functions START ///////////////////////////////////////////////////

String.prototype.backSlashesToForward = function(){
    return this.replace(/\\/g, '/');
};

String.prototype.removeTrailingSlash = function(){
    return this.replace(/\/$/, '');
};

String.prototype.removePathEnd = function(){
    return this.substring(0, this.lastIndexOf('/') + 1);
};

String.prototype.contains = function(str){
    return (this.indexOf(str) !== -1);
};

String.prototype.startsWith = function(str){
    return (this.indexOf(str) === 0);
};

String.prototype.endsWith = function(str){
    return (this.substring(this.length - str.length) === str);
};

String.prototype.addTrailingSlash = function(){
    return this.replace(/([^\/])$/, '$1/');
};

// trim string  ----------------------------------------------------------------

String.prototype.trim = function(){
    return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
};

// Removes 'empty' textnodes that FF & opera inserts and then chokes on --------

String.prototype.removeEmptyNodes = function(){
    return this.replace(/\B\s\B|[\n\r\t]/g, '');
};

// -- Makes displayed text look nicer by fx replacing '_' with ' ', and restoring mangeled characters from urls.

String.prototype.cleanUpText = function(){
    return unescape(this.replace(/_/g, ' ').replace(/#/g, ' - ').replace(/http:\/\//g, ''));
};

// Prototype functions END /////////////////////////////////////////////////////

// Set constants ///////////////////////////////////////////////////////////////

// Checks CSS compatiblity -----------------------------------------------------

var rpToolbox_CSS1Compat = (window.document.compatMode === "CSS1Compat");

// Get true pathname to current page -------------------------------------------

var realPathName = location.pathname.backSlashesToForward().replace(/ /g, '%20');

// Get the individual parts from the pathname to current page ------------------

var pathParts = realPathName.removeTrailingSlash().split("/");

// Finders START ///////////////////////////////////////////////////////////////

// Finds first element by classname --------------------------------------------

function rpToolbox_getElementByClassName(className, parentNode, tagName){
    if(!parentNode) {
        parentNode = window.document;
    }
    if(!tagName) {
        tagName = "*";
    }
    var all = parentNode.getElementsByTagName(tagName);
    var element = null;
    for (var i = 0; i < all.length; i++) {
        if(all[i].className && (all[i].className.indexOf(className) !== -1)) {
            element = all[i];
            i = all.length;
        }
    }
    return element;
}

// Finds elements by classname -------------------------------------------------

function rpToolbox_getElementsByClassName(className, parentNode, tagName){
    if(!parentNode) {
        parentNode = window.document;
    }
    if(!tagName) {
        tagName = "*";
    }
    var all = parentNode.getElementsByTagName(tagName);
    var elements = [];
    for (var i = 0; i < all.length; i++) {
        if(all[i].className && (all[i].className.indexOf(className) !== -1)) {
            elements.push(all[i]);
        }
    }
    return elements;
}

// Find first link or a -tag with rel -------------------------------------------------
function rpToolbox_getLinkByRel(rel){
    var headNodes = document.getElementsByTagName('head')[0].getElementsByTagName('link');
    for (var h = 0; h < headNodes.length; h++) {
        if(headNodes[h].rel === rel) {
            return headNodes[h];
        }
    }
    var links = document.links;
    for (var i = 0; i < links.length; i++) {
        if(links[i].rel === rel) {
            return links[i];
        }
    }
    return null;
}

// Find first scriptnode with src ----------------------------------------------

function rpToolbox_getScriptNodeBySrc(src){
    var scriptNodes = window.document.getElementsByTagName('script');
    for (var sn = 0; sn < scriptNodes.length; sn++) {
        if(scriptNodes[sn].src === src) {
            return scriptNodes[sn];
        }
    }
    return null;
}

// Returns value for an elements style rule ------------------------------------

function rpToolbox_getStyle(element, property){
    var value = "";
    if(window.document.defaultView && window.document.defaultView.getComputedStyle) {
        value = window.document.defaultView.getComputedStyle(element, null).getPropertyValue(property);
    }
    else 
    if(element.currentStyle) {
        value = element.currentStyle[property];
    }
    return value;
}

// Finders END /////////////////////////////////////////////////////////////////

// Creators START //////////////////////////////////////////////////////////////

// Create an Element with id ---------------------------------------------------

function rpToolbox_createElementWithId(type, id){
    var node = window.document.createElement(type);
    node.id = id;
    return node;
}

// Create an Element with id and text content ----------------------------------

function rpToolbox_createElementWithIDAndText(type, id, text){
    var node = window.document.createElement(type);
    if(id) {
        node.id = id;
    }
    node.appendChild(window.document.createTextNode(text));
    return node;
}

// Create a Link ---------------------------------------------------------------

function rpToolbox_createLink(href, text, rel, onClick){
    var wrapper = window.document.createElement("span");
    var content = '<a href="' + href + '"';
    if(onClick) {
        content += '" onclick="' + onClick + '"';
    }
    if(rel) {
        content += '" rel="' + rel + '"';
    }
    content += '>';
    if(text) {
        content += text;
    }
    content += '</a>';
    wrapper.innerHTML = content;
    return wrapper.firstChild;
}

// Creators END ////////////////////////////////////////////////////////////////

// Changes an elements class on mouseover --------------------------------------

var rpToolbox_oldClass = null;

function rpToolbox_changeClassNameOnMouseover(element, newClass){
    element.onmouseover = function(){
        rpToolbox_oldClass = this.className;
        this.className = newClass;
    };
    element.onmouseout = function(){
        this.className = rpToolbox_oldClass;
    };
}

// Hides an element ------------------------------------------------------------
function rpToolbox_hideElement(element){
    if(element) {
        element.style.display = ('none');
    }
}

// Unhides an element ----------------------------------------------------------

function rpToolbox_showElement(element){
    if(element) {
        element.style.display = ('');
    }
}

// IE fix START ////////////////////////////////////////////////////////////////

// Check if browser is IE ------------------------------------------------------

var rpToolbox_browserIsIE = window.ActiveXObject;

// Check if browser is IE <7 ---------------------------------------------------

var rpToolbox_browserIsOldIE = rpToolbox_browserIsOldIE || (!window.XMLHttpRequest && window.ActiveXObject);

// Fixes XMLHttpRequest for IE -------------------------------------------------

if(!window.XMLHttpRequest) {
    window.XMLHttpRequest = function(){
        return new window.ActiveXObject(window.navigator.userAgent.indexOf("MSIE 5") !== -1 ? "Microsoft.XMLHTTP" : "MSXML2.XMLHTTP");
    };
}

// Makes position: fixed work in IE --------------------------------------------

function rpToolbox_fixIEPositionFixed_step2(element){
    var value;
    if(rpToolbox_getStyle(element, 'position') === 'fixed') {
        element.style.position = 'absolute';
        if(rpToolbox_getStyle(element, 'top').endsWith('px')) {
            value = rpToolbox_getStyle(element, 'top').replace('px', '');
            element.style.setExpression('top', '(rpToolbox_CSS1Compat ? window.document.documentElement.scrollTop : body.scrollTop) + ' + value);
        }
        else {
            if(rpToolbox_getStyle(element, 'bottom').endsWith('px')) {
                value = rpToolbox_getStyle(element, 'bottom').replace('px', '');
                element.style.setExpression('top', '(rpToolbox_CSS1Compat ? (window.document.documentElement.scrollTop + window.document.documentElement.clientHeight - offsetHeight) : body.scrollTop + body.clientHeight - offsetHeight) - ' + value + ' + "px"');
            }
        }
        if(rpToolbox_getStyle(element, 'left').endsWith('px')) {
            value = rpToolbox_getStyle(element, 'left').replace('px', '');
            element.style.setExpression('left', '(rpToolbox_CSS1Compat ? (window.document.documentElement.scrollLeft) : body.scrollLeft) + ' + value + ' + "px"');
        }
        else {
            if(rpToolbox_getStyle(element, 'right').endsWith('px')) {
                value = rpToolbox_getStyle(element, 'right').replace('px', '');
                element.style.setExpression('left', '(rpToolbox_CSS1Compat ? (window.document.documentElement.scrollLeft + window.document.documentElement.clientWidth - offsetWidth) : (body.scrollLeft + body.clientWidth - offsetWidth)) - ' + value + ' + "px"');
            }
        }
    }
}

function rpToolbox_fixIEPositionFixed(nodeClassOrId){
    if(rpToolbox_browserIsOldIE) {
        var elements;
        var i;
        window.document.body.parentNode.style.backgroundImage = 'url(".")';
        window.document.body.parentNode.style.backgroundAttachment = 'fixed';
        if(nodeClassOrId && document.getElementById(nodeClassOrId)) {
            rpToolbox_fixIEPositionFixed_step2(document.getElementById(nodeClassOrId));
        }
        else 
        if(nodeClassOrId && rpToolbox_getElementsByClassName(nodeClassOrId)) {
            elements = rpToolbox_getElementsByClassName(nodeClassOrId);
            for (i = 0; i < elements.length; i++) {
                rpToolbox_fixIEPositionFixed_step2(elements[i]);
            }
        }
        else {
            elements = window.document.getElementsByTagName("*");
            for (i = 0; i < elements.length; i++) {
                rpToolbox_fixIEPositionFixed_step2(elements[i]);
            }
        }
    }
}

// Hover anything workaround for pre 7 IE --------------------------------------

function rpToolbox_hoverAnything(parentNodeId, tagName){
    if(rpToolbox_browserIsOldIE) {
        var parentNode = window.document.getElementById(parentNodeId);
        var elements = parentNode.getElementsByTagName(tagName);
        for (var i = 0; i < elements.length; i++) {
            rpToolbox_changeClassNameOnMouseover(elements[i], 'hover');
        }
    }
}

// IE fix END //////////////////////////////////////////////////////////////////

// removes 'empty' textnodes that FF & opera inserts and then chokes on --------

function rpToolbox_removeEmptyNodes(parentNode){
    if(parentNode && !rpToolbox_browserIsOldIE) { // IMPORTANT changed from rpToolbox_browserIsIE to work with IE9
        parentNode.innerHTML = parentNode.innerHTML.removeEmptyNodes();
    }
    return parentNode;
}

// Sets alternating odd/even classnames for childnodes -------------------------

function rpToolbox_setOddEvenClasses(parentNodeId, className){
    if(!className) {
        className = 'rpfx_oddeven';
    }
    var nodes;
    if(!parentNodeId) {
        nodes = rpToolbox_getElementsByClassName(className);
    }
    else {
        nodes = rpToolbox_getElementsByClassName(className, document.getElementById(parentNodeId));
    }
    for (var i = 0; i < nodes.length; i++) {
        var childNodes = nodes[i].childNodes;
        for (var n = 0; n < childNodes.length; n++) {
            var childNode = childNodes[n];
            if(n % 2 !== 0) {
                childNode.className += ' rpfx_even';
            }
            else {
                childNode.className += ' rpfx_odd';
            }
        }
    }
}

// Get real window height ------------------------------------------------------

function rpToolbox_getWinHeight(){
    var height = 0;
    if(typeof(window.innerWidth) === 'number') {
        height = window.innerHeight;
    }
    else 
    if(document.documentElement && document.documentElement.clientHeight) {
        height = document.documentElement.clientHeight;
    }
    else
    if(document.body && document.body.clientHeight) {
        height = document.body.clientHeight;
    }
    return height;
}

// Navigation START ////////////////////////////////////////////////////////////

// Mark link to current page  --------------------------------------------------

function rpToolbox_markCurrentPageLink(containerID){
    var container = null;
    if(containerID) {
        container = document.getElementById(containerID);
    }
    else {
        container = document.body;
    }
    if(container) {
        var path = realPathName + location.search;
        container.innerHTML = container.innerHTML.replace(path + '"', path + '" id="selected" ');
    }
}

// Adds BreadCrumbNavigation bar based to a node -------------------------------

function rpToolbox_addBreadCrumbNavigation(breadCrumbNavigation){
    var positionNode = document.getElementById('breadcrumbnavigation');
    if(positionNode) {
        positionNode.parentNode.replaceChild(breadCrumbNavigation, positionNode);
    }
}

// Add list with local links ---------------------------------------------------

function rpToolbox_addLocalLinks(localLinks){
    var positionNode = document.getElementById('rp_locallinksposition');
    if(positionNode) {
        positionNode.parentNode.replaceChild(localLinks, positionNode);
    }
}

// Loads sitemap using xmlHttpRequest ------------------------------------------

function rpToolbox_getSitemapFromServer_xmlHttpRequest(url){
    var req = new XMLHttpRequest();
    req.open('GET', url, false);
    req.send(null);
    if(!req.getResponseHeader("Date")) {// Forces IE to reload if cache is stale
        var lastModified = req.getResponseHeader("Last-Modified");
        var newreq = new XMLHttpRequest();
        lastModified = lastModified ? lastModified : new Date(0);
        newreq.open("GET", url, false);
        newreq.setRequestHeader("If-Modified-Since", lastModified);
        newreq.send(null);
        if(newreq.status !== 304) {
            req = newreq;
        }
    }
    return req.responseText;
}

// Enhances external links -----------------------------------------------------

function rpToolbox_externalLink(link, openInNewWindow){
    if(link.href.indexOf(window.document.location.host) === -1) {
        if(openInNewWindow) {
            link.target = '_blank';
        }
        link.className += ' externallink';
        link.title += ' (External link)';
    }
}

// Adds functionality to links -------------------------------------------------

var rpToolbox_linksEnhanced = false;
function rpToolbox_enhanceLinks(container){
    var links;
    if(!container) {
        links = document.links;
    }
    else {
        links = container.getElementsByTagName("a");
    }
    for (var i = 0; i < links.length; i++) {
        rpToolbox_externalLink(links[i]);
    }
    rpToolbox_linksEnhanced = true;
}

// Appends list with anchor links ----------------------------------------------

function rpToolbox_appendAnchorLinks(anchorLinksList, contentContainer){
    var itemCount = 0;
    if(!anchorLinksList) {
        anchorLinksList = document.getElementById('anchorlinkslist');
    }
    if(anchorLinksList) {
        var elements = rpToolbox_removeEmptyNodes(contentContainer).getElementsByTagName("*");
        var nodeValue = '';
        var previousNodeValue = '';
        var listItem = document.createElement("li");
        for (var i = 1; i < elements.length; i++) {
            if(elements[i].tagName.toLowerCase().startsWith('h') && elements[i].id) {
                itemCount++;
                listItem = document.createElement("li");
                if(elements[i].firstChild.firstChild) { // if the text is in the H tag
                    nodeValue = elements[i].firstChild.firstChild.nodeValue;
                }
                else { // if the text is in the H tags child, fx a A
                    nodeValue = elements[i].firstChild.nodeValue;
                }
            }
            else 
            if(elements[i].tagName.toLowerCase() === 'div' && elements[i].id && elements[i].firstChild.tagName.toLowerCase().startsWith('h')) {
                itemCount++;
                listItem = document.createElement("li");
                nodeValue = elements[i].firstChild.firstChild.nodeValue;
            }
            if(nodeValue && previousNodeValue !== nodeValue) {// Weed out double hits.
                listItem.appendChild(rpToolbox_createLink('#' + elements[i].id, nodeValue, '', 'rpToolbox_scrolloffset()'));
                anchorLinksList.appendChild(listItem);
            }
            previousNodeValue = nodeValue;
        }
    }
    return itemCount;
}

// Add list with anchor links --------------------------------------------------

function rpToolbox_addAnchorLinks(contentContainerID, headline){
    var contentContainer;
    if(!contentContainerID) {
        contentContainer = document.getElementById('maincontent');
    }
    else {
        contentContainer = document.getElementById(contentContainerID);
    }
    if(contentContainer) {
        var anchorlinks = document.getElementById('anchorlinks');
        if(anchorlinks) {
            anchorlinks.parentNode.removeChild(anchorlinks);
        }
        var anchorLinksList = rpToolbox_createElementWithId('ul', 'anchorlinkslist');
        var itemCount = rpToolbox_appendAnchorLinks(anchorLinksList, contentContainer);
        if(!document.getElementById("presentationbar") && itemCount > 0) {
            anchorlinks = rpToolbox_createElementWithId('div', 'anchorlinks');
            if(!headline) {
                headline = 'On This Page';
            }
            anchorlinks.appendChild(rpToolbox_createElementWithIDAndText('h2', '', headline));
            anchorlinks.appendChild(anchorLinksList);
            var positionNode = document.getElementById('rp_anchorlinksposition');
            positionNode.parentNode.replaceChild(anchorlinks, positionNode);
        }
    }
}

// Turns off position: fixed if element doesnt fit window height ---------------

function rpToolbox_positionFixedOnlyIfFitsHeight_step2(offset, element){
    var windowInnerHeight = 0;
    if(self.innerHeight) {
        windowInnerHeight = self.innerHeight;
    }
    else if(document.documentElement && document.documentElement.clientHeight) {
        windowInnerHeight = document.documentElement.clientHeight;
    }
    else if(document.body) {
        windowInnerHeight = document.body.clientHeight;
    }
    if(rpToolbox_getStyle(element, 'position') === 'fixed' && (element.offsetHeight + offset) > windowInnerHeight) {
        element.style.position = 'absolute';
    }
}

function rpToolbox_positionFixedOnlyIfFitsHeight(theOffset, nodeClassOrId){
    var elements;
    var i;
    var offset = theOffset || 0;
    if(nodeClassOrId && document.getElementById(nodeClassOrId)) {
        rpToolbox_positionFixedOnlyIfFitsHeight_step2(offset, document.getElementById(nodeClassOrId));
    }
    else
    if(nodeClassOrId && rpToolbox_getElementsByClassName(nodeClassOrId)) {
        elements = rpToolbox_getElementsByClassName(nodeClassOrId);
        for (i = 0; i < elements.length; i++) {
            rpToolbox_positionFixedOnlyIfFitsHeight_step2(offset, elements[i]);
        }
    }
    else {
        elements = window.document.getElementsByTagName("*");
        for (i = 0; i < elements.length; i++) {
            rpToolbox_positionFixedOnlyIfFitsHeight_step2(offset, elements[i]);
        }
    }
}

// Navigation END //////////////////////////////////////////////////////////////

// AJAX START ///////////////////////////((((///////////////////////////////////

// Loads data using xmlHttpRequest  --------------------------------------------
function rpToolbox_loadDataFromProxy_xmlHttpRequest(url, callbackMethodName, id, proxyURL){
    if(url.startsWith(window.document.location.protocol + "//" + window.document.location.hostname)) {
        proxyURL = null;
    }
    var callback;
    if(id) {
        callback = callbackMethodName + "(req.responseText,'" + id + "')";
    }
    else {
        callback = callbackMethodName + "(req.responseText)";
    }
    if(proxyURL !== null) {
        url = proxyURL + "?url=" + url;
    }
    var req = new window.XMLHttpRequest();
    req.open('GET', url, true);
    req.onreadystatechange = function(){
        if(req.readyState === 4) {
            eval(callback);
        }
    };
    req.send(null);
}

// Deletes the content at the current url --------------------------------------

function rpToolbox_RESTdelete(url, callback){
    var req;
    var done;
    if(!url) {
        url = location.pathname;
    }
    if(!callback && !url) {
        done = function(){
            if(req.readyState === 4 && req.status === 200) {
                document.location = '..';
            }
        };
    }
    else 
    if(!callback && url) {
        done = function(){
            if(req.readyState === 4 && req.status === 200) {
                document.location.reload();
            }
        };
    }
    else {
        done = function(){
            if(req.readyState === 4 && req.status === 200) {
                callback();
            }
        };
    }
    req = new XMLHttpRequest();
    req.onreadystatechange = done;
    req.open('DELETE', url, true);
    req.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"); // Fixes IE cache problem
    req.send(null);
}

// Fixes some stuff to make text look nice when inserted into html -------------

function rpToolbox_text2HTML(text){
    text = text.replace(/\n/g, ' <br/> ');
    return text;
}

// Converts text to xml dom ----------------------------------------------------

function rpToolbox_text2XML(text){
    var doc;
    if(window.ActiveXObject) {
        doc = new ActiveXObject("Microsoft.XMLDOM");
        doc.async = "false";
        doc.loadXML(text);
    }
    else {
        doc = new DOMParser().parseFromString(text, "text/xml");
    }
    return doc;
}

// -- Transforms xml with xsl --------------------------------------------------

function rpToolbox_xslTransform(xmlText, xslText){
    var xml = rpToolbox_text2XML(xmlText);
    var xsl = rpToolbox_text2XML(xslText);
    var result;
    if(window.ActiveXObject) { // IE
        result = xml.transformNode(xsl);
    }
    else // Mozilla, Firefox, Opera, etc.
    if(document.implementation && document.implementation.createDocument) {
        var xsltProcessor = new XSLTProcessor();
        xsltProcessor.importStylesheet(xsl);
        var wrapper = document.createElement('div');
        wrapper.appendChild(xsltProcessor.transformToFragment(xml, document));
        result = wrapper.innerHTML;
    }
    return result;
}

// -- Displays loading messages -------------------------------------------------------------------------
function rpToolbox_displayLoadingMessages(){
    var loadMessageNodes = rpToolbox_getElementsByClassName('loading');
    for (var l = 0; l < loadMessageNodes.length; l++) {
        loadMessageNodes[l].style.display = ('block');
    }
}

// -- Hides loading messages -------------------------------------------------------------------------
function rpToolbox_hideLoadingMessages(){
    var loadMessageNodes = rpToolbox_getElementsByClassName('loading');
    for (var l = 0; l < loadMessageNodes.length; l++) {
        loadMessageNodes[l].style.display = ('');
    }
}

// AJAX END ////////////////////////////////////////////////////////////////////

// RESTful Path  START /////////////////////////////////////////////////////////

// Finds a childnode witch id, classname or tagname matches an identifier ------

function rpToolbox_findNodeRecursive(parentNode, identifier){// Recursive helper function
    if(parentNode.id === identifier || parentNode.className === identifier || parentNode.nodeName.toLowerCase() === identifier) {
        return parentNode;
    }
    var childNodes = parentNode.childNodes;
    var foundNode = null;
    for (var i = 0; i < childNodes.length; i++) {
        foundNode = rpToolbox_findNodeRecursive(childNodes[i], identifier);
        if(foundNode) {
            return foundNode;
        }
    }
}

// Finds a childnode witch id or classname or tagname matches an path Part -----

// Step 2
function rpToolbox_findNodeByPathPartRecursive(parentNode, pathPart){// Recursive helper function
    if(parentNode.id === pathPart || parentNode.className === pathPart || parentNode.nodeName.toLowerCase() === pathPart) {
        return parentNode;
    }
    var childNodes = parentNode.childNodes;
    var foundNode = null;
    for (var i = 0; i < childNodes.length; i++) {
        foundNode = rpToolbox_findNodeRecursive(childNodes[i], pathPart);
        if(foundNode) {
            return foundNode;
        }
    }
}

// Step 1
function rpToolbox_findNodeByPathPart(parentNode, pathPart, count){
    var node = null;
    if(parentNode) {
        if(count > 1) {
            var childNodes = parentNode.childNodes;
            for (var i = 0; i < childNodes.length; i++) {
                node = childNodes[i];
                if(node.className === pathPart || node.nodeName.toLowerCase() === pathPart) {
                    if(count === 1) {
                        return node;
                    }
                    count--;
                }
            }
        }
        node = rpToolbox_findNodeByPathPartRecursive(parentNode, pathPart);
    }
    return node;
}

// Finds a childnode by an (restful) path --------------------------------------

function rpToolbox_findNodeByPath(path, parentNode){
    if(!parentNode) {
        parentNode = document.body;
    }
    var pathParts = path.removeTrailingSlash().split("/");
    var foundNode = parentNode;
    for (var i = 0; i < pathParts.length; i++) {
        var pathPart = pathParts[i];
        var count = 1;
        if(pathPart.indexOf("[") !== -1) {
            count = parseInt(pathPart.substring(pathPart.lastIndexOf("[") + 1, pathPart.lastIndexOf("]")), 10);
            pathPart = pathPart.substring(0, pathPart.lastIndexOf("["));
        }
        foundNode = rpToolbox_findNodeByPathPart(foundNode, pathPart, count);
    }
    return foundNode;
}

// Finds a childnode by an path identifier -------------------------------------

function rpToolbox_findNode(parentNode, identifier, count){// Main funtion
    var node = null;
    if(parentNode) {
        if(count > 1) {
            var childNodes = parentNode.childNodes;
            for (var i = 0; i < childNodes.length; i++) {
                var childNode = childNodes[i];
                if(childNode.className === identifier || childNode.nodeName.toLowerCase() === identifier) {
                    if(count === 1) {
                        return childNode;
                    }
                    count--;
                }
            }
        }
        node = rpToolbox_findNodeRecursive(parentNode, identifier);
    }
    return node;
}

function rpToolbox_findNodeByIdentifier(parentNode, identifier){
    var identifierParts = identifier.split(".");
    var foundNode = parentNode;
    for (var i = 0; i < identifierParts.length; i++) {
        var identifierPart = identifierParts[i];
        var count = 1;
        if(identifierPart.indexOf("[") !== -1) {
            count = parseInt(identifierPart.substring(identifierPart.lastIndexOf("[") + 1, identifierPart.lastIndexOf("]")), 10);
            identifierPart = identifierPart.substring(0, identifierPart.lastIndexOf("["));
        }
        foundNode = rpToolbox_findNode(foundNode, identifierPart, count);
    }
    return foundNode;
}

// Replaces a node with new content --------------------------------------------

function rpToolbox_replaceCallback_OLD(newNode){
    if(window.rpToolbox_linksEnhanced) {
        rpToolbox_enhanceLinks(newNode);
    }
    var anchorLinks = window.document.getElementById("anchorlinks");
    if(anchorLinks) {
        rpToolbox_addAnchorLinks(anchorLinks.parentNode.id, "maincontent", 75);
    }
}

function rpToolbox_replace(content, identifier){
    var oldNode = window.document.getElementById(identifier);
    var tempNode = window.document.createElement("span");
    tempNode.innerHTML = content;
    tempNode = rpToolbox_removeEmptyNodes(tempNode);
    if(!identifier.startsWith('_all')) {
        tempNode = rpToolbox_findNodeByIdentifier(tempNode, identifier);
    }
    if(tempNode && tempNode.firstChild) {
        oldNode.parentNode.replaceChild(tempNode.firstChild, oldNode);
        if(window.rpToolbox_replaceCallback) {
            rpToolbox_replaceCallback(oldNode);
        }
    // rpToolbox_enhanceContent(); // <=========================================
    }
    else {
        oldNode.className = '';
        //oldNode.replaceChild(window.document.createTextNode('Content not found'), oldNode.firstChild); //TODO: improve this
    }
}

// Adds all inserts ------------------------------------------------------------

var rpToolbox_insertNodeID = 0;

function rpToolbox_addInserts(proxyURL){
    if(!proxyURL) {
        proxyURL = '';
    }
    var insertNodes = rpToolbox_getElementsByClassName("insert");
    var insertNode;
    for (var i = 0; i < insertNodes.length; i++) {
        insertNode = insertNodes[i];
        var wrapperNode = window.document.createElement('span');
        insertNode.parentNode.replaceChild(wrapperNode, insertNode);
        wrapperNode.className = 'insert';
        wrapperNode.appendChild(insertNode);
        insertNode.className = 'loading';
        if(!insertNode.id) {
            insertNode.setAttribute("id", "_all" + rpToolbox_insertNodeID++);
        }        
    }
    for (var n = 0; n < insertNodes.length; n++) {
        insertNode = insertNodes[n];
        rpToolbox_loadDataFromProxy_xmlHttpRequest(insertNode.href, 'rpToolbox_replace', insertNode.id, proxyURL);
    }
}

function rpToolbox_addInserts_OLD(proxyURL){
    var waitMessage = 'Importing content...';
    if(!proxyURL) {
        proxyURL = '';
    }
    var insertNodes = rpToolbox_getElementsByClassName("insert");
    var insertNode;
    for (var i = 0; i < insertNodes.length; i++) {
        insertNode = insertNodes[i];
        var wrapperNode = window.document.createElement('div');
        insertNode.parentNode.replaceChild(wrapperNode, insertNode);
        wrapperNode.className = 'insert';
        wrapperNode.appendChild(insertNode);
        if(insertNode.firstChild) {
            insertNode.firstChild.nodeValue = 'Importing ' + insertNode.firstChild.nodeValue;
        }
        else {
            insertNode.appendChild(window.document.createTextNode(waitMessage));
        }
        insertNode.className = 'loading';
        insertNode.title = 'Importing content from ' + insertNode.href + insertNode.title;
        if(!insertNode.id) {
            insertNode.setAttribute("id", "_all" + rpToolbox_insertNodeID++);
        }

    }
    for (var n = 0; n < insertNodes.length; n++) {
        insertNode = insertNodes[n];
        rpToolbox_loadDataFromProxy_xmlHttpRequest(insertNode.href, 'rpToolbox_replace', insertNode.id, proxyURL);
    //rpToolbox_loadDataFromProxy_scriptNode(insertNode.href, 'rpToolbox_replace', insertNode.id, proxyURL);
    }
}

// RESTful Path  END ///////////////////////////////////////////////////////////

// Form handling START /////////////////////////////////////////////////////////

// -- Validates fields -----------------------------------------------------------------121
function rpToolbox_validateField(input){
    //input.value = input.value.replace(/\s\s/g, ' ');
    var valid = true;
    var regexp;
    var enable;
    var allowempty = input.className.contains('allowempty');
    if(input.className.contains('email')) {
        input.value = input.value.replace(/\s/g, '');
        regexp = /^[^\.][\D|\d]*@[^\.]+\.[\D|\d]+[^\.]$/;
        valid = (input.value.search(regexp) !== -1);
    }
    else if(input.className.contains('number')) {
        input.value = input.value.replace(/^0+/g, '').replace(/\D/g, '');
    }
    var empty = !(input.value.replace(/\s/g, '').length > 0);
    rpToolbox_removeClassName(input, "inputerror");
    rpToolbox_removeClassName(input, "inputok");
    if((!allowempty && (empty || !valid))  || (allowempty && !empty && !valid)) {
        rpToolbox_addClassName(input, "inputerror");
        enable = false;
    }
    if((!allowempty && !empty && valid)  || (allowempty && !empty && valid)) {
        rpToolbox_addClassName(input, "inputok");
    }
    if((!allowempty && !empty && valid)  || (allowempty && (empty || valid))) {
        enable = true;
    }
    return enable;
}

// -- Validates a form -----------------------------------------------------------------

function rpToolbox_validateTheForm(form){
    var submitButton = rpToolbox_getElementsByClassName('submitbutton', form, 'input')[0];
    submitButton.disabled = false;
    var requredInputs = rpToolbox_getElementsByClassName('required', form, 'input');
    for (var r = 0; r < requredInputs.length; r++) {
        if(!rpToolbox_validateField(requredInputs[r])) {
            submitButton.disabled = true;
        }
    }
    requredInputs = rpToolbox_getElementsByClassName('required', form, 'select');
    for (r = 0; r < requredInputs.length; r++) {
        if(requredInputs[r].value === '0') {
            submitButton.disabled = true;
        }
    }
}

function rpToolbox_validateForm(e){
    if(!e) {
        e = window.event;
    }
    var target = e.target || e.srcElement;
    var form = target.form || target;
    rpToolbox_validateTheForm(form);
}

// -- Enhances forms ------------------------------------------------------------------

function onLoadDummy(){
}

function rpToolbox_enhanceForms(){
    var forms = document.forms;
    var requredInputs;
    var inputs;
    var submitButton;
    var formClassName;
    var submittedOKMessageSource;
    var submittedOKMessage = 'Meddelandet har skickats';
    var submittedFunction = eval(function(){
        alert(submittedOKMessage);
        window.location.href = window.location.href;
    });
    for (var i = 0; i < forms.length; i++) {
        inputs = forms[i].getElementsByTagName('input');
        for (var n = 0; n < inputs.length; n++) {
            if(inputs[n].type === 'submit') {
                inputs[n].className += ' submitbutton';
                submitButton = inputs[n];
            }
        }
        requredInputs = rpToolbox_getElementsByClassName('required', forms[i], 'input');
        if(requredInputs.length > 0) {
            submitButton.disabled = true;
            rpToolbox_validateTheForm(forms[i]);
            for (var r = 0; r < requredInputs.length; r++) {
                requredInputs[r].onkeyup = rpToolbox_validateForm;
                requredInputs[r].onchange = rpToolbox_validateForm;
                requredInputs[r].onmouseup = rpToolbox_validateForm;
                requredInputs[r].onmousemove = rpToolbox_validateForm;
                requredInputs[r].onmouseover = rpToolbox_validateForm;
                requredInputs[r].onpaste = rpToolbox_validateForm; // For IE
                requredInputs[r].oninput = rpToolbox_validateForm; // For Moz
            }
        }
        requredInputs = rpToolbox_getElementsByClassName('required', forms[i], 'select');
        if(requredInputs.length > 0) {
            submitButton.disabled = true;
            rpToolbox_validateTheForm(forms[i]);
            for (var sel = 0; sel < requredInputs.length; sel++) {
                requredInputs[sel].onchange = rpToolbox_validateForm;
            }
        }
        if(forms[i].className.contains('hiddentarget')) {
            forms[i].className += ' hiddentargetform' + i;
            formClassName = 'hiddentargetform' + i;
            submittedOKMessageSource = rpToolbox_getElementsByClassName('submittedtext', forms[i], 'input')[0];
            if(submittedOKMessageSource) {
                submittedOKMessage = submittedOKMessageSource.title;
            }
            submittedOKMessage = '<h1>' + document.getElementById('maincontent').getElementsByTagName('h1')[0].innerHTML +
            '</h1><p class="submittedmessage"><span>' + rpToolbox_getElementsByClassName('submittedtext', forms[i], 'input')[0].title + '</span></p>';
            //submittedFunction = function(){rpToolbox_getElementsByClassName(formClassName)[0].innerHTML = submittedOKMessage;};
            submittedFunction = function(){
                document.getElementById('maincontent').innerHTML = submittedOKMessage;
            };
            var target = document.createElement("div");
            document.body.appendChild(target);
            target.innerHTML = '<iframe name="target_iframe' + i + '" id="target_iframe' + i +
            '" onload="onLoadDummy();" style="height: 0px; border: 0;"></iframe>';
            forms[i].target = "target_iframe" + i;
            var className = " targetredirectform" + i;
            forms[i].className += className;
            forms[i].onsubmit = function(){
                onLoadDummy = submittedFunction;
            };
        }
    }
}

// Form handling END ///////////////////////////////////////////////////////////

// Scroll page -----------------------------------------------------------------

function rpToolbox_scrolloffset(scrolloffset, delay, bottomSpace){
    if(bottomSpace) {
        window.document.body.style.marginBottom = bottomSpace + 'px';
    }
    if(!delay) {
        delay = 1;
    }
    var header = document.getElementById('header');
    if(!scrolloffset || scrolloffset === 0) {
        if(header) {
            scrolloffset = rpToolbox_getStyle(header, 'height') || rpToolbox_getStyle(header, 'height');
        }
        else {
            scrolloffset = 0;
        }
    }
    scrolloffset = scrolloffset + '';
    scrolloffset = scrolloffset.replace(/px/, '');
    scrolloffset = scrolloffset.replace(/auto/, '');
    window.setTimeout("window.scrollBy(0, -5 - " + scrolloffset + ")", delay);
}

// Removes a classname ---------------------------------------------------------

function rpToolbox_removeClassName(node, className){
    var oldClasses = node.className;
    node.className = oldClasses.replace((' ' + className), '').replace(className, '');
}

// Adds a classname ------------------------------------------------------------

function rpToolbox_addClassName(node, className){
    rpToolbox_removeClassName(node, className);
    node.className += (" " + className);
}

// Converts raw time to localized format ---------------------------------------

function rpComments_time2local(time){
    var date = new Date();
    date.setTime(time);
    //return date.toLocaleString();
    return date.toLocaleDateString() + "  " + date.toLocaleTimeString();
}

// Convert content in nodes to local date  -------------------------------------

function rpToolbox_timeNodes2local(){
    var nodes = rpToolbox_getElementsByClassName('rp_time');
    for (var i = 0; i < nodes.length; i++) {
        if(nodes[i].firstChild && nodes[i].firstChild.nodeValue) {
            rpToolbox_removeClassName(nodes[i], 'rp_time');
            nodes[i].firstChild.nodeValue = rpComments_time2local(nodes[i].firstChild.nodeValue);
        }
    }
}

// getURLFromForm --------------------------------------------------------------

function rpToolbox_getURLFromForm(form){
    var url = form.elements[0].name + "=" + form.elements[0].value.trim();
    for (var i = 1; i < form.length - 1; i++) {
        if(form.elements[i].value) {
            url += "&" + form.elements[i].name + "=" + form.elements[i].value.trim();
        }
    }
    return url;
}

// escapeParamParts ------------------------------------------------------------

function rpToolbox_escapeParamParts(paramstring){
    paramstring = paramstring.replace("#", "").replace("?", "").replace(/\+/g, " ");
    var params = paramstring.split('&');
    var arg = params[0].split("=");
    var url = arg[0];
    if(arg[1]) {
        url += "=" + escape(unescape(arg[1])).trim();
    }
    for (var i = 1; i < params.length; i++) {
        arg = params[i].split("=");
        url += "&" + arg[0];
        if(arg[1]) {
            url += "=" + escape(unescape(arg[1])).trim();
        }
    }
    return url;
}

// get cookie ------------------------------------------------------------------

function rpToolbox_getCookie(name){
    var search = name + "=";
    var value = "";
    if(window.document.cookie.length > 0) {
        var offset = window.document.cookie.indexOf(search);
        if(offset !== -1) {
            offset += search.length;
            var end = window.document.cookie.indexOf(";", offset);
            if(end === -1) {
                end = window.document.cookie.length;
            }
            value = unescape(window.document.cookie.substring(offset, end));
        }
    }
    return value;
}

// Adds import css link to head ------------------------------------------------

function rpToolbox_addCSS(cssURL, parent){
    if(!parent) {
        parent = window.document.getElementsByTagName('head')[0];
    }
    var newStyleNode = window.document.createElement("link");
    newStyleNode.href = cssURL;
    newStyleNode.rel = "stylesheet";
    newStyleNode.type = "text/css";
    parent.appendChild(newStyleNode);
}

// Adds a function to window.onload event --------------------------------------

function rpToolbox_addOnLoad(newOnload){
    if(window.onload) {
        var oldOnload = window.onload;
        window.onload = function(){
            newOnload();
            oldOnload();
        };
    }
    else {
        window.onload = newOnload;
    }
}

// Toolbox handling START //////////////////////////////////////////////////////

// Adds javascript import node -------------------------------------------------
// Use in parent script to load this toolbox.
// Example: addJS("/js/toolbox.js");

function rpToolbox_addJS(src, doc){
    if(!doc) {
        doc = document;
    }
    var newJsNode = doc.createElement("script");
    newJsNode.src = src;
    newJsNode.type = "text/javascript";
    //newJsNode.type = "application/javascript";
    //newJsNode.charset = document.charset;
    var existingJsNode = rpToolbox_getScriptNodeBySrc(src);
    if(existingJsNode) {
        existingJsNode.parentNode.replaceChild(newJsNode, existingJsNode);
    }
    else {
        doc.getElementsByTagName('head')[0].appendChild(newJsNode);
    }
}

// Runs callback function named 'importedCodeCallBack', if it exists -----------
// Use in parent script to run stuff that needs this toolbox.
// Example: function importedCodeCallBack(){ stuff }

if(window.rpToolbox_toolboxLoadedCallBack) {
    window.rpToolbox_toolboxLoadedCallBack();
}

// Marks that toolbox is already available -------------------------------------
var rpToolbox_toolboxLoaded = true;

// Toolbox handling END ////////////////////////////////////////////////////////

