// Uncomment line below to squash JavaScript errors
//window.onerror = handleError;

function handleError() {
    //alert("JavaScript error");
    return true;
}

    // Global variables
    var globalParentId = null;
    var globalParentType = null;
    var globalPasteBuffer = null;
    var globalNextAction = null;
    var globalNamespace = null;            
    var isValid = true;


    /* AJAX FUNCTIONALITY BELOW */
    var request = null;
    var responseHandler = null;

    /*  Wrapper function for constructing a request object.
        Parameters:
            requestType: The HTTP request type such as GET or POST
            url: The URL of the server program
            asynch: Whether to send the request asynchronously or not
            callback: Name of the function that will handle the response
            Any fifth parameters represented as arguments[4], are the data a POST request is designed to send. */
        function httpRequest(requestType, url, asynch, callback) {
            if (window.XMLHttpRequest) {
                request = new XMLHttpRequest();
            }
            else if (window.ActiveXObject) {
                request = new ActiveXObject("Msxml2.XMLHTTP");
                if (!request) {
                    request = new ActiveXObject("Microsoft.XMLHTTP");
                }
            }
            if (request) {
                // if the requestType is POST then the 5th arg is the POSTed data
                if (requestType.toLowerCase() != "post") {
                    initRequest(requestType, url, asynch, callback);
                }
                else {
                    var args = arguments[4]; // the POSTed data
                    if (args != null && args.length > 0) {
                        initRequest(requestType, url, asynch, callback, args);
                    }
                }
            }
            else {
                alert("Sorry, your browser is not supported by this application");
            }
        }

        /* Initialize and send a request object that has already been created */
        function initRequest(requestType, url, asynch, callback) {
            try {
                // Set the responseHandler
                responseHandler = callback;
                request.onreadystatechange = wrapResponseHandler;
                request.open(requestType, url, asynch);
                if (requestType.toLowerCase() == "post") {
                    request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
                    request.send(arguments[4]);
                }
                else {
                    request.send(null);
                }
            }
            catch(errv) {
                alert("The application cannot contact " + url + " at the moment." +
                        "Please try again in a few seconds.\n" +
                        "Error detail: " + errv.message);
            }
        }

        function wrapResponseHandler() {
            if (request.readyState == 4) {
                if (request.status == 200) {
                    responseHandler();
                }
                else {
                    //alert("request.status = " + request.status);
                }
            }
            else {
                //alert("request.readyState = " + request.readyState);
            }
        }
    /* AJAX FUNCTIONALITY ABOVE */    


    /* VALIDATION FUNCTIONS BELOW */

        function validateMandatoryAcceptanceType(input, label) {
            if (!input.checked) {
                alert("You must agree to the \"" + label + "\".");
                input.focus();
            }
            return input.checked;
        }

        // Add a validation function to ensure field is filled in
        function validateMandatoryText(input, label) {
            if (input.value == "") {
                var action = "enter";
                if (input.type == "hidden") {
                    action = "click and upload";
                }
                var indefiniteArticle = "a";
                var labelStart = label.substr(0,1).toLowerCase();
                if (labelStart == "a" || labelStart == "e" || labelStart == "i" || labelStart == "o" || labelStart == "u") {
                    indefiniteArticle = "an";
                }
                var msg = "You must " + action + " " + indefiniteArticle + " \"" + label + "\".";
                alert(msg);
                input.focus();
                result = false;
            }
            else {
                result = true;
            }                                
            return result;
        }

        function validateMandatoryTextWithConfirmation(input, label) {
            var idPrefix = new String(input.id).substring(0, (input.id.length - "MandatoryText".length));
            var confirmation = document.getElementById(idPrefix + "Confirm");
            if (input.value == "") {
                alert("You must enter a \"" + label + "\".");
                input.focus();
                result = false;
            }
            else if (input.value != confirmation.value) {
                alert("The value you entered for \"" + label + "\" and the confirmation do not match.");
                input.focus();
                result = false;
            }
            else {
                result = true;
            }                                
            return result;
        }
    
        function validateIdWithConfirmation(input, label) {
            var idPrefix = new String(input.id).substring(0, (input.id.length - "MandatoryText".length));
            var confirmation = document.getElementById(idPrefix + "Confirm");
            if (input.value == "") {
                alert("You must enter a \"" + label + "\".");
                input.focus();
                result = false;
            }
            else if (input.value != confirmation.value) {
                alert("The value you entered for \"" + label + "\" and the confirmation do not match.");
                input.focus();
                result = false;
            }
            else {
                result = true;
            }                                
            return result;
        }
    

        var idField;
        var idLabel;
        function verifyUniqueId(input, label) {
            if (input.value != "") {
                // Need to call serverside function which returns true/false (to dangerous to return id data)
                var url = "cat.read?document=security.xml&stylesheet=../FRAMEWORK/cat/check-id.xsl&xpath=//user[@id='" + encodeURIComponent(input.value) + "']";
                var requestType = "GET";
                var asynch = true;
                //alert("About to call " + url);
                httpRequest(requestType, url, asynch, checkId);
                // Set up some of the variable used by the callback function
                idField = input;
                idLabel = label;
            }
        }
        function checkId() {
            var result = request.responseText;            
            //alert("You entered a " + idLabel + " \"" + idField.value + "\", found \"" + result + "\".");
            if (result == idField.value) {
                var message = "The " + idLabel + " \"" + idField.value + "\" already exists.\nPlease choose a different " + idLabel + ", or login if you have already registered.";
                alert(message);                
            }
        }
        
    /* VALIDATION FUNCTIONS ABOVE */

    // Array of validation listeners that are checked when the form is submitted
    var validators = new Array();
    validators["mandatoryAcceptanceType"] = validateMandatoryAcceptanceType;

    // This function gets called for each input field node. It looks to see if there is a validation function for the node
    // and if so, calls it passing the input field to be validated
    function validateNode(input) {
        var name = input.getAttribute("_nodename");
        var type = input.getAttribute("_type");
        var use = input.getAttribute("_use");
        var appinfo = input.getAttribute("_appinfo");
        //alert("validating " + type + ", " + use + ", " + appinfo);            
        if (isValid == true) {
            if (type != null && type != "") {
                if(validators[type]) {
                    isValid = validators[type](input, appinfo);
                }
            }
        }
        if (isValid == true) {
            if (use == "required") {
                isValid = validateMandatoryText(input, appinfo);            
            }
        }
        if (isValid == true) {
            if (name == "id") {
                isValid = validateIdWithConfirmation(input, appinfo);            
            }
        }
        if (isValid == true) {
            if (name == "password") {
                isValid = validateMandatoryTextWithConfirmation(input, appinfo);            
            }
        }
    }

    function resetGlobalVariables() {
        globalParentId = null;
    }

	// Toggles the className of elements
	function toggleClassName(element, class1, class2) {
	}

        // Toggles the visbility of the element's children
	// N.B. Only toggles elements with style="display: block"
	function toggleVisibilityOfChildren(elementId) {
	    toggleImage(elementId);
	    var targetNode = getElement(elementId);
	    var childNodes = targetNode.childNodes;
	    // If we have already loaded children for this node then show/hide them
	    if ( childNodes.length > 0 ) {
		var i = 0;
		for (i = 0; i < childNodes.length; i++) {
		    var element = childNodes[i];
		    var style = element.style;
		    if (style) {
			//alert("toggleVisibility(): Got style " + style);            
			if (style.display == "none") {
			    style.display = "block";
			}
			else if (style.display == "block") {
			    style.display = "none";
			}
		    }
		}
	    }
	}
	
	// Switches between open and closed icons
	function toggleImage(imageId) {
	    var src1 = "node-open.jpg";
	    var src2 = "node-closed.jpg";
	    var prefix = "images/";
	    var img = getElement("img" + imageId);
	    if (img.src.indexOf(src1) != -1){
		img.src = prefix + src2;
	    }
	    else {
		img.src = prefix + src1;
	    }
	}
    
    function save(namespace) {
        isValid = true; // Reset before we start
        globalNamespace = namespace;
        // Loop through the validators and check each one
        //alert("validators.length = " + validators.length);
        /*for (var i = 0; i < validators.length; i++) {
            isValid = validators[i]();
            if (isValid == false) {
                break;
            }
        }*/
        
        //alert("isValid = " + isValid);
        if (isValid == true) {
            send();
        }
    }

    // Like save() but no validation
    function send() {
        var form = document.forms[0];
        form.xml.value = getXML();
        //alert(form.xml.value);
        if (isValid) {
            form.submit();  
        }
    }
    function deleteItem(name, document, stylesheet, xpath) {
        var warning = "The item \"" + name + "\"  will be permanently deleted.\nContinue?";
        if (confirm(warning)) {
            var url = "cat.write?document=" + document + "&stylesheet=" + stylesheet + "&xpath=" + xpath + "&mode=delete";
            //alert(url);
            globalNextAction = reloadWindow;
            var hiddenframe = window.frames[0];
            hiddenframe.location.href = url;
        }
    }

    function reloadWindow() {
	    window.location.replace( unescape(window.location.href) );
    }
    
    function getXML() {
        // Get all the div tags in the visible form
        var inputElement = document.forms[1];
        var outputString = appendChildren(inputElement);
        //alert(outputString);
        return outputString;
    }

    function appendChildren(inputElement) {
       var outputString = "";
       
       //alert("Processing parent node " + inputElement.tagName + " id=" + inputElement.id + " _nodetype=" + (inputElement.getAttribute ? " _nodetype=" + inputElement.getAttribute("_nodetype") : ""));
       var elements = inputElement.childNodes;
        // Loop through elements and convert to output
        for (var i = 0; i < elements.length; i++) {
            var inputChild = elements[i];
            //alert("Processing child node " + inputChild.tagName + (inputChild.getAttribute ? " _nodetype=" + inputChild.getAttribute("_nodetype") : "") );
            //alert("Processing child node " + inputChild.tagName);
            if ( inputChild.getAttribute && inputChild.getAttribute("_nodetype") ) {
                var nodetype = inputChild.getAttribute("_nodetype");
                //alert("nodetype " + nodetype);
                if ( nodetype == "element" ) {
                    var tagname = inputChild.getAttribute("_nodename");
                    //alert("tagname " + tagname);
                    outputString += "<" + tagname;
                    outputString += appendNamespace(tagname);
                    outputString += appendAttributes(inputChild);
                    outputString += ">";

                    // If the element is an input with a value, then treat value as text node
                    if ( inputChild.value ) {
                        var text = inputChild.value;
                        //outputString += "<![CDATA[" + escapeTextNode(text) + "]]>";
                        outputString += escapeTextNode(text);
                        //validateNode(inputChild);                    
                    }
                    else {
                        outputString += appendChildren(inputChild);                    
                    }
                    outputString += "</" + tagname + ">";
                }
                else if ( nodetype == "text" ) {
                    var text = inputChild.value;
                    //alert("text = " + text);
                    //outputString += "<![CDATA[" + escapeTextNode(text) + "]]>";
                    outputString += escapeTextNode(text);
                    validateNode(inputChild);
                }     
            }
            else {
                outputString += appendChildren(inputChild);
            }
        }
        return outputString;
    }

    function appendNamespace(tagname) {
       var outputString = "";
       if (globalNamespace != null && globalNamespace != "") {
           var index = tagname.indexOf(":");
           if (index > -1) {
             var prefix = tagname.substr(0, index);
             outputString += " xmlns:" + prefix + "=\"" + globalNamespace + "\"";
           }
        }
       return outputString;
    }

    function appendAttributes(inputElement) {
       var outputString = "";
       
       //alert("Processing parent node " + inputElement.tagName + " _nodetype=" + inputElement.getAttribute("_nodetype"));
       var elements = inputElement.childNodes;
        // Loop through elements and convert to output
        for (var i = 0; i < elements.length; i++) {
            var inputChild = elements[i];
            //alert("Processing child node " + inputChild.tagName + (inputChild.getAttribute ? " _nodetype=" + inputChild.getAttribute("_nodetype") : "") );
            if ( inputChild.getAttribute && inputChild.getAttribute("_nodetype") ) {
                var nodetype = inputChild.getAttribute("_nodetype");
                if ( nodetype == "attribute" ) {
                    var attributeName = inputChild.getAttribute("_nodename");
                    var attributeValue = inputChild.value; // must be some kind of form control 
                    //attributeValue = escapeAttribute(attributeValue);
                    outputString += " " + attributeName + "=\"" + escapeAttributeValue(attributeValue) + "\"";
                    validateNode(inputChild);
                }                            
            }
            else {
                outputString += appendAttributes(inputChild);
            }
        }
        return outputString;
    }

    function escapeAttributeValue(attributeValue) {
        if (attributeValue != "") {
            var sanitizedText = removeNonUnicodeChars(attributeValue);
            var element = document.createElement("temp");
            var parent = document.createElement("temp");
            var attributeName = "attname";
            element.setAttribute(attributeName, sanitizedText);
            parent.appendChild(element);
            var html = new String(element.parentNode.innerHTML);
            var lHtml = html.toLowerCase();
            var startIndex = lHtml.indexOf(attributeName) + attributeName.length + 2;
            var endIndex = lHtml.indexOf("\"", startIndex);
            var escapedValue = html.substring(startIndex, endIndex);
            return escapedValue;
        }
        else {
            return attributeValue;
        }
    }

    function escapeTextNode(text) {
        if (text != "") {
            // TODO hack to get round bug in Java parsing string containing pound sign
            //var sanitizedText = replaceString(text, "\u00A3", "GBP ");
            // TODO hack end.
            var sanitizedText = removeNonUnicodeChars(text);
            var element = document.createElement("temp");
            var textNode = document.createTextNode(sanitizedText);
            element.appendChild(textNode);
            var escapedValue = element.innerHTML;
            return escapedValue;
        }
        else {
            return text;
        }
    }

    function removeNonUnicodeChars(text) {
        var sanitizedText = text.replace(new RegExp("[^{\\w\\d\\s!@#$%^&*()_\\-|+=\\{\\}\\[\\]\"':;\\/\\?\\\\,.}]","g"),"");            
        return sanitizedText;
    }
        
    function escapeAttribute(text) {        
        var result = escapeTextNode(text);
        return result;
    }

    function replaceString(text, oldString, newString) {        
        var result = new String(text);
        result = result.replace(new RegExp(oldString,"g"),newString);
        //alert("Replaced " + oldString + " with " + newString + ": returning \"" + result + "\"");
        return result;
    }

    function isDataNode(element) {
        if (element != null && element._nodetype) {
            //alert("isDataNode(element): element " + element.tagName + " has nodeype = " + element._nodetype);
            return true;
        }
        if (element != null && element.innerHTML != null && element.innerHTML.toString().indexOf("_nodetype", 0) > -1) {
            return true;
        }
        else {
            return false;
        }
    }

    function moveUp() {
        var element = document.getElementById(globalParentId);
        //alert("element = " + element.innerHTML);
        var parent = element.parentNode;
        var previousSibling = findPreviousSibling(element);
        if (previousSibling) {
            parent.removeChild(element);
            parent.insertBefore(element, previousSibling);
        }
    }
    
    // Find the previous sibling with an id attribute
    function findPreviousSibling(element) {
        //alert("findPreviousSibling(element): element.nodeName = " + element.nodeName);
        var sibling = element.previousSibling;
        if (sibling == null) {
            sibling = element;
        }
        else {
            if (!isDataNode(sibling)) {
                sibling = findPreviousSibling(sibling);
            }
        }
        //alert("sibling = " + sibling.innerHTML);
        return sibling;
    }
    // Find the first child with an id attribute
    function findFirstChild(parent) {
        var child = parent.firstChild;
        //alert("findFirstChild(): child = " + child);
        if (child != null && !child._nodetype) {
            sibling = findNextSibling(child);
        }
        return sibling;
    }

    // Moves to top above all siblings
    function moveToTop() {
        //alert("globalParentId = " + globalParentId);
        var element = document.getElementById(globalParentId);
        //alert("element = " + element);
        var parent = element.parentNode;
        //alert("parent = " + parent);
        //var firstChild = parent.firstChild;
        var firstChild = findFirstChild(parent);
        if (firstChild && firstChild != element) {
            parent.removeChild(element);
            parent.insertBefore(element, firstChild);
        }
    }
    function moveDown() {
        var element = document.getElementById(globalParentId);
        var parent = element.parentNode;
        var nextSibling = findNextSibling(element);
        if (nextSibling) {
            parent.removeChild(nextSibling);
            parent.insertBefore(nextSibling, element);
        }
    }
    // Find the next sibling with an id attribute
    function findNextSibling(element) {
        var sibling = element.nextSibling;
        if (sibling == null) {
            sibling = element;
        }
        else {
            if (!isDataNode(sibling)) {
                sibling = findNextSibling(sibling);
            }
        }
        return sibling;
    }
    // Moves to bottom below all siblings
    function moveToBottom() {
        var element = document.getElementById(globalParentId);
        var parent = element.parentNode;
        var lastChild = parent.lastChild;
        if (lastChild && lastChild != element) {
            parent.removeChild(element);
            parent.insertBefore(element, lastChild);
            parent.removeChild(lastChild);
            parent.insertBefore(lastChild, element);                    
        }
    }
    function deleteElement() {
        var warning = "This item will be deleted.\nContinue?\n\n(This change will not be permanent until you save).";
        if (confirm(warning)) {
            var element = document.getElementById(globalParentId);
            var parent = element.parentNode;
            parent.removeChild(element);                        
        }
    }  
    function cutElement() {
        var element = document.getElementById(globalParentId);
        var parent = element.parentNode;
        globalPasteBuffer = parent.removeChild(element);                        
    }  
    function copyElement() {
        var element = document.getElementById(globalParentId);
        globalPasteBuffer = replaceText(element.cloneNode(true), globalParentId, createId());
    }  
    function pasteElement() {
        var element = document.getElementById(globalParentId);
        if (element) {
            if (globalPasteBuffer) {
                element.appendChild( globalPasteBuffer );
            }
        }
    }  

    var globalMenuContainerId;
    function showMenu(parentId, parentType) {
        var containerId = "menu" + parentId;
        var container = document.getElementById(containerId);
        var menu = document.getElementById("menu");
        if (containerId != globalMenuContainerId) {            
            menu.style.display = "none";
        }
        container.appendChild(menu);        
        hideChildren("menu");        
        var submenu = document.getElementById(parentType + "-submenu");
        if (submenu) {
            submenu.style.display = "inline";
        }
        toggleVisibility("menu");   
        globalParentId = parentId;
        globalParentType = parentType;
        globalMenuContainerId = containerId;
    }

    function hideMenu() {
        var container = document.getElementById("menucontainer");
        var menu = document.getElementById("menu");
        container.appendChild(menu);        
    }


    // Toggles the visibility of the element
    function toggleVisibility(elementId) {
        var element = document.getElementById(elementId);
        var style = element.style;
        if (style.display == "none") {
            style.display = "inline";
        }
        else if (style.display == "inline") {
            style.display = "none";
        }
    }

    // Toggles the visbility of the element
    function hideChildren(elementId) {
        var element = document.getElementById(elementId);
        var children = element.childNodes;
        for (var i = 0; i < children.length; i++) {
            var child = children[i];
            if (child.style) {
                if (child.style.visibility == "visible") {
                    child.style.visibility = "hidden";
                }
                if (child.style.display == "inline") {
                    child.style.display = "none";
                }
                else if (child.style.display == "block") {
                    child.style.display = "none";
                }
            }
        }
    }

    function replaceText(element, oldText, newText){
        var parent = document.createElement("temp");
        parent.appendChild(element);
        var html = new String(element.parentNode.innerHTML);
        html = html.replace(new RegExp(oldText,"g"),newText);
        parent.innerHTML = html;        
        element = parent.firstChild;
        return element;
    }

    function createId() {
        return "N" + (new Date()).getTime();
    }

    function addElement(id) {
        //alert("addElement(" + id + ")");
        var item = document.getElementById(id).cloneNode(true);
        item = replaceText(item, id, createId());
        var parent = document.getElementById(globalParentId + "children");        
        parent.appendChild(item);
        hideMenu();
        return item.id
    }

    function modifyFileURLTypeAttribute(nodeId, maxDimension) {
        var message = "Please choose the file to upload.";
        uploadWindow=window.open("cat.upload?message=" + escape(message) + "&nodeId=" + nodeId + "&maxDimension=" + maxDimension,"FileUpload",
        'width=500,height=300,top=300,left=500,menubar=no,location=no,resizable=yes,status=no,toolbar=no');
        uploadWindow.focus();
    }

    function cancelUpload(nodeId) {
        var element = window.opener.document.getElementById(nodeId);
        if (element != null) {
            var parent = element.parentNode;
            parent.removeChild(element);                        
        }
        window.opener.focus();
        self.close();
        return false;
    }

    // Handle file upload in generic way like image
    function returnUploadedURL(nodeId, suffix, url){
        // Decide what kind of image to display for the URL
        var ext = suffix.toLowerCase();
        var dir = ext;
        var src = "../FRAMEWORK/cat/images/file.png";
        if (ext == "jpg"
            || ext == "jpeg"
            || ext == "png"
            || ext == "gif") {
            src = "uploads/optimized/" + suffix + "/" + url;
        }
        else if (ext == "doc") {
            src = "../FRAMEWORK/cat/images/doc.png";
        }
        else if (ext == "xls") {
            src = "../FRAMEWORK/cat/images/xls.png";
        }
        else if (ext == "ppt") {
            src = "../FRAMEWORK/cat/images/ppt.png";
        }
        else if (ext == "pdf") {
            src = "../FRAMEWORK/cat/images/pdf.png";
        }
        else if (ext == "zip") {
            src = "../FRAMEWORK/cat/images/zip.png";
        }
        var image = window.opener.document.getElementById("image" + nodeId);
        image.src = src;
        var urlElement = window.opener.document.getElementById("url" + nodeId);
        urlElement.value = dir + "/" + url;
        var viewlinkElement = window.opener.document.getElementById("viewlink" + nodeId);
        viewlinkElement.href = src;
        viewlinkElement.target = "_blank";
        var editlinkElement = window.opener.document.getElementById("editlink" + nodeId);
        editlinkElement.innerHTML = "Modify \"" + url + "\"";
        window.opener.focus();
        self.close();
        return false;
    }

    // Get a document element object
    function getElement( elementId )
    {
          var element = null;

          if(document.layers) {
            element = document.layers[ elementId ];
          }
          else if (document.all)
          {
            element = document.all[ elementId ];
          }
          else { 
            element = document.getElementById( elementId );
          }

          return element;
    }
    
    
    function setTimestamp(nodeId, time) {
	var day = new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday")
	var month = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
	var timestamp;
	if (time) {
		timestamp = new Date(time);
	}
	else {
		timestamp = new Date();
	}
	var dateString = day[timestamp.getDay()] + ", "
			+ timestamp.getDate() + " "
			+ month[timestamp.getMonth()] + " "
			+ timestamp.getFullYear();
	
	document.getElementById(nodeId).innerHTML = dateString;			
    }		

    function displayTimestamp(nodeId, timestamp) {
	var days = new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday")
	var months = new Array("January","February","March","April","May","June","July","August","September","October","November","December");

        var date = new Date();
	if (timestamp) {
            date = getDate(timestamp);
	}
	var dateString = days[date.getDay()] + ", "
			+ date.getDate() + " "
			+ months[date.getMonth()] + " "
			+ date.getFullYear();

	document.getElementById(nodeId).innerHTML = dateString;			
    }		

    function resetTimestamp(nodeId) {
        var timestamp = getTimestamp(new Date());
        displayTimestamp("text" + nodeId, timestamp);
        document.getElementById("time" + nodeId).value = timestamp;	    
    }                

    // Returns a JavaScript Date object given a String timestamp of the form YYYY-MM-DDThh:mm:ss.sssZ
    function getDate(timestamp) {
        var date = new Date();
        if (timestamp == null) {
            date = new Date();
        }
        else if (timestamp - timestamp == 0) {
            timestamp = timestamp -0;
            date = new Date(timestamp);
        }
        else if (new String(timestamp).indexOf("T") != -1) {
            // Timestamp should be in the RSS style format YYYY-MM-DDThh:mm:ss.sssZ
            var datetime = timestamp.split("T");
            var dateString = datetime[0].split("-");
            var year = dateString[0];
            var month = dateString[1];
            var day = dateString[2];
            var timeString = datetime[1].split(":");
            var hour = timeString[0];
            var minute = timeString[1];
            var remainder = timeString[2].split(".");
            var second = remainder[0];
  
            date = new Date();
            date.setMonth(month - 1);        
            date.setDate(day);
            date.setFullYear(year);
            date.setHours(hour);
            date.setMinutes(minute);
            date.setSeconds(second);
        }
        return date
    }

    // Returns a String timestamp of the form YYYY-MM-DDThh:mm:ss given a JavaScript Date object
    function getTimestamp(date) {
            // Timestamp should be in the RSS style format YYYY-MM-DDThh:mm:ss.sssZ                        
            var year = date.getFullYear();
            var month = zeropad(date.getMonth() + 1, 2, "left");   
            var day = zeropad(date.getDate(), 2, "left");
            var hour = zeropad(date.getHours(), 2, "left");
            var minute = zeropad(date.getMinutes(), 2, "left");
            var second = zeropad(date.getSeconds(), 2, "left");
            var milliseconds = zeropad(date.getMilliseconds(), 3, "left");
            var timestamp = year + "-" + month + "-" + day + "T" + hour + ":" + minute + ":" + second + "." + milliseconds + "Z";
            return timestamp;
    }

    function zeropad(text, length, direction) {
        text = new String(text);
        if (text.length < length) {
            if (direction == "right") {
                text = text + "0";
            }
            else {
                text = "0" + text;
            }
            if (text.length < length) {
                zeropad(text, length, direction);
            }
        }
        return text;
    }

    function handleKeyPress(textbox, e) {
        if ( isEnterKey(e) ) {
           doSearch(textbox);
           return false;
        }
        else {
           return true;
        }
    }
    function isEnterKey(e) {
      var keyPressed;

      if (e.which) {
        keyPressed = e.which;
      }
      else if (e.keyCode) {
        keyPressed = e.keyCode;
      }

      // key code "13" corresponds to the enter key
      if ( keyPressed == 13 ) {
        return true;
      }
      else {
        return false;
      }
    }
    function getSearchXPath(text) {
        text = text.toLowerCase();
        var nodes = new Array(
                        "@name",
                        "@*",
                        "text()"
                    );
        var xpath = createXPathClause(nodes, text);
        return xpath;                
    }

    function createXPathClause(nodes, text) {
        var xpath = "//*[";
        for(var i = 0; i < nodes.length; i++) {
            xpath += "contains(translate(" + nodes[i] + ",'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'),'" + text + "')";
            if(i < (nodes.length-1)) {
                xpath += "%20or%20";                    
            }
        }
        xpath += "]";                
        return xpath;
    }
    
    
    // The following functions perform image transitions

    //change the opacity for different browsers 
    function changeOpacity(opacity, id) { 
        var object = document.getElementById(id).style; 
        object.opacity = (opacity / 100); 
        object.MozOpacity = (opacity / 100); 
        object.KhtmlOpacity = (opacity / 100); 
        object.filter = "alpha(opacity=" + opacity + ")"; 
    }
    
    function blendImage(divid, imageid, imagefile, millisec) { 
        var speed = Math.round(millisec / 100); 
        var timer = 0; 

        //set the current image as background 
        document.getElementById(divid).style.backgroundImage = "url(" + document.getElementById(imageid).src + ")"; 

        //make image transparent 
        changeOpacity(0, imageid); 

        //make new image
        document.getElementById(imageid).src = imagefile; 

        //fade in image
        for(i = 0; i <= 100; i++) { 
            setTimeout("changeOpacity(" + i + ",'" + imageid + "')",(timer * speed)); 
            timer++; 
        } 
    }    
