/**
 * Forwards to the error page in case of an exception during an ajax call..
 *
 * @param ajCall
 * @param resParam
 */
function forwardToException(ajCall, resParam){
    if (ajCall.xhr.responseText.indexOf("relogin") > 0){
        window.location.href = "relogin.jsp";
    } else {
        document.getElementById("contentContainer").style.display = "none";
        document.getElementById("errorContainer").innerHTML = ajCall.xhr.responseText;
        document.getElementById("errorContainer").style.display = "block";
    }

    //break handler chain
    return true;
}

/**
 * Displays the loading indicator after the given field.
 *
 * @param field the field after which the indicator should be displayed
 */
function addLoadingIndicator(field){
    var loadingIndicatorImage = new Image();
    loadingIndicatorImage.src = "images/indicator.gif";
    loadingIndicatorImage.id = "indicator." + field.id;

    var parentField = field.parentNode;
    parentField.appendChild(loadingIndicatorImage);
}

/**
 * Removes the loading indicator after the given field.
 *
 * @param field the field after which the indicator should be removed
 */
function removeLoadingIndicator(field){
    var loadingIndicatorImage = document.getElementById("indicator." + field.id);

    field.parentNode.removeChild(loadingIndicatorImage);
}

var workingCounter = 0;
var unchangedItems = new Array();

/**
 * This javascript function is called prior to every ajax request to disable the form fields until the
 * ajax request is completed in order to prevent inconsistencies.
 *
 * @param form the form who's fields need to be disabled
 */
function disableFormFields(form){
    workingCounter ++;
    if (workingCounter == 1){
        for (var i = 0; i < form.elements.length; i++){
            var currentElement = form.elements[i];
            if (currentElement.disabled){
                unchangedItems[unchangedItems.length] = currentElement.name;
            } else {
                currentElement.disabled = true;
            }
        }
    }
}

/**
 * This javascript function is called prior to every ajax request to disable the specified form fields until the
 * ajax request is completed in order to prevent inconsistencies.
 *
 * @param fields the form fields list
 */
function disableSpecifiedFormFields(fields){
    workingCounter ++;
    if (workingCounter == 1){
        for (var i = 0; i < fields.length; i++){
            var currentElement = fields[i];
            if (currentElement.disabled){
                unchangedItems[unchangedItems.length] = currentElement.name;
            } else {
                currentElement.disabled = true;
            }
        }
    }
}

/**
 * This javascript function is called after to every ajax request to enable the form fields
 * disabled prior to the ajax request.
 *
 * @param form the form who's fields need to be disabled
 */
function enableFormFields(form){
    workingCounter --;
    if (workingCounter == 0){
        var fieldNamesList = unchangedItems.join('|') + '|';
        unchangedItems = new Array();
         for (var i = 0; i < form.elements.length; i++){
            var currentElement = form.elements[i];
            if (currentElement.name == '' || fieldNamesList.indexOf(currentElement.name + '|') == -1){
                currentElement.disabled = false;
            }
        }
    }
}

/**
 * This javascript function is called after to every ajax request to enable the specified form fields
 * disabled prior to the ajax request.
 *
 * @param fields the form fields list
 */
function enableSpecifiedFormFields(fields){
    workingCounter --;
    if (workingCounter == 0){
        var fieldNamesList = unchangedItems.join('|') + '|';
        unchangedItems = new Array();
         for (var i = 0; i < fields.length; i++){
            var currentElement = fields[i];
            if (currentElement.name == '' || fieldNamesList.indexOf(currentElement.name + '|') == -1){
                currentElement.disabled = false;
            }
        }
    }
}

var loadingIndicatorCounter = 0;

/**
 * Displays the page loading indicator.
 */
function showLoadingIndicator(){
    loadingIndicatorCounter ++;
    if (loadingIndicatorCounter == 1){
        document.getElementById('loadingIndicatorImage').style.visibility = 'visible';
    }
}

/**
 * Hiddes the page loading indicator.
 */
function hiddeLoadingIndicator(){
    loadingIndicatorCounter --;
    if (loadingIndicatorCounter == 0){
        document.getElementById('loadingIndicatorImage').style.visibility = 'hidden';
    }
}

/**
 * Multiple lists update handler updates multiple combos with the same values and sets
 * for each the selected value according to the specific element value. 
 *
 * @param ajCall
 * @param resParam
 */
function multipleListsUpdate(ajCall, resParam){
    //get list node
    var listNode = ajCall.xhr.responseXML.getElementsByTagName("list").item(0);
    var isListChanged = (listNode.getAttribute("isListChanged") == null || listNode.getAttribute("isListChanged") == "true");

    //for each element update the combo and set the selected value
    if (isListChanged){
        var elementsList = ajCall.xhr.responseXML.getElementsByTagName("element");
        if (elementsList != null){
            for (var i= 0 ; i < elementsList.length; i++){
                var combo = document.getElementsByName(elementsList[i].getAttribute("name"))[0];
                var oldValue = combo.options[combo.selectedIndex].value
                var newValue = elementsList[i].getAttribute("value");
                updateSelectBox(combo, listNode);
                combo.value = newValue;
                if (newValue != oldValue && combo.onchange != null){
                    combo.onchange();
                }
            }
        }
    }

    //continue handler chain
    return false;
}

function updateSelectBox(targetField, listNode) {
    targetField.options.length = 0;

    if (listNode != null) {
        var optionList = listNode.getElementsByTagName("option");
        for (var i = 0; i < optionList.length; i++) {
            var temp = ' ';
            if (optionList[i].firstChild) {
                temp = optionList[i].firstChild.nodeValue;
            }
            targetField.options[i] = new Option(temp, optionList[i].getAttribute("value"));
        }
    }
}

/**
 * Multibox update handler updates multiple checkbox lists.
 *
 * @param ajCall
 * @param resParam
 */
function multiboxUpdate(ajCall, resParam){
    //get list node
    var listNode = ajCall.xhr.responseXML.getElementsByTagName("multibox").item(0);
    var multiboxName = listNode.getAttribute("name");

    //for each element create the appropriate checkbox
    var multiboxHtml = "";
    var elementsList = ajCall.xhr.responseXML.getElementsByTagName("element");
    if (elementsList != null){
        for (var i= 0; i < elementsList.length; i++){
            var attributes = elementsList[i].getElementsByTagName("attribute");
            multiboxHtml = multiboxHtml + '<input type="checkbox" name="' + multiboxName + '" value="' + elementsList[i].getAttribute("value") + '"' + multiboxUpdateGetAttributeString(attributes) + '/>';
            multiboxHtml = multiboxHtml + '&nbsp;<label>' + elementsList[i].getAttribute("label") + '</label><br/>';
        }
    }

    //update the multibox list
    var multiboxList = document.getElementById(multiboxName + "List")
    multiboxList.innerHTML = multiboxHtml;

    //show hide multibox area
    var multiboxUpdateArea = document.getElementById(multiboxName + "Area");
    if (multiboxUpdateArea != null){
        showHideMultiboxUpdateArea(multiboxUpdateArea, multiboxHtml != "");
    }

    //continue handler chain
    return false;
}

function multiboxUpdateGetAttributeString(attributes) {
    var attributesHtml = '';

    if (attributes != null && attributes.length > 0){
        for (var i= 0; i < attributes.length; i++){
            attributesHtml = attributesHtml + ' ' + attributes[i].getAttribute("name") + ' ="' + attributes[i].getAttribute("value") +'"';
        }
    }

    return attributesHtml;
}

function showHideMultiboxUpdateArea(multiboxUpdateArea, isShow){

    if (multiboxUpdateArea != null){
        if (isShow){
            multiboxUpdateArea.style.display = "";
        } else {
            multiboxUpdateArea.style.display = "none";
        }
    }
}

/**
 * Validation error handler displays given validation errors. The errors for a field with the name fieldName
 * are displayed as inner html in the element with the id error.fieldName.  
 *
 * @param ajCall
 * @param resParam
 */
function validationError(ajCall, resParam){
    //get element list
    var elementsList = ajCall.xhr.responseXML.getElementsByTagName("error");
    if (elementsList != null){
        for (var i = 0; i < elementsList.length; i++){
            var fieldName = elementsList[i].getAttribute("field");
            var errorMessageElement = document.getElementById("error." + fieldName);

            errorMessageElement.innerHTML = errorMessageElement.innerHTML + elementsList[i].getAttribute("text");
        }
    }

    var validationErrorsIndicator = document.getElementById("areValidationErrorsPresent");
    if (validationErrorsIndicator !=  null){
        validationErrorsIndicator.value = true;
    }

    //break handler chain
    return true;
}

function clearValidationErrors(){
    var spanList = document.getElementsByTagName("span");

    if (spanList != null && spanList.length > 0){
        for (var i = 0; i < spanList.length; i++) {
            if (spanList[i].id.indexOf("error.") == 0){
                spanList[i].innerHTML = "";
            }
        }
    }

    var validationErrorsIndicator = document.getElementById("areValidationErrorsPresent");
    if (validationErrorsIndicator !=  null){
        validationErrorsIndicator.value = false;
    }
}



