

function showEmail (linkText, subject) {
    // Hide the email from crawlers and harvesters.
    showEmailAddress ("info", linkText, subject);
}



function showEmailAddress (mailbox, linkText, subject) {
    // Hide the email from crawlers and harvesters.
    var email = mailbox + "@sfa" + "finity.com";
    document.write ("<a href=\"mailto:" + email + (subject ? ("?subject=" + subject) : "") +
                    "\">" + (linkText? linkText : email) + "</a>");
}


var months = new Array(13);
months[0]  = "January";
months[1]  = "February";
months[2]  = "March";
months[3]  = "April";
months[4]  = "May";
months[5]  = "June";
months[6]  = "July";
months[7]  = "August";
months[8]  = "September";
months[9]  = "October";
months[10] = "November";
months[11] = "December";


function showDate() {
    var today = new Date();
    document.write (months[today.getMonth()] + " " + today.getDate() + ", " + today.getFullYear());
}


function showDemoWindow (name, windowTitle) {
    var title = windowTitle ? windowTitle : "Demo";
    window.open ("/public/demoWindow.html?demoName=" + name + "&windowTitle=" + title,
                 "demoWindow", "toolbar=no,location=no,status=no,menubar=no,scrollbars=no," +
                 "width=810,height=600,resizable=no");
}

function getWindowHeight() {
    var windowHeight = 0;
    if (typeof (window.innerHeight) == 'number') {
        windowHeight = window.innerHeight;
    } else if (document.documentElement && document.documentElement.clientHeight) {
        windowHeight = document.documentElement.clientHeight;
    } else if (document.body && document.body.clientHeight) {
        windowHeight = document.body.clientHeight;
    }
    return windowHeight;
}


function setFooter() {
    if (document.getElementById) {
        var windowHeight = getWindowHeight();
        if (windowHeight > 0) {
            var footerElement = document.getElementById('footer');
            var footerHeight = footerElement.offsetHeight;
            if (windowHeight - footerHeight >= 0) {
                footerElement.style.position = "absolute";
                footerElement.style.top = (windowHeight - footerHeight - 30) + "px";
            } else {
                footerElement.style.position = "static";
            }
        }
    }
}

// window.onresize = setFooter;

window.onload = function () {
    // Set up the click handlers for the main menu
    _setupClickHandlers();
}


function _setupClickHandlers () {
    var cells = document.getElementsByTagName ("td");
    for (var i = 0; i < cells.length; i++) {
        if (!cells[i].className || !cells[i].className.substring(0,8) == "menuCell") continue;
        var link = cells[i].getElementsByTagName ("a");
        if (link && link.length > 0) {
            var uri = link[0].getAttribute ("href");
            cells[i].uri = uri;
            cells[i].onclick = function () {
                window.location.href = this.uri;
            }
        }
    }
}







var isIE = document.all ? true : false;

// Construct a URL string that can be used to reload this window. Use all the parameters of the
// current window, adding (or replacing) the given parameter with the given value.
function windowReloadUrl (parameterName, value, dontUseSearchId) {
    var queryStringPkt = getQueryParameterPacket();
    if (!queryStringPkt) {
        queryStringPkt = new Array();
    }
    if (!dontUseSearchId && searchId && searchId != "") {
        // -----------------^^^^^^^^ This variable should be defined in the page
        queryStringPkt["search__id"] = searchId;
    }
    if (parameterName) queryStringPkt [parameterName] = value;
    return  window.location.pathname + makeQueryString (queryStringPkt);
}


function reloadWindow (parameterName, value, dontUseSearchId) {
    window.location.href = windowReloadUrl (parameterName, value, dontUseSearchId);
}


function doSort (pagingNodeId) {
    var sortSelector = document.getElementById ("sortSelector__" + pagingNodeId);
    if (!sortSelector) {
        alert ("Huh? No sort selector!");
        return;
    }
    var sortId = sortSelector.options[sortSelector.selectedIndex].value;
    reloadWindow ("order__by__" + pagingNodeId, sortId);
}

  

function showNextRecord (nodeId) {
    var recNo = listNodeProperties[nodeId].recNo;
    if (!recNo) {
        recNo = 0;
    }
    document.write (++recNo);
    listNodeProperties[nodeId].recNo = recNo;
}


function showPage (pageNumber, pagingNodeId) {
    reloadWindow ("page__number__" + pagingNodeId, pageNumber);
}


function generationhref (pageNumber, pagingNodeId) {
    return "javascript:showPage (" + pageNumber + "," + pagingNodeId + ")";
}


function emitPagingRibbon (pagingNodeId) {
    var props = listNodeProperties[pagingNodeId];
    if (props) {
        paging (props.linkCount, props.pageNumber, 'public', pagingNodeId);
    }
}


function emitSortingArrow (listNodeId, columnNodeId, derefNodeId, columnNodeDesc) {
    var props = listNodeProperties[listNodeId];
    if (!props) return;
    var count = parseInt (props.count);
    if (isNaN(count) || count == 0) return;
    var result = "";
    var orderByField = props.orderBy;
    var sortKeyId = derefNodeId != "" ? derefNodeId : columnNodeId;
    var orderByParam = "order__by__" + listNodeId;
    if (orderByField == sortKeyId ||
        isPrefix (orderByField, sortKeyId + ",") ||
        isSuffix (orderByField, "," + sortKeyId)) {
        
        result = "<a href=javascript:reloadWindow('" + orderByParam + "',-" + sortKeyId + ")>" +
            '<img src="/atCRM/images/arrow_dwn.gif" border="0" ' +
            'title="Sort descending, by ' + columnNodeDesc + '"></a>';
    } else if (orderByField == ('-' + sortKeyId) ||
        isPrefix (orderByField, '-' + sortKeyId + ",") ||
        isSuffix (orderByField, ",-" + sortKeyId)) {
        result = "<a href=javascript:reloadWindow('" + orderByParam + "'," + sortKeyId + ")>" +
            '<img src="/atCRM/images/arrow_up.gif" border="0" ' +
            'title="Sort ascending, by ' + columnNodeDesc + '"></a>';
    }  else {
        result = "<a href=javascript:reloadWindow('" + orderByParam + "'," + sortKeyId + ")>" +
            '<img src="/atCRM/images/arrow_rt.gif" border="0" ' +
            'title="Sort ascending, by ' + columnNodeDesc + '"></a>';
    }
    document.write (result);
}


function isPrefix (s1, s2) {
    return s1.substring (0, s2.length) == s2;
}

function isSuffix (s1, s2) {
    return s1.substring (s1.length - s2.length) == s2;
}


function reloadByLetter (nodeId, columnName, letter) {
    var condKey = "condition__" + nodeId;
    var cond = (columnName && letter) ? ("upper (" + columnName + ") like '" + letter + "%'") : "";
    reloadWindow (condKey, cond, true);
}


function setupLetterLink (nodeId) {
    var condition = getQueryParameter ("condition__" + nodeId);
    if (!condition) return;
    condition = unescape (condition);
    var letters = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
                   "A", "B", "C", "D", "E", "F", "G", "H", "I",
                   "J", "K", "L", "M", "N", "O", "P", "Q", "R",
                   "S", "T", "U", "V", "W", "X", "Y", "Z"];
    try {
        // Loop through the letter links for the given node id, and if one corresponds to our
        // current search string, highlight it.
        for (var i = 0; i < letters.length; i++) {
            var linkObj = document.getElementById ("letterLink__" + letters[i] + "__" + nodeId);
            if (linkObj && linkObj.tagName.toLowerCase() == "span" &&
                isPrefix (condition, "upper (") &&
                isSuffix(condition, ") like '" + letters[i] + "%'")) {
                // This link is for the current search, so it must be disabled.
                linkObj.style.color = "red";
                linkObj.innerHTML = '<a class="letterLinkClass" title="Records matching ' +
                    letters[i] + '">' + letters[i] + '</a>';
                break;
            }
        }
    } catch (e) {
        // If something bad happened, we just ignore the exception rather than show a JavaScript
        // error, because it isn't a big deal to fail to show the one link in red anyway.
    }
}







// Return the value of the query string parameter with the specified name.
function getQueryParameter (parameterName) {
    var qs = window.location.search;
    var result = null;
    if (qs && qs != "") {
        if (qs.charAt (0) == '?') qs = qs.substr(1);
        var params = qs.split ("&");
        for (var i = 0; i < params.length; i++) {
            var substring = params[i].substr (0, parameterName.length + 1);
            if (substring == parameterName + "=") {
                var value = params[i].substr(parameterName.length + 1).replace(/\+/g, ' ');
                result = unescape (value);
                break;
            }
        }
    }
    return result;
}




// Decode the query string and return a map of query parameters and associated values.
function getQueryParameterPacket () {
    var qs = window.location.search;
    var result = null;
    if (qs && qs != "") {
        if (qs.charAt (0) == '?') qs = qs.substr(1);
        result = parseQueryString (qs);
    }
    return result;
}


// Parse the given string as a query string, and return a map containing the corresponding keys and
// values.
function parseQueryString (qs) {
    if (!qs) return null;
    var result = new Array();
    var params = qs.split ("&");
    for (var i = 0; i < params.length; i++) {
        var str = params[i];
        var index = str.indexOf ('=');
        if (index > 0) {
            var key = str.substr (0, index);
            var value = unescape (str.substr (index+1));
            result[key] = value;
        }
    }
    return result;
}


// Construct a query string from a map of query parameters.
function makeQueryString (parameterPacket) {
    var strg = "";
    for (var key in parameterPacket) {
        var value = parameterPacket[key];
        if (value) {
            if (strg != "") {
                strg += "&";
            }
            strg += key + "=" + escape (parameterPacket[key]);
        }
    }
    if (strg != "") strg = "?" + strg;
    return strg;
}


// Unescape any embedded HTML-escaped characters in the given string, and return the result.
function htmlUnescape (s) {
    if (!s) return "";
    var returnVal = "";
    for (var i = 0; i < s.length; i++) {
        var c = s.charAt (i);
        if (c != '&') {
            returnVal += c;
        } else if (s.substring (i, i+5) == "&amp;") {
            // Take care of some special cases, though not all.
            returnVal += "&";
            i += 4;
        } else if (s.substring (i, i+4) == "&lt;") {
            returnVal += "<";
            i += 3;
        } else if (s.substring (i, i+4) == "&gt;") {
            returnVal += ">";
            i += 3;
        } else if (s.substring (i, i+6) == "&quot;") {
            returnVal += '"';
            i += 5;
        }  else {
            // Do the numeric case.
            if (i < s.length - 1 && s.charAt (i+1) == '#') {
                var j = s.indexOf (';', i+1);
                var charVal = parseInt (s.substring (i+2,j));
                returnVal += String.fromCharCode (charVal);
                i = j;
            } else {
                returnVal += c;
            }
        }
    }
    return returnVal;
}


function contentOfElementWithId (eltId) {
    var elt = document.getElementById (eltId);
    return elt ? elt.innerHTML : null;
}

// Provide the ability to trim a string, by removing leading and trailing spaces.
// For example:
//        var s2 = s1.trim();
String.prototype.trim = function () {
    if (this.length <= 0) return this;
    var left, right;
    for (var left = 0; left < this.length && this.charAt(left) == ' '; left++);
    for (var right = this.length-1; right >= 0 && this.charAt(right) == ' ';
         right--);
    return left <= right ? this.substring (left, right+1) : "";
}



String.prototype.startsWith = function (otherStr) {
    var len = Math.min (this.length, otherStr.length);
    return otherStr && (this.substring (0, len) == otherStr);
}


String.prototype.endsWith = function (otherStr) {
    var len = Math.min (this.length, otherStr.length);
    return otherStr && (this.substring (this.length - len) == otherStr);
}


String.prototype.replaceAll = function (target, replacement) {
    var s = this.replace (new RegExp (target, "g"), replacement);
    return s;
}


Number.prototype.formatWithLeadingZeros = function (minLength) {
    var strg = this.toString();
    var nChars = strg.length;
    for (var i = nChars; i < minLength; i++) {
        strg = "0" + strg;
    }
    return strg;
}


Number.prototype.formatWithCommas = function () {
    var aString = this.toString();
    var result = "";
    var n = aString.length;
    var index = aString.indexOf ('.');
    if (index > 0) n = index;
    for (var i = n-1; i >= 0; i--) {
        var aChar = aString.charAt (i);
        if ((n-1-i) % 3 == 0 && i < n-1 && i >= 0) result = "," + result;
        result = aChar + result;
    }
    return result;
}
