var isNS4 = (document.layers ? true : false);
var isNS6 = (!document.all && document.getElementById) ? true : false;
var isIE4 = (document.all && !document.getElementById) ? true : false;
var isIE5plus = (document.all && document.getElementById) ? true : false;
// var isIE = (isIE4 || isIE5plus);
var isIE = navigator.appName.indexOf("Microsoft") != -1;
var isFirefox = isNS6; // navigator.appName.indexOf("Firefox") != -1;

var useDialogs = isIE;

function saveFormData(form) {
    var saveData = new Array(form.elements.length);
    for (var i = 0; i < saveData.length; i++) {
        saveData[i] = getValue(form.elements[i]);
    }
    form.saveData = saveData;
    return saveData;
}

function initialiseFormData(form) {
    for (var i = 0; i < form.elements.length; i++) {
        var field = form.elements[i];
        initialiseFormField(field);
    }
    // initialiseControls(form.name);
}

function initialiseControls() {
    if (window.registeredControls) {
        for (var i = 0; i < document.forms.length; i++) {
            var registeredControls = window.registeredControls[document.forms[i].name];
            if (registeredControls) {
                for (var i = 0; i < registeredControls.length; i++) {
                    if (registeredControls[i].initialise) {
                        registeredControls[i].initialise();
                    }
                }
            }
        }
    }
}

function initialiseFormField(field) {
    var form = field.form;
    var value = form.initialValues[field.name];
    if (value != null) {
        if (typeof value != "string") {
            select(field, value);
        }
        else {
            setValue(field, value);
        }
    }
}

function registerControl(formName, control) {
    if (control != null) {
        if (!window.registeredControls) {
            window.registeredControls = new Array();
        }
        var registeredControls = window.registeredControls[formName];
        if (registeredControls == null) {
            registeredControls = new Array();
            window.registeredControls[formName] = registeredControls;
        }
        registeredControls[registeredControls.length] = control;
    }
}

function hasFormDataChanged(form, saveData) {
    for (var i = 0; i < saveData.length; i++) {
        if (form.elements[i].name.indexOf("DB_") == 0 && saveData[i] != getValue(form.elements[i])) {
            return true;
        }
    }
    return false;
}

function forwardForm(form, url) {
    if (form.newData) {
        if (confirm("The data you are editing is new and must be saved before continuing. Do you wish to save?")) {
            form.forward.value = url;
            if (form.validate()) {
                submitForm(form, 'save');
            }
        }
        return false;
    }
    if (hasFormDataChanged(form, form.saveData)) {
        form.forward.value = url;
        if (confirm("The data you are editing has been changed. Do you wish to save?")) {
            if (form.validate()) {
                submitForm(form, 'save');
            }
        }
        else {
            submitForm(form, 'cancel');
        }
    }
    else {
        form.forward.value = url;
        submitForm(form, 'cancel');
    }
    return true;
}

function validateAndSubmitForm(form, button, target, operationType) {
    if (validateForm(form, button, operationType)) {
        submitForm(form, button, target);
        return true;
    }
    return false;
}

function validateForm(form, button, operationType) {
    if ((button == 'save') && (operationType == 'edit')) {
        if (!hasFormDataChanged(form, form.saveData)) {
            alert("No changes have been made to the data.");
            return false;
        }
    }
    if (form.validate ? !form.validate() : !processValidationRules(form)) return false;
    if (form.customValidate && !form.customValidate()) { // check if custom validation is defined
        return false;
    }
    return true;
}

function addValidationRule(functionVar, field, arg1, arg2, etc) {
    // supports 10 arguments
    if (!field.validationRules) {
        field.validationRules = new Array();
    }
    var rules = field.validationRules;
    var args = new Array();
    for (var i = 0; i < arguments.length; i++) {
        args[i] = arguments[i];
    }
    rules[rules.length] = args;
}

function processValidationRules(form) {
    for (var i = 0; i < form.elements.length; i++) {
        var element = form.elements[i];
        // alert("Element: " + element.name);
        if (element.type == "radio") {
            var collection = element.form[element.name];
            if (element != collection[0]) {
                continue;
            }
            element = collection;
        }
        if (element.validationRules) {
            var rules = element.validationRules;
            for (var j = 0; j < rules.length; j++) {
                var rule = rules[j];
                var args = new Array();
                for (var k = 0; k < rule.length; k++) {
                    args[k] = rule[k];
                }
                // alert("Rule: " + args[1].name);
                var fn = args.shift();
                if (!fn(args.shift(), args.shift(), args.shift(), args.shift(), args.shift(), args.shift(), args.shift(), args.shift(), args.shift())) return false;
            }
        }
    }
    return true;
}

function submitForm(form, button, target) {
    if (form.button) {
        form.button.value = button;
    }

    if (target != null) {
        form.target = target;
    }

    enableForm(form);
    form.submit();
}

function getValue(field) {
    if (field) {
        if (field.type == 'select-one') {
            return (field.selectedIndex < 0 ? "" : field.options[field.selectedIndex].value);
        }
        else if (field.type == 'checkbox') {
            return (field.checked ? 1 : 0);
        }
        else if ((field.length != null) && (field.length > 0)) {
             if (field[0].type == "radio") {
                 for (var i = 0; i < field.length; i++) {
                     if (field[i].checked) {
                         return field[i].value;
                     }
                 }
                 return "";
             }
             var ka = new Array();
             for (var i = 0; i < field.length; i++) {
                 if (field[i].type != 'checkbox' || field[i].checked) {
                     var value = field[i].value;
                     ka[value] = value;
                 }
             }
             return ka;
        }
        else if (field.type == "radio") {
            return (field.checked ? field.value : "");
        }
        else {
            return field.value;
        }
    }
    return null;
}

function getSelectedOption(field) {
    if (typeof field != 'undefined') {
        if (field.type == 'select-one') {
            if (field.selectedIndex >= 0) {
                return field.options[field.selectedIndex];
            }
        }
    }
    return null;
}

function getSelectedOptionText(field) {
    var option = getSelectedOption(field);
    if (option != null) {
        return option.text;
    }
    return null;
}

function checkMandatoryField(field, message) {
    var text = getValue(field);
    if (text != null) {
        if (trim(text) == '') {
            alert(message);
            focusOn(field);
            return false;
        }
    }
    return true;
}

function checkFieldLength(field, maxLength, message) {
    if (field.value.length > maxLength) {
        alert(message);
        field.focus();
        return false;
    }
    return true;
}

function checkFieldLengthRange(field, minLength, maxLength, message) {
    if ((field.value.length < minLength) || (field.value.length > maxLength)) {
        alert(message);
        field.focus();
        return false;
    }
    return true;
}

var monthNames = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');

function checkDateField(field, message) {
    if (field.value != "") {
        var date = validateDate(field.value);
        if (date == null) {
            alert(message);
            field.focus();
            return false;
        }
        field.value = date.getDate() + " " + monthNames[date.getMonth()].substring(0, 3) + " " + date.getFullYear();
    }
    return true;
}

function validateDate(date) {
    if (date.indexOf("-") >= 0) {
        var parts = date.split("-");
        if (parts.length > 0 && isInteger(parts[1])) {
            date = date.replaceAll("-", "/");
        }
        else {
            date = date.replaceAll("-", " ");
        }
    }
    if (date.indexOf("/") >= 0) {
        var parts = date.split("/");
        if (parts.length == 3 && isInteger(parts[0]) && isInteger(parts[1]) && isInteger(parts[2])) {
            var year = parseInt(parts[2]);
            if (year < 50) {
                year += 2000;
            }
            // reverse the day and month for Australian dates
            date = parts[1] + "/" + parts[0] + "/" + year;
        }
    }
    var validDate = Date.parse(date);
    if (isNaN(validDate)) {
        return null;
    }
    return new Date(validDate);
}

function checkDateRange(fromField, toField, message) {
    if (fromField.value != "" && toField.value != "") {
        var date1 = validateDate(fromField.value);
        var date2 = Date.parse(toField.value);
        if (date1 == null || date2 == null || date1 > date2) {
            alert(message);
            fromField.focus();
            return false;
        }
    }
    return true;
}

function changePageNo(form, pageNo) {
    form.pageNo.value = pageNo; form.submit();
}

function fixURL(url) {
    url = escape(url);
    url = url.replace(/\//g, "%2f");
    return url;
}

function newUser() {
    if (top.mast != null) {
        top.mast.location.reload();
    }
}

function setValue(field, value) {
    if (field != null) {
        if (field.type == 'select-one') {
            field.selectedIndex = 0; // -1;
            for (i = 0; i < field.options.length; i++) { if (field.options[i].value == value) { field.selectedIndex = i; break; } }
        }
        else if (field.type == 'select-multiple') {
            field.selectedIndex = -1;
            for (i = 0; i < field.options.length; i++) { if (field.options[i].value == value) { field.selectedIndex = i; break; } }
        }
        else if (field.type == 'checkbox') {
            field.checked = (value == '1');
        }
        else if (field.length != null) {
            if (field[0].type == 'radio') {
                for (var i = 0; i < field.length; i++) {
                    if (field[i].value == value) {
                        field[i].checked = true;
                        break;
                    }
                }
            }
            else if (field[0].type == 'checkbox' && value instanceof Array) {
                for (var i = 0; i < field.length; i++) {
                    field[i].checked = (value[field[i].value] != null);
                }
            }
        }
        else if (field.type == 'radio') {
            if (field.value == value) {
                field.checked = true;
            }
        }
        else if (field.type == 'hidden') {
            if (value == '1' || value == '0') {
               field.value = (value == '1' ? '1' : '0');
               var checkbox = field.form["CB_" + field.name];
               if (checkbox != null) {
                   checkbox.checked = (value == '1');
               }
            }
            else {
                field.value = value;
            }
        }
        else {
            field.value = value;
        }
    }
}

function setValueByText(field, value) {
    if (field != null) {
        if (field.type == 'select-one' || field.type == 'select-multiple') {
            field.selectedIndex = 0; // -1;
            for (i = 0; i < field.options.length; i++) { if (field.options[i].text == value) { field.selectedIndex = i; break; } }
        }
    }
}

function select(field, values) {
    if (field != null) {
        if (field.type == 'select-multiple') {
            for (i = 0; i < field.options.length; i++) { field.options[i].selected = false; for (j = 0; j < values.length; j++) { if (field.options[i].value == values[j]) { field.options[i].selected = true; break; } } }
        }
    }
}

function validateEmail(email) {
    var atIndex = email.indexOf("@");
    if (atIndex > 0) {
        var dotIndex = email.indexOf(".",atIndex);
        if ((dotIndex > atIndex+1) && (email.length > dotIndex+1))
            return true;
    }
    return false;
}

function isInteger(string) {
    return validateString(string, "1234567890");
}

function validateString(originalString, validChars) {
    for (var i = 0; i < originalString.length; i++) {
        if (validChars.indexOf(originalString.charAt(i)) == -1) {
            return false;
        }
    }
    return true;
}

function validatePhoneNumber(phoneNumber) {
    return validateString(phoneNumber, " +-()0123456789");
}

function checkFloatField(field, message) {
    if (!validateFloat(field.value)) {
        alert(message);
        field.focus();
        return false;
    }
    return true;
}

function checkIntegerField(field, message) {
    if (!validateInteger(field.value)) {
        alert(message);
        field.focus();
        return false;
    }
    return true;
}

function validateInteger(number) {
    var string = number;
    if (string.indexOf("-") == 0) {
        string = string.substr(1);
    }
    return validateString(string, "0123456789");
}

function validateFloat(number) {
    var string = number;
    if (string.indexOf("-") == 0) {
        string = string.substr(1);
    }
    if (string.indexOf(".") != string.lastIndexOf(".")) {
        return false;
    }
    return validateString(string, "0123456789.");
}

function validateNumberInRange(field, fieldName, min, max) {
    var value = parseFloat(field.value);
    if (value < min || value > max) {
        alert("You must enter a value for " + fieldName + " between " + min + " and " + max + ".");
        field.focus();
        return false;
    }
    return true;
}

function getURI(URL) {
    var pos = URL.indexOf("?");
    if (pos >= 0) {
        return URL.substring(0, pos);
    }
    else {
        return URL;
    }
}

function getURLParameters(URL) {
    var pos = URL.indexOf("?");
    if (pos >= 0) {
        return URL.substring(pos+1);
    }
    else {
        return "";
    }
}

function showFrame(frameName, href, height, width) {
    var frame = window.frames[frameName];
    if (typeof(frame) == "undefined") {
        frame = addIframe(frameName);
    }
    if (href != null) {
        frame.location.href = href;
    }
    frame = document.getElementById(frameName);
    frame.style.visibility = "visible";
    if (height != null) {
        frame.height = height;
    }
    if (width != null) {
        frame.width = width;
    }
}

// maximiseFrame: define iframe with name tag and call in child onload event (initialise) with
//  "parent.maximiseFrame(window.name)";

function maximiseFrame(frameName) {
    var frame = document.getElementById(frameName);
    var height = frame.Document.body.scrollHeight;
    // alert("Tag: " + lastChild.tagName + " Height: " + height); // leave for debug
    frame.style.height = height;
}

function loadFrame(frameName, href) {
    var frame = window.frames[frameName];
    if (typeof(frame) == "undefined") {
        frame = addIframe(frameName);
    }
    if (href != null) {
        frame.location.replace(href);
    }
}

function hideFrame(frameName) {
    frame = document.getElementById(frameName);
    if (frame == null) {
        return;
    }
    frame.style.visibility = "hidden";
    frame.height = 0;
    frame.width = 0;
}

function openWindow(windowName, URL, x, y, width, height, hasScrollbars, isResizable, hasHistory, hasStatus) {
    var scrollbars = "yes";
    var resizable = "yes";
    if (hasScrollbars != null && !hasScrollbars) {
        scrollbars = "no";
    }
    if (isResizable != null && !isResizable) {
        resizable = "no";
    }
    var status = "0";
    if (hasStatus != null && hasStatus) {
        status = "1";
    }
    if (x == -1) {
        x = getWindowLeft() + (getWindowWidth() - width) / 2;
    }
    if (y == -1) {
        y = getWindowTop() + (getWindowHeight() - height) / 2;
    }
    var parameters = "toolbar=0,status=" + status + ",menubar=0,resizable=" + resizable + ",scrollbars=" + scrollbars + ",screenX=" + x + ",screenY=" + y + ",left=" + x + ",top=" + y + ",width=" + width + ",height=" + height;
    // alert(parameters);
    if (hasHistory == null || hasHistory) {
        URL = getContextPath() + "/vision/vision.jsp?URL=" + escape(URL);
    }
    var newWindow = window.open(URL, windowName, parameters);
    // var newWindow = showModalDialog(URL,'','help:no;status:no;');
    newWindow.opener = window;
    if (top.history.mainWindow) {
        newWindow.history.mainWindow = top.history.mainWindow;
    }
    newWindow.focus();
    return newWindow;
}

function openWindowRelative(windowName, URL, xOffset, yOffset, width, height, hasScrollbars, isResizable, hasHistory) {
    var x = getWindowLeft() + xOffset;
    var y = getWindowTop() + yOffset;
    return openWindow(windowName, URL, x, y, width, height, hasScrollbars, isResizable, hasHistory);
}

function openCentredWindow(windowName, URL, width, height, hasScrollbars, isResizable, hasHistory) {
    return openWindow(windowName, URL, -1, -1, width, height, hasScrollbars, isResizable, hasHistory);
}

function openDialog(URL, args, x, y, width, height, hasScrollbars, isResizable, hasHistory, hasStatus) {
    var scrollbars = "yes";
    var resizable = "yes";
    if (hasScrollbars != null && !hasScrollbars) {
        scrollbars = "no";
    }
    if (isResizable != null && !isResizable) {
        resizable = "no";
    }
    var status = "0";
    if (hasStatus != null && hasStatus) {
        status = "1";
    }
    if (x == -1) {
        x = getWindowLeft() + (getWindowWidth() - width) / 2;
    }
    if (y == -1) {
        y = getWindowTop() + (getWindowHeight() - height) / 2;
    }
    var features = "status: " + status + "; resizable: " + resizable + "; scroll: " + scrollbars + "; dialogLeft: " + x + "px; dialogTop: " + y + "px; dialogWidth: " + width + "px; dialogHeight: " + height + "px;";
    // alert(features);
    if (hasHistory == null || hasHistory) {
        URL = getContextPath() + "/vision/vision.jsp?URL=" + escape(URL);
    }
    var result = showModalDialog(URL, args, features);
    return result;
}

function openCentredDialog(URL, args, width, height, hasScrollbars, isResizable, hasHistory, hasStatus) {
    openDialog(URL, args, -1, -1, width, height, hasScrollbars, isResizable, hasHistory, hasStatus);
}

function openDialogRelative(URL, args, xOffset, yOffset, width, height, hasScrollbars, isResizable, hasHistory) {
    var x = getWindowLeft() + xOffset;
    var y = getWindowTop() + yOffset;
    return openDialog(URL, args, x, y, width, height, hasScrollbars, isResizable, hasHistory);
}

function extractKey(URLKey, columnName) {
    // lower-case URLKey and columnName to enable case-insensitive searching
    var unencoded = unescape(URLKey);
    var lcUnencoded = unencoded.toLowerCase();
    var lcColumnName = columnName.toLowerCase();
    var pos = lcUnencoded.indexOf("." + lcColumnName + "=");
    var extra = 2;
    if (pos < 0) {
        pos = lcUnencoded.indexOf("," + lcColumnName + "=");
    }
    if (pos < 0) {
        pos = lcUnencoded.indexOf(lcColumnName + "=");
        extra = 1;
    }
    // Now that we have pos, use the original columnName and unencoded
    // vars to return the proper case.
    if (pos >= 0) {
        pos += columnName.length + extra;
        var key = unencoded.substring(pos);
        var endPos = key.indexOf(",");
        if (endPos >= 0) {
            key = key.substring(0, endPos);
        }
    }
    return key;
}

function getWindowLeft() {
    if (isNS6) {
        return top.screenX;
    }
    else if (isIE) {
        return top.screenLeft;
    }
    return 0;
}

function getWindowTop() {
    if (isNS6) {
        return top.screenY;
    }
    else if (isIE) {
        return top.screenTop;
    }
    return 0;
}

function disableForm(form) {
    if (!form.saveProtection) {
        var saveProtection = new Array(form.elements.length);
        for (var i = 0; i < saveProtection.length; i++) {
            saveProtection[i] = form.elements[i].disabled;
            form.elements[i].disabled = true;
        }
        form.saveProtection = saveProtection;
    }
}

function enableForm(form) {
    for (var i = 0; i < form.elements.length; i++) {
        if (form.saveProtection && form.saveProtection.length == form.elements.length) {
            form.elements[i].disabled = form.saveProtection[i];
        }
        else {
            form.elements[i].disabled = false;
        }
    }
    form.saveProtection = null;
}

function clearAndDisable(field) {
    if (field.type == 'select-one') {
        field.options.length = 0;
        field.options[0] = new Option("", "");
        field.selectedIndex = 0;
    }
    else if (field.type == 'select-multiple') {
        field.options.length = 0;
    }
    else {
        setValue(field, "");
    }
    field.disabled = true;
}

function ltrim(s) {
    return s.replace(/^\s*/, "");
}

function rtrim(s) {
    return s.replace(/\s*$/, "");
}

function trim(s) {
    s = ltrim(s);
    return rtrim(s);
}

function getUniqueWindowName(prefix) {
    var dte = new Date();
    return prefix + dte.getDay() + dte.getMonth() + dte.getYear() +
                    dte.getHours() + dte.getMinutes() + dte.getSeconds();
}

function focusOn(field) {
    if (field.length != null && field.type != 'select-one' && field.type != 'select-multiple') {
        field[0].focus();
    }
    else {
        if (!field.disabled) {
            field.focus();
        }
    }
}

function addToStartOfList(list, item, delimiter) {
    if (delimiter == null) {
        delimiter = ",";
    }
    var newList = removeFromList(list, item, delimiter);
    if (newList.length > 0) {
        newList = item + delimiter + newList;
    }
    else {
        newList = item;
    }
    return newList;
}

function addToEndOfList(list, item, delimiter) {
    if (delimiter == null) {
        delimiter = ",";
    }
    var newList = removeFromList(list, item, delimiter);
    if (newList.length > 0) {
        newList = newList + delimiter + item;
    }
    else {
        newList = item;
    }
    return newList;
}

function removeFromList(list, item, delimiter) {
    if (delimiter == null) {
        delimiter = ",";
    }
    var items = list.split(delimiter);
    var newList = "";
    if (items != null) {
        var count = 0;
        for (var i = 0; i < items.length; i++) {
            if (items[i] != item) {
                newList += (count > 0 ? delimiter : "") + items[i];
                count++;
            }
        }
    }
    return newList;
}

function releaseTableRowOnCloseEvent() {
    if (event.clientY < 0) {
        releaseTableRow();
    }
}

function releaseTableRowOnClose(context) {
    window.onbeforeunload = releaseTableRowOnCloseEvent;
    window.lockContext = context;
}

function releaseTableRow(context) {
    if (context == null && window.lockContext) {
        context = window.lockContext;
    }
    var serverLink = null;
    if (top.opener && !top.opener.closed && top.opener.top.serverLink) {
        serverLink = top.opener.top.serverLink;
    }
    else if (top.history.mainWindow && !top.history.mainWindow.closed) {
        serverLink = top.history.mainWindow.serverLink;
    }
    if (serverLink) {
        var URL = getContextPath() + "/vision/service/release-row.jsp?" + getQueryString(location.href);
        if (context != null) {
            URL = addURLParameter(URL, "context", context);
        }
        serverLink.location.replace(URL);
    }
    else {
        alert("Cannot release locked row.");
    }
}

function releaseTableRowAndClose(context) {
    releaseTableRow(context);
    top.close();
}

function getQueryString(URL) {
    var pos = URL.indexOf("?");
    if (pos >= 0) {
        return URL.substring(pos + 1);
    }
    return "";
}

function addURLParameter(URL, parameter, value) {
    var pos = URL.indexOf("?");
    URL += (pos >= 0 ? "&" : "?") + parameter + "=" + escape(value);
    return URL;
}

function replaceURLParameter(URL, parameter, value) {
    var pos = URL.indexOf("?");
    if (pos >= 0) {
        pos = URL.search("[?&]" + parameter + "=")
        if (pos >= 0) {
            var newURL = URL.substr(0, pos + parameter.length + 2) + escape(value);
            pos = URL.indexOf("&", pos + 1);
            if (pos >= 0) {
                newURL += URL.substr(pos);
            }
            URL = newURL;
        }
        else {
            URL += "&" + parameter + "=" + escape(value);
        }
    }
    else {
        URL += "?" + parameter + "=" + escape(value);
    }
    return URL;
}

function dumpWindowStack() {
    var stack = "Window Stack:\n";
    stack = _dumpWindowStack(window, stack);
    alert(stack);
}

function _dumpWindowStack(window, stack) {
    var name = "<closed>";
    if (!window.closed) {
        if (window.top.opener) {
            stack = _dumpWindowStack(window.top.opener, stack);
        }
        var name = window.top.name;
        if (name == "") {
            name = "<unnamed>";
        }
    }
    stack += " " + name + "\n";
    return stack;
}

function getXOffset(element) {
    var x = element.offsetLeft;
    if (!x) {
        x = 0;
    }
    if (element.parentElement) {
        x += getXOffset(element.parentElement);
    }
    return x;
}

function getYOffset(element) {
    var y = element.offsetTop;
    if (element.tagName == "TR") {
        y = 0;
    }
    if (!y) {
        y = 0;
    }
    if (element.parentElement) {
        y += getYOffset(element.parentElement);
    }
    return y;
}

function calculateFittedX(frame, x, width, cornerX, hasScrollBar) {
    var SBWidth = (hasScrollBar ? 20 : 0);
    if (x + width + SBWidth > frame.offsetWidth) {
        if (cornerX) {
            x -= width;
        }
        if (!cornerX || x < 0) {
            x = frame.offsetWidth - width - SBWidth;
            if (x < 0) {
                x = 0;
            }
        }
    }
    x += getXOffset(frame);
    return x;
}

function calculateFittedY(frame, y, height, cornerY, hasScrollBar) {
    var SBHeight = (hasScrollBar ? 18 : 0);
    if (y + height + SBHeight > frame.offsetHeight) {
        if (cornerY) {
            y -= height;
        }
        if (!cornerY || y < 0) {
            y = frame.offsetHeight - height - SBHeight;
            if (y < 0) {
                y = 0;
            }
        }
    }
    y += getYOffset(frame);
    return y;
}

function showPrompt(title, message, width, height, inputSize, defaultValue, callbackName) {
    var buttonList = "OK,Cancel";
    var buttonWidth = 60;
    var buttons = buttonList.split(",");
    var html = '<HTML><HEAD><TITLE>' + title + '</TITLE></HEAD>'
             + '<STYLE TYPE="text/css">'
             + 'body {font-family: Arial;}'
             + '</STYLE>'
             + '<BODY ONLOAD="document.promptForm.data.focus();" BGCOLOR="#D4D0C8" TOPMARGIN="5">'
             + '<SCRIPT LANGUAGE="Javascript">'
             + 'function submitForm(button) {'
             + 'var msg = opener.' + callbackName + '(window, button, document.promptForm.data.value); if (msg != null) {alert(msg);}'
             + '}'
             + '</SCRIPT>'
             + '<CENTER><B>'
             + message
             + '</B><FORM NAME="promptForm" ONSUBMIT="submitForm(\'OK\'); return false;">'
             // + '&nbsp;'
             + '<INPUT NAME="data" TYPE="TEXT" STYLE="font-family: Arial;" SIZE="' + inputSize + '" VALUE="' + defaultValue + '"><BR><BR>';
    for (var i = 0; i < buttons.length; i++) {
        html += '<INPUT TYPE="button" VALUE="' + buttons[i] + '" ONCLICK="submitForm(this.value); return false;" STYLE="width: ' + buttonWidth + ';">'
                 + '&nbsp;';
    }
    html += '</FORM></BODY></HTML>';
    var args = new Array();
    args["opener"] = window;
    args["html"] = html;
    var results = openCentredDialog(getContextPath() + "/vision/dialog.html", args, width, height, false, false, false, false);
    return results;
}

function showQuestion(name, title, message, x, y, width, height, buttonList, buttonWidth, callbackName) {
    var buttons = buttonList.split(",");
    var html = '<HTML><HEAD><TITLE>' + title + '</TITLE></HEAD>'
             + '<BODY BGCOLOR="#D4D0C8">'
             + '<SCRIPT LANGUAGE="Javascript">'
             + 'function callback(button) {'
             + '    opener.' + callbackName + '(window, button);'
             + '}'
             + '</SCRIPT>'
             + '<CENTER>'
             + '<B>' + message + '</B><BR>'
             + '<FORM NAME="questionForm">';
    for (var i = 0; i < buttons.length; i++) {
        html += '<INPUT TYPE="button" VALUE="' + buttons[i] + '" ONCLICK="callback(this.value); return false;" STYLE="width: ' + buttonWidth + ';">'
                 + '&nbsp;';
    }
    html += '</FORM></CENTER></BODY></HTML>';
    var promptWindow = openWindowRelative(name, "about:blank", x, y, width, height, false, false, false, false);
    if (promptWindow) {
        promptWindow.title = title;
        var doc = promptWindow.document;
        doc.open();
        doc.writeln(html);
        doc.close();
    }
}

function questionDialog(title, message, messageStyle, x, y, width, height, buttonList, buttonWidth, icon) {
    var buttons = buttonList.split(",");
    var html = '<HTML><HEAD><TITLE>' + title + '</TITLE></HEAD>'
             + '<BODY BGCOLOR="buttonface">'
             + '<SCRIPT LANGUAGE="Javascript">'
             + 'function answer(button) {'
             + '    window.returnValue = button;'
             + '    window.close();'
             + '}'
             + '</SCRIPT>'
             + '<TABLE CELLPADDING="5" CELLSPACING="10" BORDER="0">'
             + '<FORM NAME="questionForm">'
             + '<TR>'
             + '<TD>' + ((!icon || icon=='') ? '' : '<IMG SRC="' + icon + '">') + '</TD>'
             + '<TD style="' + messageStyle + '">' + message + '</TD>'
             + '</TR>'
             + '<TR><TD COLSPAN="2" ALIGN="center">';
    for (var i = 0; i < buttons.length; i++) {
        html += '<INPUT TYPE="button" VALUE="' + buttons[i] + '" ONCLICK="answer(this.value); return false;" STYLE="width: ' + buttonWidth + ';">'
                 + '&nbsp;';
    }
    html += '</TD></TR></TABLE></FORM></BODY></HTML>';
    if (x == -1) {
        x = getWindowLeft() + (getWindowWidth() - width) / 2;
    }
    if (y == -1) {
        y = getWindowTop() + (getWindowHeight() - height) / 2;
    }
    return openDialog(getContextPath() + "/vision/javascript/dialog.html", html, x, y, width, height, false, false, false);
}

function showList(frameName, options, x, y, width, maxRows, callbackName) {
    var rows = options.length;
    if (rows < 2) {
        rows = 2;
    }
    if (rows > maxRows) {
        rows = maxRows;
    }
    var frame = window.frames[frameName];
    if (typeof(frame) == "undefined") {
        frame = addIframe(frameName);
    }
    var html = '<HTML>'
             + '<BODY BGCOLOR="#D4D0C8" LEFTMARGIN="0" TOPMARGIN="0" MARGINWIDTH="0" MARGINHEIGHT="0" STYLE="overflow: hidden;">'
             + '<SCRIPT LANGUAGE="Javascript">'
             + 'function submitForm() {'
             + 'var list = document.listForm.list;'
             + 'var item = list.selectedIndex >= 0 ? list.options[list.selectedIndex] : null;'
             + 'parent.' + callbackName + '(item != null ? item.value : null, item != null ? item.text : null);'
             + '}'
             + 'function keyPress() {'
             + 'var key = event.keyCode;'
             + 'if (key == 13) submitForm(); else if (key == 27) parent.' + callbackName + '(null);'
             + '}'
             + '</SCRIPT>'
             + '<FORM NAME="listForm" ACTION="javascript: submitForm();">'
             + '<SELECT NAME="list" STYLE="width: 100%;" SIZE="' + rows + '" ONDBLCLICK="submitForm();" ONKEYPRESS="keyPress();"></SELECT>';
    html += '</FORM></BODY></HTML>';
    var doc = frame.document;
    doc.writeln(html);
    doc.close();
    var list = frame.document.listForm.list;
    list.options.length = 0;
    for (var i = 0; i < options.length; i++) {
        list.options[i] = options[i];
    }
    var frameElement = document.getElementById(frameName);
    frameElement.style.top = y;
    frameElement.style.left = x;
    frameElement.style.width = width;
    frameElement.style.height = doc.body.scrollHeight + 3;
    frameElement.style.visibility = "visible";
    // frameElement.frameBorder = "no";
    list.focus();
}

function hide(element) {
    if (element.style) {
        element.style.visibility = "hidden";
    }
}

function checkStyles(document) {
    var body = document.body;
    var message = checkAllStyles(body);
    if (message == "") {
        message = "All style classes are defined.";
    }
    alert(message);
}

function checkAllStyles(element) {
    var message = "";
    if (element.className) {
        var style = findStyle(element.document, element.className);
        if (style == null) {
            message += "Element " + element.tagName + " has undefined style class " + element.className + "\n";
        }
    }
    if (element.children) {
        for (var i = 0; i < element.children.length; i++) {
            message += checkAllStyles(element.children[i]);
        }
    }
    return message;
}

function findStyle(document, styleName) {
    for (var i = 0; i < document.styleSheets.length; i++) {
        var styleSheet = document.styleSheets[i];
        var rules = styleSheet.rules;
        if (!rules) {
            rules = styleSheet.cssRules;
        }
        if (rules) {
            for (var j = 0; j < rules.length; j++) {
                var rule = rules[j];
                if (rule.selectorText == "." + styleName) {
                    return rule.style;
                }
            }
        }
    }
    return null;
}

function styleAttribute(styleName, attributeName) {
    var style = findStyle(document, styleName);
    if (style != null) {
        return style[attributeName];
    }
    return null;
}

function setStyleWidth(styleName, width) {
    var style = findStyle(document, styleName);
    if (style != null) {
        style.width = width;
    }
}

function queueCall(queueName, functionVar, arg1, arg2, etc) {
    // supports 10 arguments
    if (!window.queue) {
        window.queue = new Array();
    }
    var queuedCalls = window.queue[queueName];
    if (!queuedCalls) {
        queuedCalls = new Array();
        window.queue[queueName] = queuedCalls;
    }
    var args = new Array();
    for (var i = 0; i < arguments.length; i++) {
        args[i] = arguments[i];
    }
    args.shift();
    queuedCalls[queuedCalls.length] = args;
}

function processCallQueue(queueName) {
    var queue = window.queue[queueName];
    var args = queue.shift();
    var fn = args.shift();
    fn(args.shift(), args.shift(), args.shift(), args.shift(), args.shift(), args.shift(), args.shift(), args.shift(), args.shift());
}

function loadOptions(field, options) {
    if (field.options) {
        field.options.length = 0;
        if (options) {
            for (var i = 0; i < options.length; i++) {
                field.options[i] = options[i];
            }
        }
    }
}

function KeyedArray() {
    this.list = new Array();
    this.keys = new Array();
}

KeyedArray.prototype.add = function(key, value) {
    var object = this.list[this.list.length] = new Object();
    object.key = key;
    object.value = value;
    this.keys[key] = object;
}

KeyedArray.prototype.toArray = function() {
    var array = new Array();
    for (var i = 0; i < this.list.length; i++) {
        array[i] = this.list[i].value;
    }
    return array;
}

KeyedArray.prototype.exclude = function(excludeList) {
    var result = new KeyedArray();
    for (var i = 0; i < this.list.length; i++) {
        var key = this.list[i].key;
        if (!excludeList.keys[key]) {
            result.add(key, this.list[i].value);
        }
    }
    return result;
}

KeyedArray.prototype.remove = function(key) {
    var value = this.keys[key];
    if (value != null) {
        this.keys[key] = null;
        if (value instanceof Object) {
            for (var i = 0; i < this.list.length; i++) {
                if (this.list[i] == value) {
                    this.list.splice(i, 1);
                    break;
                }
            }
        }
    }
}

function moveSelectedOptions(list1, list2) {
    var c = 0;
    while (c < list1.options.length) {
        var option = list1.options[c];
        if (option.selected) {
             list2.options[list2.options.length] = new Option(option.text, option.value);
             list1.options[c] = null;
        }
        else {
            c++;
        }
    }
}

String.prototype.replaceAll = function(findText, replaceText) {
    var originalString = new String(this);
    var newString = "";
    var index = 0;
    var pos = originalString.indexOf(findText, index);
    while (pos != -1) {
        newString += originalString.substring(index, pos) + replaceText;
        index = pos + findText.length;
        pos = originalString.indexOf(findText, index);
    }
    newString += originalString.substring(index, originalString.length);
    return newString;
}

function roundDecimal(value, precision) {
    var divide = Math.pow(10, precision);
    value = Math.round(value * divide) / divide;
    return value;
}

function columnFieldName(reference) {
    var f = this;
    if (reference.indexOf(".") == -1) {
        alert('Invalid syntax for column() function: "' + reference + '". Syntax: <table-alias>.<column>');
        return null;
    }
    reference = "DB_" + reference.replaceAll(".", "_");
    var field = f[reference];
    if (field == null) {
        field = f[reference.toUpperCase()];
        if (field == null) {
            alert("Form field " + reference + " not found.");
            return null;
        }
    }
    return field;
}

function scrollIntoView(element) {
    if (typeof element == "string") {
        element = document.getElementById(element);
    }
    if (element == null) {
        alert("scrollIntoView(): cannot find element.");
    }
    var window = element.document.parentWindow;
  var x = getXOffset(element);
  var w = element.offsetWidth;
  var y = getYOffset(element);
  var h = element.offsetHeight;
  var body = window.document.body;
  if (x < body.scrollLeft) {
    body.scrollLeft = x;
  }
  else if (x + w > body.scrollLeft + body.clientWidth) {
    body.scrollLeft = x + w - body.clientWidth;
  }
  if (y < body.scrollTop) {
    body.scrollTop = y;
  }
  else if (y + h > body.scrollTop + body.clientHeight) {
    body.scrollTop = y + h - body.clientHeight;
  }
}

function registerEventHandler(eventName, handlerFunction) {
    if (!window.events) {
        window.events = new Array();
    }
    window.events[eventName] = handlerFunction;
}

function raiseEvent(eventName, arg1, arg2, etc) {
    if (parent) {
        var args = arguments;
        if (handleEvent(parent, eventName, args)) {
            return true;
        }
    }
    if (top.opener && !top.opener.closed) {
        var args = arguments;
        if (handleEvent(top.opener, eventName, args)) {
            return true;
        }
    }
    return false;
}

function handleEvent(handlerWindow, eventName, originalArgs) {
    var events = null;
    try {
        events = handlerWindow.events;
    }
    catch (exception) {
        // alert("error: " + exception);
    }
    if (events) {
        var handlerFunction = events[eventName];
        if (handlerFunction) {
            var args = new Array();
            for (var i = 0; i < originalArgs.length; i++) {
                args[i] = originalArgs[i];
            }
            if (handlerFunction(args.shift(), args.shift(), args.shift(), args.shift(), args.shift(), args.shift(), args.shift(), args.shift(), args.shift())) {
                return true;
            }
        }
    }
    return false;
}

function saveVariable(variableName, value) {
    if (parent) {
        var save = null;
        if (!parent.save) {
            parent.save = new Array();
        }
        else {
            save = parent.save[window.name];
        }
        if (!save) {
            save = parent.save[window.name] = new Object();
        }
        save[variableName] = value;
     }
     else {
        alert("Nowhere to save variable.");
     }
}

function restoreVariable(variableName) {
    if (parent) {
        if (parent.save) {
            var save = parent.save[window.name];
            if (save) {
                return save[variableName];
            }
        }
    }
    return null;
}

function getFormFieldArray(formField) {
    if (formField) {
        if (!(formField.length > 0)) {
            var array = new Array(formField);
            return array;
        }
        return formField;
    }
    return null;
}

function addIframe(name) {
    var ifr = document.createElement("IFRAME");
    ifr.id = name;
    ifr.name = name;
    ifr.src = "/vision/blank.html";
    ifr.style.visibility = "hidden";
    ifr.style.position = "absolute";
    document.body.appendChild(ifr);
    return window.frames[name];
}

function sortResults(columnName) {
    var form = document.PageNav;
    form.sequence.value = (columnName == form.orderBy.value && form.sequence.value == "A") ? "D" : "A";
    form.orderBy.value = columnName;
    form.submit();
}

function openChildWindow(URL, width, height, windowNameOrArguments, hasScrollbars, isResizable, hasHistory) {
    var args = null;
    var windowName = null;
    if (windowNameOrArguments instanceof Array) {
        args = windowNameOrArguments;
    }
    else {
        windowName = windowNameOrArguments;
    }
    if (useDialogs && windowName == null) {
        if (args == null) {
            args = new Array();
        }
        args["opener"] = window;
        return openCentredDialog(URL, args, width, height, hasScrollbars, isResizable, hasHistory, false);
    }
    else {
        if (windowName == null) {
            windowName = getUniqueWindowName("WIN_");
        }
        openCentredWindow(windowName, URL, width, height, hasScrollbars, isResizable, hasHistory, false);
    }
    return null;
}

function initialiseChildWindow(pageName, URL) {
    if (top.dialogArguments != null) {
        var args = top.dialogArguments;
        top.opener = args["opener"];
    }
    else {
        top.registerWindow(top);
    }
    if (URL != null) {
        top.addToHistory(window, pageName, URL);
    }
    initialiseControls();
}

function setCheckBoxes(field, checked) {
    var array = getFormFieldArray(field);
    for (var i = 0; i < array.length; i++) {
        array[i].checked = checked;
    }
}

function sizeof(field) {
    var value = getValue(field);
    if (value instanceof Array) {
        if (value.length) {
            return value.length;
        }
        var count = 0;
        for (var key in value) count++;
        return count;
    }
    else if (value == "") {
        return 0;
    }
    return 1;
}

function getContextPath() {
    if (window.contextPath) {
        return window.contextPath;
    }
    return "";
}

function createForm(action, target, method) {
    if (method == null) {
        method = "POST";
    }
    var form = document.createElement("FORM");
    if (action != null) {
        form.action = action;
    }
    if (target != null) {
        form.target = target;
    }
    form.method = method;
    return form;
}

function addFormField(form, fieldType, fieldName, fieldValue) {
    if (document.getElementById) {
        var input = document.createElement("INPUT");
        input.setAttribute("type", fieldType);
        input.setAttribute("name", fieldName);
        input.setAttribute("value", fieldValue);
        form.appendChild(input);
    }
}

function addHiddenField(form, fieldName, fieldValue) {
    addFormField(form, "hidden", fieldName, fieldValue);
}

function copyForm(fromForm, toForm) {
    for (var i = 0; i < fromForm.elements.length; i++) {
        var element = fromForm.elements[i];
        if ((element.type != "radio" || element.checked) && (element.type != "checkbox" || getValue(element) != "")) {
            addFormField(toForm, "hidden", element.name, getValue(element));
        }
    }
}

function loadDocument(URL) {
    var request = null;
    if (window.XMLHttpRequest) {
        request = new XMLHttpRequest();
    }
    else if (window.ActiveXObject) {
        request = new ActiveXObject("Microsoft.XMLHTTP");
    }
    if (request) {
        request.open("GET", URL, false);
        request.send(null);
    }
    if (request.status == 200) {
        return request.responseText;
    }
    else {
        alert("ERROR: " + request.status + " " + request.statusText);
    }
    return null;
}

function executeServerFunction(URL) {
    return loadDocument(URL);
}

function encode(text) {
    text = text.replaceAll("&", "&amp;");
    text = text.replaceAll("<", "&lt;");
    text = text.replaceAll(">", "&gt;");
    return text;
}

function decode(text) {
    text = text.replaceAll("&amp;", "&");
    text = text.replaceAll("&lt;", "<");
    text = text.replaceAll("&gt;", ">");
    return text;
}

function funcName(f) {
    var s = f.toString().match(/function (\w*)/)[1];
    if ((s == null) || (s.length == 0)) return "anonymous";
    return s;
}

function stackTrace() {
    var s = "";
    for (var a = arguments.caller; a != null; a = a.caller) {
        s += funcName(a.callee) + "\n";
        if (a.caller == a) break;
    }
    return s;
}

function getWindowWidth() {
    if (top.document.body) {
        return top.document.body.offsetWidth;
    }
    return 0;
}

function getWindowHeight() {
    if (top.document.body) {
        return top.document.body.offsetHeight;
    }
    return 0;
}

function getFrameHeight() {
    if (isIE) {
        return document.body.offsetHeight;
    }
    else if (isFirefox) {
        return document.body.scrollHeight;
    }
    return 0;
}

function getPageHeight() {
    if (isIE) {
        return document.body.scrollHeight;
    }
    else if (isFirefox) {
        return document.body.offsetHeight;
    }
    return 0;
}

function maximiseHeight(element, minHeight) {
    if (isIE || isFirefox) {
        var height = element.offsetHeight;
        var pageHeight = getPageHeight();
        var maxHeight = getFrameHeight();
        var newHeight = maxHeight - (pageHeight - height);
        if (newHeight < minHeight) {
            newHeight = minHeight;
        }
        element.style.height = newHeight;
    }
}

function getDomain() {
    var protocol = location.protocol;
    var port = location.port;
    var portSuffix = ((protocol == "http:" && port == 80) || protocol == "https:" && port == 443) ? "" : ":" + port;
    return location.protocol + "//" + location.hostname + portSuffix + "/";
}

function addLoadEvent(func) {
  if (!document.getElementById | !document.getElementsByTagName) return;
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      oldonload();
      func();
    }
  }
}
