﻿// Contains all the javascript functions

// Global variable to get browser window information
var windowState =
(function() {
    var readScroll = { scrollLeft: 0, scrollTop: 0 };
    var readSize = { clientWidth: 0, clientHeight: 0 };
    var readScrollX = 'scrollLeft';
    var readScrollY = 'scrollTop';
    var readWidth = 'clientWidth';
    var readHeight = 'clientHeight';

    function otherWindowTest(obj) {
        if ((document.compatMode) && (document.compatMode == 'CSS1Compat') && (document.documentElement)) {
            return document.documentElement;
        }
        else if (document.body) {
            return document.body;
        } else {
            return obj;
        }
    };

    if ((typeof this.innerHeight == 'number') && (typeof this.innerWidth == 'number')) {
        readSize = this;
        readWidth = 'innerWidth';
        readHeight = 'innerHeight';
    } else {
        readSize = otherWindowTest(readSize);
    }
    if ((typeof this.pageYOffset == 'number') && (typeof this.pageXOffset == 'number')) {
        readScroll = this;
        readScrollY = 'pageYOffset';
        readScrollX = 'pageXOffset';
    } else {
        readScroll = otherWindowTest(readScroll);
    }

    return {
        getScrollX: function() {
            return (readScroll[readScrollX] || 0);
        },
        getScrollY: function() {
            return (readScroll[readScrollY] || 0);
        },
        getWidth: function() {
            return (readSize[readWidth] || 0);
        },
        getHeight: function() {
            return (readSize[readHeight] || 0);
        }
    };
})();

// -------------- Dragging Functions ------------- //

// Global variable to handle dragging and dropping
var g_objDragController = new Object();

// This function will make all elements on a page with a certain class name draggable
function makeClassesDraggable(classNames) {
    // Make sure the parameter is valid
    if (!classNames || !classNames.length) { return; }
    // Uppercase each class name
    var nClassNameCount = classNames.length;
    for (var i = 0; i < nClassNameCount; i++) {
        classNames[i] = classNames[i].toUpperCase();
    }

    // Get all the div elements for that class name
    var a_objElements = document.getElementsByTagName("div");

    // working variables
    var nCount = a_objElements.length;
    var obj = null;
    var a_elementClasses = null;
    var nElementClassesCount = 0;
    var szClassName = "";
    var bEventAdded = false;

    for (var i = 0; i < nCount; i++) {
        // Get the element
        obj = a_objElements[i];
        if (obj.className) {
            // the classes are space delimited, so get them as individual names
            a_elementClasses = obj.className.split(' ');
            nElementClassesCount = a_elementClasses.length;
            bEventAdded = false;

            // Loop through all the valid class names we'll make draggable
            for (var j = 0; j < nClassNameCount; j++) {
                // check if we've already made a match
                if (bEventAdded) { break; }

                // Get the name of the class we're trying to match
                szClassName = classNames[j];

                // Loop through the classes of the element
                for (var k = 0; k < nElementClassesCount; k++) {
                    // check if this matches our class
                    if (szClassName = a_elementClasses[k].toUpperCase()) {
                        // DOM Standard way of add mouse event
                        if (obj.addEventListener) {
                            obj.addEventListener("mousedown", makeDraggable, true);
                        } else if (obj.attachEvent) {
                            // IE way of doing it
                            obj.attachEvent("onmousedown", makeDraggable);
                        }

                        // event added, we can stop
                        bEventAdded = true;
                        break;
                    }
                } // end for of element classes count
            } // end for of class name count
        } // end if for obj.className
    } // end for the total elements by tagname count
}

// Starts a drag on an element
function makeDraggable(event,element) {
    // Make sure we have valid parameters
    if (!event) { return; }
    return;

    // get the mouse position
    var x, y;
    var bIsIE = false;
    if (document.attachEvent) {
        // Handle the IE version of this method
        x = window.event.clientX;
        y = window.event.clientY;
        g_objDragController.dragElement = window.event.srcElement;
        bIsIE = true;
    } else {
        // Handle the Netscape/Firefox version of this method
        x = event.clientX;
        y = event.clientY;
        g_objDragController.dragElement = event.target;
    }

    // Check if we were supplied an element
    if (arguments.length > 1 && element && element.style) {
        g_objDragController.dragElement = element;
    }

    // Make sure we have a valid object
    if (!g_objDragController.dragElement || !g_objDragController.dragElement.style) { return; }

    // Save the start position of the mouse and the element
    g_objDragController.cursorStartX = x + windowState.getScrollX();
    g_objDragController.cursorStartY = y + windowState.getScrollY();
    g_objDragController.dragElement.style.position = 'absolute';
    g_objDragController.elementStartLeft = parseInt(g_objDragController.dragElement.style.left, 10);
    g_objDragController.elementStartTop = parseInt(g_objDragController.dragElement.style.top, 10);
    if (isNaN(g_objDragController.elementStartLeft)) { g_objDragController.elementStartLeft = g_objDragController.cursorStartX - 50; }
    if (isNaN(g_objDragController.elementStartTop)) { g_objDragController.elementStartTop = g_objDragController.cursorStartY - 10; }

    // Update the zindex of the element to be above all others
    try {
        g_objDragController.dragElement.style.zIndex = ++g_objDragController.zIndex;
    } catch (err) { }

    // Add the mousemove and moseup events on the page
    if (bIsIE) {
        document.attachEvent("onmousemove", performDrag);
        document.attachEvent("onmouseup", removeDraggable);
    } else {
        document.addEventListener("mousemove", performDrag, true);
        document.addEventListener("mouseup", removeDraggable, true);
    }

    // Cancel the event so this is the only funciton that handles it
    cancelEvent(event);
}

// Performs the action of dragging the stored element
function performDrag(event) {
    // Make sure we have a valid element
    if (!g_objDragController.dragElement || !g_objDragController.dragElement.style) { return; }

    // get the new mouse position
    var x, y;
    var bIsIE = false;
    if (document.attachEvent) {
        // Handle the IE version of this method
        x = window.event.clientX;
        y = window.event.clientY;
        bIsIE = true;
    } else {
        // Handle the Netscape/Firefox version of this method
        x = event.clientX;
        y = event.clientY;
    }

    // Move the element by the same pixels the mouse has moved
    g_objDragController.dragElement.style.left = (g_objDragController.elementStartLeft + x + windowState.getScrollX() - g_objDragController.cursorStartX) + "px";
    g_objDragController.dragElement.style.top = (g_objDragController.elementStartTop + y + windowState.getScrollY() - g_objDragController.cursorStartY) + "px";

    // Cancel the event
    cancelEvent(event);
}
    
// Performs the action of stopping the drag actions and resetting member variables
function removeDraggable(event) {
    // Make sure we have a valid element
    if (!g_objDragController.dragElement || !g_objDragController.dragElement.style) { return; }

    if (document.detachEvent) {
        // Handle the IE version of this method
        document.detachEvent("onmousemove", performDrag);
        document.detachEvent("onmouseup", removeDraggable);
    } else {
        // Handle the Netscape/Firefox version of this method
        document.removeEventListener("mousemove", performDrag, true);
        document.removeEventListener("mouseup", removeDraggable, true);
    }

    // Reset the member elements
    g_objDragController.dragElement = null;
    g_objDragController.cursorStartX = 0;
    g_objDragController.cursorStartY = 0;
    g_objDragController.elementStartLeft = 0;
    g_objDragController.elementStartTop = 0;
}

// ------------ Delimited Item Input Functions ------------ //
// Removes an existing item from a delimited form
function DelimitedForm_RemoveItem(elementID, itemValue, hiddenElementID, listElementID) {
    // Parameters:
    //      elementID = the ID for the element that houses the item
    //      itemValue = the text value for the element to remove from the hidden input
    //      hiddenElementID = the ID for the hidden element that contains all the values as a delimited string
    //      listElementID = the ID for the parent list that contains all the items (so we can remove the element)

    // Make sure the parameters are valid
    if (!elementID || !itemValue || !hiddenElementID || !listElementID) { return; }

    // Get the objects
    var objElement = getElement(elementID);
    var objHiddenElement = getElement(hiddenElementID);
    var objListElement = getElement(listElementID);

    // Make sure we have objects
    if (!objElement || !objHiddenElement || !objListElement) { return; }

    // Get rid of the element
    objListElement.removeChild(objElement);

    // Remove the value from the hidden element
    var szValues = getValue(objHiddenElement);
    if (!szValues) { return; } // we don't have a value anyway, so nothing to remove

    szValues = szValues.replace(itemValue, "").replace("||", "|"); // remove the value, and then remove any multiple delimiters are created
    setValue(objHiddenElement, szValues);

    // All set
    return;
}
// This function handles monitoring the input form for a completed item and adds it to the hidden value
function DelimitedForm_AddItem(event, elementID, hiddenElementID, listElementID, errorMsgID, disablePriceUpdate) {
    // Parameters:
    //      event = the event code for the keydown event that this function should have been assigned to [Default Value: null]
    //      elementID = the ID for the input element that new items are entered into
    //      hiddenElementID = the ID for the hidden element that valid items are moved into
    //      listElementID = the ID for the parent list that contains all the items (so we can add the completed item element)
    //      errorMsgID = the ID for the element to show if the value in the elementID is not valid [OPTIONAL]
    //      disablePriceUpdate = indicates if the onclick that removes the new item should NOT contain the javascript to update price [OPTIONAL]
    //  Returns:
    //      true = if the key is NOT handled by this function, in other words, if the key is not a delimiter
    //      false = the key is a delimiter was handled by this function (item is added, and processing should stop on the function that called this function)

    // Return parameter
    var bReturnValue = true;

    // Make sure the parameters are valid
    if (!elementID || !hiddenElementID || !listElementID) { return bReturnValue; }
    var objElement = getElement(elementID);

    // Make sure this event code key matches a delimiter
    if (event) {
        var keyCode = 0;
        if (window.event) keyCode = event.keyCode;
        else if (event.which) keyCode = event.which;
        else return bReturnValue;

        //      return          spacebar            comma         semicolon
        if (keyCode == 13 || keyCode == 32 || keyCode == 188 || keyCode == 186) {
            keyCode = keyCode; // just empty line, I like using || instead of &&, so this is needed for that
        } else {
            // this doesn't match the key codes we use for delimits, stop processing
            return bReturnValue;
        }
    }  // if we don't have an event, we assume this is being called manually and we'll add regardless

    // We don't allow entry of delimiters
    bReturnValue = false;

    // We have a valid delimiter -- get the objects
    var objHiddenElement = getElement(hiddenElementID);
    var objListElement = getElement(listElementID);

    // Make sure we have objects
    if (!objElement || !objHiddenElement || !objListElement) { return bReturnValue; }

    // Get the value
    var szNewValue = trim(getValue(objElement));
    if (!szNewValue) { return bReturnValue; }

    // Remove the http or https from the domain (in case they entered a URL)
    var nIndex = szNewValue.indexOf('://', 0);
    if (nIndex > -1) {
        // They entered a URL, not a domain
        if (szNewValue.length > nIndex + 3) {
            szNewValue = szNewValue.substr(nIndex + 3);
        } else { szNewValue = ""; }
    }

    // Remove the directory from the domain
    nIndex = szNewValue.indexOf("/", 0);
    if (nIndex > -1) {
        if (nIndex > 0) {
            szNewValue = szNewValue.substr(0, nIndex);
        } else { szNewValue = ""; }
    }

    // Remove the query string, if there is one
    nIndex = szNewValue.indexOf("?", 0);
    if (nIndex > -1) {
        if (nIndex > 0) {
            szNewValue = szNewValue.substr(0, nIndex);
        } else { szNewValue = ""; }
    }

    // Remove the leading www
    nIndex = szNewValue.indexOf("www.", 0);
    if (nIndex > -1) {
        if (szNewValue.length > nIndex + 4) {
            szNewValue = szNewValue.substr(nIndex + 4);
        } else { szNewValue = ""; }
    }

    // Make sure the domain doesn't start with a period
    if (szNewValue.length > 0 && szNewValue.substr(0, 1) == ".") {
        szNewValue = "";
    }

    // Make sure there is a period for the domain
    if (!szNewValue || szNewValue.indexOf(".", 0) < 0) {
        // This domain is not valid
        if (arguments.length > 4 && errorMsgID) {
            // Show the error message
            showElement_NoFade(errorMsgID);
        }

        // We can't process this domain
        return bReturnValue;
    }

    // Update the value of the hidden element
    if (szNewValue.toUpperCase() != "LOCALHOST" && szNewValue != "127.0.0.1") {
        var szDelimitedValue = getValue(objHiddenElement);

        // Make sure the value does not already exist
        if (szDelimitedValue == szNewValue || szDelimitedValue.indexOf(szNewValue + "|", 0) > -1) {
            setValue(objElement, "");
            return bReturnValue;
        }
        
        if (szDelimitedValue) { szDelimitedValue += "|"; }
        szDelimitedValue += szNewValue;
        setValue(objHiddenElement, szDelimitedValue);

        // Clear the input
        setValue(objElement, "");
    }

    // Get the element ID for the new item
    var szNewItemID = new Date().getTime();
    
    // Create the onclick value: DelimitedForm_RemoveItem(elementID, itemValue, hiddenElementID, listElementID)
    var szNewItemClick =
        "DelimitedForm_RemoveItem(&quot;" + szNewItemID + "&quot;,&quot;" +
        escape(szNewValue) + "&quot;,&quot;" + escape(hiddenElementID) + "&quot;,&quot;" +
        escape(listElementID) + "&quot;); ";
    if (arguments.length < 6 || !disablePriceUpdate) {
        // auto-update price by default
        szNewItemClick += "Checkout_UpdateGoogleMiniPrice(&quot;googleMini_buy_price&quot;,&quot;" + hiddenElementID + "&quot;,895); ";
    }
    szNewItemClick += "focusElement(getElement(&quot;" + elementID + "&quot;)); return false;";
        
    // Get the list HTML so we can insert the new item
    var szListHTML = getInnerHTML(objListElement);
        
    // Create the new element
    var szNewElement = "";

    var bIsIE = false;
    if (navigator.appName && navigator.appName.toLowerCase().indexOf("microsoft") > -1) {
        bIsIE = true;
    }
    
    if (bIsIE) {
        // Get the new element input for IE
        szNewElement =
            '<LI class=delimitedForm_CompletedItem id=' + szNewItemID + '>' +
                '<SPAN>' + szNewValue + '</SPAN>' +
                '<A onclick=\'' + szNewItemClick + '\' href="#">' +
                    '<IMG class=delimitedForm_RemoveItem title="remove domain" alt="remove domain" src="/images/icon_deleteContact.png" border=0>' +
                '</A>' +
            '</LI>';
        
        // Insert the new item
        szListHTML = szListHTML.replace("<LI class=delimitedForm_Container", szNewElement + "<LI class=delimitedForm_Container");
    } else {
        // Get the new element input for Firefox
        szNewElement =
            '<li class="delimitedForm_CompletedItem" id="' + szNewItemID + '">' +
                '<span>' + szNewValue + '</span>' +
                '<a onclick="' + szNewItemClick + '" href="#">' +
                '<img class="delimitedForm_RemoveItem" title="remove domain" alt="remove domain" src="/images/icon_deleteContact.png" border="0">' +
                '</a>' +
            '</li>';

        // Insert the new item
        szListHTML = szListHTML.replace('<li id="domainList_InsertNewItem"', szNewElement + '<li id="domainList_InsertNewItem"');
    }

    // Update the list HTML
    setInnerHTML(objListElement, szListHTML);
    
    
    /* This method doesn't work for IE, when rendered to the page it doesn't display properly [it does work for Firefox]
    var objNewItem = document.createElement("li");
    var szNewItemID = new Date().getTime();
    objNewItem.setAttribute("id", szNewItemID);
    objNewItem.setAttribute("class", "delimitedForm_CompletedItem");

    // Create the span tag
    var objTag = document.createElement("span");
    objTag.appendChild(document.createTextNode(szNewValue));

    objNewItem.appendChild(objTag);

    // Create the onclick value: DelimitedForm_RemoveItem(elementID, itemValue, hiddenElementID, listElementID)
    var szNewItemClick =
            "DelimitedForm_RemoveItem('" + szNewItemID + "','" +
            escape(szNewValue) + "','" + escape(hiddenElementID) + "','" +
            escape(listElementID) + "'); return false;";

    // Create the anchor tag
    objTag = document.createElement("a");
    objTag.setAttribute("href", "#");
    objTag.setAttribute("onclick", szNewItemClick);

    // Create the image element
    var objImageTag = document.createElement("img");
    objImageTag.setAttribute("class", "delimitedForm_RemoveItem");
    objImageTag.setAttribute("border", "0");
    objImageTag.setAttribute("src", "/images/icon_deleteContact.png");
    objImageTag.setAttribute("title", "remove domain");
    objImageTag.setAttribute("alt", "remove domain");

    // Add the image to the anchor tag
    objTag.appendChild(objImageTag);

    objNewItem.appendChild(objTag);
    
    // Add the new item to the list
    objListElement.insertBefore(objNewItem, objElement.parentNode);
    */

    // Focus the element again (it'll lose focus when we update its inner HTML)
    setTimeout(function() { getElement(elementID).style.width = '1px'; }, 100);
    if (event) {
        // If this was called because of a keydown command, we'll focus back to the element
        setTimeout(function() { focusElement(getElement(elementID)); }, 110);
    }

    // Stop the propagation of the event (we don't want someone hitting enter to submit a list element and then also submit the form)
    cancelEvent(event);

    // All set
    return bReturnValue;
}
// This function handles caclulating the size of the entered text and resizing the delimited input field to accomodate
function DelimitedForm_ResizeInput(elementID) {
    // Parameters:
    //      elementID = the ID for the input element that new items are entered into

    // Make sure the parameters are valid
    if (!elementID) { return; }

    // Get the objects
    var objElement = getElement(elementID);
    if (!objElement) { return; }

    // Resize the object (8 pixels per character, plus 20 pixel padding)
    var nWidth = getValue(objElement).length * 8;
    nWidth += 20;
    objElement.style.width = nWidth + 'px';
}

// -------------- Same Window Popup Functions ------------- //
// Closes an open popup
function Popup_Close() {
    // Hide the popup and fader
    hideElement_NoFade('hideshow');
}
// Shows the default loading message
function Popup_ShowLoading(messageID) {
    // Parameters:
    //      messageID = the identifier for the same window popup content <div>

    // Make sure we have a messageID
    if (!messageID) { messageID = "popup_block_content"; }
    
    // Make sure we have the content div
    var szContentDivId = "aspnetForm";
    var objContent = getElement(szContentDivId);
    if (!objContent) { return; }

    // Load the loading image
    var imgLoad = new Image();
    imgLoad.src = "/images/loading.gif";

    // Create the popup
    var szPopupDivId = "hideshow";
    var szInvisibleContentId = "popup_box_sizer_content";
    var szLoadingHTML =
        '<div id="fade" onclick="Popup_Close(); return false;"></div>' +
        '<div id="popup_box" class="popup_block" onmousedown="makeDraggable(event,this);">' +
            '<div id="' + messageID + '" class="popup"><center><img src="/images/loading.gif" alt="Loading..." title="Loading..." /></center></div>' +
        '</div>' +
        '<div id="popup_box_sizer" class="popup_block" style="visibility:hidden; width:500px; height:auto;">' +
            '<div id="' + szInvisibleContentId + '" class="popup">&nbsp;</div>' +
        '</div>';
    var objPopup = getElementOrCreate(objContent, szPopupDivId, '<div id="' + szPopupDivId + '" class="ghost">' + szLoadingHTML + '</div>', false);
    if (!objPopup) { return; }

    // Update the loading message
    setInnerHTML(objPopup, szLoadingHTML);
    objPopup.style.width = 80;
    objPopup.className = 'ghost';

    // Show the element
    showElement_NoFade(szPopupDivId);
    showMessage_Centered("popup_box");
}
// Gets a same window popup using AJAX
function Popup_GetMessage(messageID) {
    // Parameters:
    //      messageID = the identifier for the same window popup to get HTML for

    // Check the parameters
    if (!messageID) { return; }

    // Show the loading message
    Popup_ShowLoading(messageID);
    
    // Get the actual message
    var szAjaxRequest =
        g_szAjaxFile + "cmd=site_popup&m=" + escape(messageID);

    // Get additional parameters
    if (arguments.length > 1) {
        szAjaxRequest += arguments[1];
    }
        
    szAjaxRequest += "&a=" + getRandomString(25);

    // Create an ajax object
    g_objAjax.AjaxRequest(szAjaxRequest);

    // All set, the AJAX call will automatically close the loading image
}
// Shows a message in the center content and animates the expansion
function Popup_ShowMessage(messageID, messageContent) {
    // Parameters:
    //      messageID = the identifier for the same window popup to show
    //      messageContent = the HTML to load into the same window popup

    // Working variables
    var divWidth = 0;
    var divHeight = 0;

    // Load the content into the invisible place holder to get the size
    var szInvisibleContentId = "popup_box_sizer_content";
    var objInvisContent = getElement(szInvisibleContentId);
    if (!objInvisContent) { nDivWidth = 480; }
    else {
        // Update the invisible content
        setInnerHTML(objInvisContent, messageContent);

        divWidth = 0;
        if (objInvisContent.offsetWidth) { divWidth = objInvisContent.offsetWidth; }
        else if (objInvisContent.style.width) { divWidth = objInvisContent.style.width.replace('px', ''); }

        divHeight = 0;
        if (objInvisContent.offsetHeight) { divHeight = objInvisContent.offsetHeight; }
        else if (objInvisContent.style.height) { divHeight = objInvisContent.style.height.replace('px', ''); }
    }

    // We're done loading
    setInnerHTML(getElement(unescape(messageID)), "&nbsp;");

    // Resize the div
    var i = 0;
    i = Popup_ExpandDiv(messageID, divWidth, divHeight);

    // Move the popup to the center
    setTimeout('centerElement("popup_box", ' + divWidth + ', ' + divHeight + ')', 10);

    // Update the element
    setTimeout("setInnerHTML(getElement(unescape('" + messageID + "')), '" + messageContent + "')", i);

    // Update the div height to auto
    setTimeout("getElement(unescape('" + messageID + "')).style.height = 'auto';", i + 150);
}
// Animates a popup expansion
function Popup_ExpandDiv(messageID, divWidth, divHeight) {
    // Parameters:
    //      messageID = the identifier for the same window popup to resize
    //      divWidth = the new width for the div
    //      divHeight = the new height for the div [Default value = 0, which will default to auto]

    // Get the popup
    var objPopup = getElement("popup_box");
    if (!objPopup || !objPopup.style) { return; }
    objPopup.style.width = 'auto';
    objPopup.style.height = 'auto';
    
    // Get the message
    if (!messageID) { return; }
    var objMessage = getElement(messageID);
    if (!objMessage || !objMessage.style) { return; }

    // Get the current div width and height
    var messageWidth = 0;
    if (objMessage.offsetWidth) { messageWidth = objMessage.offsetWidth; }
    else if (objMessage.style.width) { messageWidth = objMessage.style.width.replace('px', ''); }

    var messageHeight = 0;
    if (objMessage.offsetHeight) { messageHeight = objMessage.offsetHeight; }
    else if (objMessage.style.height) { messageHeight = objMessage.style.height.replace('px', ''); }

    // Get the containing popup div width and height
    var popupWidth = 0;
    if (objPopup.offsetWidth) { popupWidth = objPopup.offsetWidth; }
    else if (objPopup.style.width) { popupWidth = objPopup.style.width.replace('px', ''); }

    var popupHeight = 0;
    if (objPopup.offsetHeight) { popupHeight = objPopup.offsetHeight; }
    else if (objPopup.style.height) { popupHeight = objPopup.style.height.replace('px', ''); }

    // Animate the resizing
    var duration = 90; // duration between EACH step
    var j = 0;
    var steps = 14; // number of resize intervals
    var i = 0;
    var incrementWidth = Math.floor((divWidth - messageWidth) / steps);
    var incrementHeight = Math.floor((divHeight - messageHeight) / steps);
    var incrementTimeout = (1 / steps);

    // Resize the message
    for(i = 0; i <= steps; i += 1)
    {
        messageWidth += incrementWidth;
        messageHeight += incrementHeight;
        if (messageWidth > divWidth) { messageWidth = divWidth; }
        if (messageHeight > divHeight) { messageHeight = divHeight; }
        
        popupWidth += incrementWidth;
        popupHeight += incrementHeight;

        // Resize the content div
        setTimeout("resizeElement('" + escape(messageID) + "', " + messageWidth + ", " + messageHeight + ")", j * duration);
        j += incrementTimeout;
    }

    // Completely resize the element
    setTimeout("resizeElement('" + escape(messageID) + "', " + divWidth + ", " + divHeight + ")", j * duration);
    
    // Return the amount of time it'll take for all timeouts to complete
    return j * duration;
}
// Submits a form using POST from a popup
function Popup_SubmitForm() {
    // Parameters:
    //      arguments[0] = the form name
    //      arguments[1] = the loading text
    //      arguments[1..n] = the form input elements

    // Make sure we have arguments
    if (arguments.length < 3) { return false; }

    // Get the form name
    var szFormName = arguments[0];
    var szPostData = "";

    // Make sure the form is valid
    var i = 0;
    var nLength = arguments.length;
    var bValid = true;
    var szValue = "";
    for (i = 2; i < nLength; i++) {
        // Get the next argument
        szValue = arguments[i];
        if (!szValue) { continue; }
        
        // Make sure the argument is not data that will be added directly to the post (as opposed to an elementID which is what we expect by default)
        if (szValue.substr(0, 1) == "&") {
            szPostData += szValue;
            continue;
        }

        // Make sure the element is valid
        if (checkElement(szValue, true)) {
            // Add the post data
            szPostData += "&" + szValue + "=" + escape( getValue(getElement(szValue)) );
        } else {
            bValid = false;
        }
    }

    if (!bValid) { return false; }

    // Show the status message
    var szStatusMsgId = szFormName + "-status";
    var objStatus = getElement(szStatusMsgId);
    if (objStatus) {
        // This doesn't contain a status message
        setInnerHTML(objStatus, '<label>&nbsp;</label><span class="statusmsg">' + arguments[1] + '</span>');

        // Show the status message
        showElement_NoFade(szStatusMsgId);
    }

    // Trim the post data
    szPostData = szPostData.substring(1);

    // Generate the Ajax Request String
    var szAjaxRequest =
        g_szAjaxFile + "cmd=popup_form&f=" + escape(szFormName) + "&a=" + getRandomString(25);

    // Create an ajax object
    g_objAjax.AjaxRequest_Post(szAjaxRequest, szPostData);

    // All set
    return true;
}
// Resizes the popup div
function Popup_Resize(popupWidth) {
    // Parameters:
    //      popupWidth = the width for the popup

    // Resize the popup sizer box
    var objPopup = getElement("popup_box_sizer");
    if (!objPopup || !objPopup.style) { return; }

    // Get the popup width
    var nPopupWidth = parseInt(popupWidth, 10);
    if (nPopupWidth && nPopupWidth > 0) { popupWidth = popupWidth + 'px'; }

    // Resize the popup
    objPopup.style.width = popupWidth;
}

// Resizes a Div
function resizeElement(elementID, elementWidth, elementHeight) {
    // Parameters:
    //      elementID = the identifier for the element to resize
    //      elementWidth = the new width for the element
    //      elementHeight = the new height for the element [Default value = 0, which will default to auto]

    // Check parameters
    if (!elementID) { return; }
    var objElement = getElement(unescape(elementID));
    if (!objElement || !objElement.style) { return; }

    // Resize div
    objElement.style.width = elementWidth + 'px';
    if (elementHeight < 1) {
        objElement.style.height = 'auto';
    } else { objElement.style.height = elementHeight + 'px'; }

    // All set
    return;
}

// -------------- Regular Functions ------------- //

// Checks an element to see if it is populated
function checkElement(elementID, setFocus) {
    // Parameters:
    //		elementID = the ID of the <input> to validate
    //		setFocus = indicates if we should set the focus on the element as well

    // Make sure parameters are valid
    if (!elementID) { return; }
    
    // Return variable
    var bValid = true; 
    var bRegexValid = true;
    
    // Validate the object
    var objElement = getElement(elementID);
    // Make sure this isn't a checkbox
    if (objElement && !objElement.checked) {
        // Check if the element has a value
        var szValue = getValue(objElement);
        bValid = szValue && szValue.length && szValue.length >= 1;

        // Check if the element has options
        if (bValid && objElement.options && objElement.selectedIndex == 0) {
            bValid = false;
        }

        // Check for a regex match
        if (bValid) {
            var objRegexValidator = getElement(elementID + "-rev");
            var szRegex = getAttribute(objRegexValidator, "name");
            if (objRegexValidator && szRegex && szRegex.length && szRegex.length >= 1) {
                var regex = new RegExp(szRegex);
                bValid = regex.test(szValue);
                bRegexValid = bValid;
            } else { bValid = true; }
        }
    }

    // Make sure we have validators to show
    var objRFV = getElement(elementID + "-rfv");
    var objREV = getElement(elementID + "-rev");

    // Check if we were valid or not
    if (objRFV || objREV) {
        if (bValid) {
            // Hide regular expressions
            hideElement_NoFade(elementID + "-rfv");
            hideElement_NoFade(elementID + "-rev");
        }
        else {
            if (bRegexValid) {
                showElement_NoFade(elementID + "-rfv");
                // hide the regular expression validator
                hideElement_NoFade(elementID + "-rev");
            }
            else {
                showElement_NoFade(elementID + "-rev");
                // hide the required field validator
                hideElement_NoFade(elementID + "-rfv");
            }

            // Check if we should focus
            if (arguments.length > 1 && setFocus) {
                focusElement(objElement);
            }
        }
    } else { bValid = true; }

    // Return the validity
    return bValid;
}

// Sets the focus on an element
function focusElement(objElement) {
    // Parameters:
    //      objElement = the object to set the focus on
    if (!objElement || objElement.disabled || !objElement.focus) {
        return;
    }

    // Focus the element
    try {
        objElement.focus();
    } catch (err) { return; }
}

// Checks if a user submits a form by pressing enter
function checkSubmitForm(e) {
    var keyCode = 0;
    if (window.event) keyCode = e.keyCode;
    else if (e.which) keyCode = e.which;
    if (keyCode == 13) return true;
    return false;
}

// Changes tabs on a page
function Site_ChangeTab(tabPrefix, linkPrefix, activeTab, totalTabs, activeClass, inactiveClass, imagePrefix) {
    // Parameters:
    //      tabPrefix = the prefix for the tab IDs
    //      linkPrefix = the prefix for the Link element used to change tabs
    //      activeTab = the integer for the tab to make active
    //      totalTabs = the integer for the total number of tabs
    //      activeClass = the CSS class to assign to the active tab
    //      inactiveClass = the CSS class to assign to the inactive tab (default value: empty string);
    //      imagePrefix = the prefix for the tab image IDs (optional)

    // Make sure the parameters are valid
    if (!tabPrefix || !linkPrefix || !activeClass) { return; }
    
    activeTab = parseInt(activeTab, 10);
    if (!activeTab || activeTab < 1) { return; }

    totalTabs = parseInt(totalTabs, 10);
    if (!totalTabs || totalTabs < 1) { return; }

    // Check if we are also handling images
    var bImages = false;
    if (arguments.length > 6 && imagePrefix) {
        bImages = true;
    }

    // Hide all tabs
    var i = 1; var objLink = null;
    for (i = 1; i <= totalTabs; i++) {
        // Hide the tab
        hideElement_NoFade(tabPrefix + i.toString());

        // Hide the link element for the tab
        changeClass(linkPrefix + i.toString(), inactiveClass);

        // Check if we need to hide images
        if (bImages) {
            hideElement_NoFade(imagePrefix + i.toString());
        }
    }

    // Show the active tab
    showElement_NoFade(tabPrefix + activeTab.toString());

    // Show the link element for the active tab
    changeClass(linkPrefix + activeTab.toString(), activeClass);
    
    // Show the tab image
    if (bImages) {
        showElement_NoFade(imagePrefix + activeTab.toString());
    }
}

// Redirects to the search page
function Site_Search(searchPage, searchTextBoxID) {
    // Parameters:
    //      searchPage = the search page
    //      searchTextBoxID = the search textbox elementID
    
    // Make sure parameters are valid
    if (!searchPage) { return; }

    // Working variables
    var searchQuery = "";
    if (searchTextBoxID) { searchQuery = getValue(getElement(searchTextBoxID)); }

    // Redirect
    window.location = searchPage + escape(searchQuery);
}

// Checks if an array of input elements is valid
function Site_Validate(arrayElementIDs, setFocus) {
    // Parameters:
    //      arrayElementIDs = an array of IDs of the <input> and <select> tags to validate input for
    //      setFocus = indicates if we should set the focus to the input tags if they are not valid

    // Make sure the parameters are valid
    if (!arrayElementIDs) { return; }

    // Loop through the array
    var bValid = true;
    var nArrayLength = arrayElementIDs.length;
    for (var i = 0; i < nArrayLength; i++) {
        if (!checkElement(arrayElementIDs[i], setFocus)) {
            bValid = false;
        }
    }

    // These are fine
    return bValid;
}

// Disables a dropdown and shows the supplied message
function disableDropDown(dropDownID, disabledMessage) {
    // Parameters:
    //      dropDownID = the ID of the <select> tag to disable
    //      disabledMessage = the message to show in the dropdown box showing this item has been disabled

    // Makes sure the parameters are valid
    if (!dropDownID || !disabledMessage) { return; }

    // Get the objects
    var objDropDown = getElement(dropDownID);
    if (!objDropDown) { return; }

    // Create the value
    var szValue = "-1~" + escape(unescape(disabledMessage));

    // Update the dropdown
    populateDropDown(objDropDown, szValue);
    objDropDown.disabled = true;
}

// Clears a dropdown of all its entries
function clearDropDown(objDropDown) {
    if (!objDropDown || !objDropDown.length || !objDropDown.options) {
        return;
    }

    for (var j = objDropDown.length; j >= 0; j--) {
        objDropDown.options[j] = null;
    }
}

// Populates a dropdown using a string with format Value~Name|Value2~Name2|Value3~Name3
function populateDropDown(objDropDown, _delimitedString) {
    if (!_delimitedString || !objDropDown) {
        return;
    }
    // Split the response (Value~Name|Value~Name|Value~Name) up into the individual brands
    var a_AllItems = _delimitedString.split('|');
    if (!a_AllItems || !a_AllItems.length) {
        // Unable to parse the delimited string
        return;
    }

    // Clear the dropDown
    clearDropDown(objDropDown);
    objDropDown.disabled = false;

    // Add the new values
    for (var i = 0; i < a_AllItems.length; i++) {
        // Make sure this row has information
        if (!a_AllItems[i]) {
            continue;
        }

        // Split up the Value~Name into individual elements
        var a_ItemInfo = a_AllItems[i].split('~');
        if (a_ItemInfo.length < 2) {
            continue;
        }

        // Create a new option element for the dropdown
        var objDropDownOption = document.createElement("option");

        // Add the value to the drop down option
        if (a_ItemInfo[0]) { objDropDownOption.setAttribute('value', unescape(a_ItemInfo[0])); }
        else { objDropDownOption.setAttribute('value', ''); }

        // Add the text to the drop down option
        objDropDownOption.appendChild(document.createTextNode(unescape(a_ItemInfo[1])));

        // Append the new option to the dropdown
        objDropDown.appendChild(objDropDownOption);
    }
}

// Removes leading whitespaces
function LTrim(value) {
    if (!value || !value.replace) { return value; }
    var re = /\s*((\S+\s*)*)/;
    return value.replace(re, "$1");
}

// Removes ending whitespaces
function RTrim(value) {
    if (!value || !value.replace) { return value; }
    var re = /((\s*\S+)*)\s*/;
    return value.replace(re, "$1");
}

// Removes leading and ending whitespaces
function trim( value ) {
	if(!value || !value.replace) { return value; }
	return LTrim(RTrim(value));
}

// Preloads an array of images
function preloadImages(imageArray) {
    // Parameters:
    //      imageArray = the array of image URLs to load

    // Make sure the parameter is valid
    if (!imageArray || !imageArray.length) { return; }

    // Pre-load the images
    var objImage = new Image();
    var nSourceCount = imageArray.length;

    for (var i = 0; i < nSourceCount; i++) {
        // load the new image
        objImage.src = imageArray[nSourceCount];
    }
}

// Generates a random string of characters and numbers
function getRandomString(lengthCount) {
    // Parameters:
    //      lengthCount = the number of characters for the random string

    // Make sure the parameter is valid
    lengthCount = parseInt(lengthCount, 10);
    if (!lengthCount || lengthCount < 1) { return ''; }
    
    // Create the random string
    var szRandomString = '';
    var aCharacterValues = ['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', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    var nLength = aCharacterValues.length;
    var nRandomNum = 0;

    for (var i = 0; i < lengthCount; i++) {
        nRandomNum = Math.floor(Math.random() * nLength);
        szRandomString = szRandomString + aCharacterValues[nRandomNum];
    }

    // Return the random string
    return szRandomString;
}

// Gets an element by it's id on the page
function getElement(id) {
    var returnVar = null;
    
    // Get the element
    if (document.getElementById) {
        returnVar = document.getElementById(id);
    }
    else if (document.all) {
        returnVar = document.all[id];
    }
    else if (document.layers) {
        returnVar = document.layers[id];
    }

    // If we don't have an element, check for a parent window
    try
    {
        if (!returnVar && window && window.parent && window.parent.document) {
            // get the element from the parent document
            if (window.parent.document.getElementById) {
                returnVar = window.parent.document.getElementById(id);
            }
            else if (window.parent.document.all) {
                returnVar = window.parent.document.all[id];
            }
            else if (window.parent.document.layers) {
                returnVar = window.parent.document.layers[id];
            }
        }
    } catch (err) { returnVar = null; }
    
    return returnVar;
}

// This function creates an existing tag if it does not already exist on the page
function getElementOrCreate(objParent, elementID, elementTemplate, createOnTop) {
    // Parameters:
    //      objParent = the parent object for the element. This is only needed if we have to create the element.
    //      elementID = the ID for the element to get or create
    //      elementTemplate = the default value for the element if it does not already exist
    //      createOnTop = indicates if the element should be created above all the existing XHTML in the parent, or below it

    // Make sure the parameters are valid
    if (arguments.length < 4 || !elementID) { return null; }

    // Check if the element already exists
    elementID = unescape(elementID);
    var objElement = getElement(elementID);
    if (objElement) { return objElement; }

    // Create the element
    if (!objParent || !elementTemplate || typeof (objParent.innerHTML) == undefined) { return null; }
    if (createOnTop) {
        objParent.innerHTML = elementTemplate + objParent.innerHTML;
    } else {
        objParent.innerHTML = objParent.innerHTML + elementTemplate;
    }

    // Now get the element again, since we know it has been created
    return getElement(elementID);
}

// This function gets the value of the supplied element
function getValue(objElement) {
    // Parameters:
    //		objElement = the element to get the value for

    // Make sure the object is valid
    if (!objElement) { return ""; }

    // Get the value
    var szValue = trim(objElement.value);
    if (szValue.toUpperCase() == "ON" && !objElement.checked) {
        szValue = "";
    }

    // Return the value of the object
    return szValue;
}

// This function gets an elements attribute
function getAttribute(objElement, attributeName) {
    // Parameters:
    //		objElement = the element to get the value for
    //      attributeName = the name of the attribute to retrieve

    // Make sure the object is valid
    if (!objElement) { return ""; }

    // Get the attributes
    var aAttribs = objElement.attributes;
    if (!aAttribs || !aAttribs.length || aAttribs.length == 0) { return; }
    
    // Get the attribute value
    var i = 0;
    var attribLength = aAttribs.length;
    for (i = 0; i < attribLength; i++) {
        if (aAttribs[i].name == attributeName) {
            // Found it
            return aAttribs[i].value;
        }
    }

    // Couldn't find the attribute
    return "";
}

// This function sets the value of an element
function setValue(objElement, value) {
    // Parameters:
    //		objElement = the element to set the value for
    //		value = the value to set

    // Make sure we have valid parameters
    if (!objElement || typeof (value) == undefined) { return; }
    
    // Unescape the value
    value = unescape(value);

    // Set the value of the object
    objElement.value = value;
}

function getInnerHTML(objElement) {
    // Parameters:
    //		objElement = the element to get the value for

    // Make sure the object is valid
    if (!objElement) { return ""; }

    // Return the value of the object
    return trim(objElement.innerHTML);
}

// This function sets the innerHTML value of an element
function setInnerHTML(objElement, innerHTML) {
    // Parameters:
    //		objElement = the element to set the value for
    //		innerHTML = the new innerHTML value of the element

    // Make sure we have valid parameters
    if (!objElement || typeof (innerHTML) == undefined) { return; }
    innerHTML = unescape(innerHTML);

    // Step 2.  Set the value of the object
    objElement.innerHTML = innerHTML;
}

// This function gets the width for an element
function getWidth(objElement) {
    // Parameters:
    //      objElement = the object to get the width for

    // Make sure the parameters are valid
    if (!objElement) { return 0; }

    var elementWidth = 0;
    if (objElement.offsetWidth) { elementWidth = objElement.offsetWidth; }
    else if (objElement.style && objElement.style.width) { elementWidth = objElement.style.width.replace('px', ''); }

    // All set
    return elementWidth;
}

// This function directly hides an element (no fading)
function hideElement_NoFade(_elementID) {
    // Parameters:
    //		_elementID = the ID of the element to hide

    // Make sure we have valid parameters
    if (!_elementID) { return; }
    _elementID = unescape(_elementID);
    
    // Cancel existing opacity changes
    cancelOpacity(_elementID);

    // Get the object
    var objElement = getElement(_elementID);

    // Make sure we have valid objects
    if (!objElement || !objElement.style) { return false; }

    // Hide the element
    objElement.style.display = 'none';
    return true;
}

// This function hides an element on the page using its ID
function hideElement(_elementID) {
    // Parameters:
    //		_elementID = the ID of the element to hide

    // Make sure we have valid parameters
    if (!_elementID) { return; }
    _elementID = unescape(_elementID);

    // Cancel existing opacity changes
    cancelOpacity(_elementID);

    // Create the opacity object
    var objOpacity = new Object();
    objOpacity.elementID = _elementID.toUpperCase();
    objOpacity.timeoutArray = new Array();

    // Get the object
    var objElement = getElement(_elementID);

    // Make sure we have valid objects and that they are not already hidden
    if (!objElement || !objElement.style || objElement.style.display == 'none') { return; }

    // Fade the element
    var duration = 800; // 800 milliseconds
    var steps = 20; // number of opacity intervals
    var i = 0;
    for (i = 0; i <= 1; i += (1 / steps)) {
        // opacity levels are between 0 and 1
        objOpacity.timeoutArray.push(setTimeout("setOpacity('" + escape(_elementID) + "', " + (1 - i) + ")", i * duration));
    }

    // Completely hide the element after the fade out is complete
    objOpacity.timeoutArray.push(setTimeout("hideElement_NoFade('" + escape(_elementID) + "')", i * duration));

    // Add the opacity object to the global element
    g_aOpacityTimeouts.push(objOpacity);

    // Return the duration it will take for this fade to be accomplished
    return i * duration;
}

// This function shows an element on the page
function showElement(_elementID) {
    // Parameters:
    //		_elementID = the ID of the element to show

    // Make sure we have valid parameters
    if (!_elementID) { return; }
    _elementID = unescape(_elementID);
    
    // Cancel existing opacity changes
    cancelOpacity(_elementID);

    // Create the opacity object
    var objOpacity = new Object();
    objOpacity.elementID = _elementID.toUpperCase();
    objOpacity.timeoutArray = new Array();

    // Get the object
    var objElement = getElement(_elementID);

    // Make sure we have valid objects
    if (!objElement || !objElement.style) { return; }

    // Fade the element
    var duration = 800; // 800 milliseconds
    var steps = 20; // number of opacity intervals
    var i = 0;
    for (i = 0; i <= 1; i += (1 / steps)) {
        // opacity levels are between 0 and 1
        objOpacity.timeoutArray.push(setTimeout("setOpacity('" + escape(_elementID) + "', " + i + ")", i * duration));
    }

    // Show the element as a block
    objOpacity.timeoutArray.push(setTimeout("showElement_NoFade('" + escape(_elementID) + "')", i * duration));

    // Add the opacity object to the global element
    g_aOpacityTimeouts.push(objOpacity);

    // Return the duration it will take for this fade to be accomplished
    return i * duration;
}

// This function shows an element on the page
function showElement_NoFade(_elementID) {
    // Parameters:
    //      _elementID = the ID of the element to show

    // Make sure the parameters are valid
    if (!_elementID) { return false; }
    _elementID = unescape(_elementID);
    // Cancel existing opacity changes
    cancelOpacity(_elementID);

    // Get the object
    var objElement = getElement(_elementID);
    if (!objElement || !objElement.style) { return false; }

    // Show the element
    objElement.style.display = 'block';
    
    // Update the opacity
    objElement.style.display = 'block';
    objElement.style.zoom = 1;
    objElement.style.opacity = null;
    objElement.style.MozOpacity = null;
    objElement.style.KhtmlOpacity = null;
    objElement.style.filter = null;

    // All set
    return true;
}

// This function hides an element after a certain array
function hideElementWithDelay(elementID, hideDelay) {
    // Parameters:
    //      elementID = the ID of the XHTML tag to hide
    //      delay = the delay in milliseconds

    // Make sure the parameters are valid
    if (!elementID) { return; }

    // Hide the element
    return setTimeout('hideElement("' + escape(elementID) + '")', hideDelay);
}

// This function sets the opactiy of an element
function setOpacity(elementID, opacityLevel) {
    // Parameters:
    //      elementID = the ID of the XHTML tag to set the opacity for
    //      opacityLevel = the opacity level as a value between 0 and 1

    // Make sure the parameters are valid
    if (!elementID) { return; }
    elementID = unescape(elementID);

    // Get the object
    var objElement = getElement(elementID);
    if (!objElement || !objElement.style) { return; }

    // Update the opacity
    objElement.style.display = 'block';
    objElement.style.zoom = 1;
    objElement.style.opacity = opacityLevel;
    objElement.style.MozOpacity = opacityLevel;
    objElement.style.KhtmlOpacity = opacityLevel;
    objElement.style.filter = "alpha(opacity=" + (opacityLevel * 100) + ");";
}

// This function cancels current opacity requests
var g_aOpacityTimeouts = new Array();
function cancelOpacity(_elementID) {
    // Parameters:
    //      elementID = the ID for the element to cancel the opacity modification for

    // Make sure the parameters are valid
    if (!_elementID) { return; }
    _elementID = _elementID.toUpperCase();

    // Find the element to cancel
    var objElement = null;

    var i = 0;
    var nElementIndex = 0;
    var nArrayLength = g_aOpacityTimeouts.length;
    for (i = 0; i < nArrayLength; i++) {
        objElement = g_aOpacityTimeouts[i];
        if (objElement.elementID && objElement.elementID == _elementID) {
            nElementIndex = i;
            break; // we found the element
        }
        objElement = null; // not the element we're looking for
    }

    // Make sure we have an element
    if (!objElement) { return; }

    // Remove all element timeouts
    if (objElement.timeoutArray) {
        nArrayLength = objElement.timeoutArray.length;
        for (i = 0; i < nArrayLength; i++) {
            clearTimeout(objElement.timeoutArray[i]);
        }
    }

    // Remove this element from the array
    objElement = null;
    g_aOpacityTimeouts[nElementIndex] = null;
    g_aOpacityTimeouts.splice(nElementIndex, 1);
}

// This function sets the onclick property for an element
function setOnClick(obj, functionName) {
    // Parameters:
    //      obj = the object to set the onclick property for
    //      functionName = the name of the function to call when the event occurs


    // DOM Standard way of add click event
    if (obj.addEventListener) {
        obj.addEventListener("click", functionName, false);
    }
    else if (obj.attachEvent) {
        // IE way of doing it
        obj.attachEvent("onclick", functionName);
    }
}

// This function cancels an event (it's called from the switchNavMode function
function cancelEvent(e) {
    // Parameters:
    //      e = the event to cancel


    // Step 1.  Make sure we have the event
    if (!e) {
        e = window.event;
        // Make sure we could get the event
        if (!e) { return; }
    }


    // Step 2.  Stop the event
    if (e.stopPropagation) { e.stopPropagation(); }
    if (e.preventDefault) { e.preventDefault(); }
    e.cancelBubble = true;
    e.cancel = true;
    e.returnValue = false;


    // Step 3.  All done
    return false;
}

// This function centers an element on the screen and fades in the display
function showMessage_Centered(elementID) {
    // Parameters:
    //      elementID = the ID of the XHTML tag to show

    // Make sure the parameters are valid
    if (!elementID) { return; }
    // Get the object
    var objElement = getElement(unescape(elementID));
    if (!objElement || !objElement.style) { return; }

    // Get the div size
    var divWidth = 0;
    if (objElement.offsetWidth) { divWidth = objElement.offsetWidth; }
    else if (objElement.style.width) { divWidth = objElement.style.width.replace('px', ''); }

    var divHeight = 0;
    if (objElement.offsetHeight) { divHeight = objElement.offsetHeight; }
    else if (objElement.style.height) { divHeight = objElement.style.height.replace('px', ''); }

    // Center the element
    centerElement(elementID, divWidth, divHeight);

    // Show the element
    showElement_NoFade(elementID);
}

// This function centers an element on the screen an element
function centerElement(elementID, elementWidth, elementHeight) {
    // Parameters:
    //      elementID = the ID of the XHTML tag to show
    //      elementWidth = the width to use to center the element
    //      elementHeight = the height to use to center the element

    // Make sure the parameters are valid
    if (!elementID || !elementWidth || !elementHeight) { return; }
    elementWidth = parseInt(elementWidth, 10);
    if (!elementWidth || elementWidth < 1) { return; }
    elementHeight = parseInt(elementHeight, 10);
    if (!elementHeight || elementHeight < 1) { return; }
    
    // Get the screen size
    var viewPortWidth = windowState.getWidth();
    var viewPortHeight = windowState.getHeight();
    var horizontalScroll = windowState.getScrollX();
    var verticalScroll = windowState.getScrollY();
    
    // Find the center
    var xAdd = Math.round(horizontalScroll + ((viewPortWidth - elementWidth) / 2));
    var yAdd = Math.round(verticalScroll + ((viewPortHeight - elementHeight) / 2));
    
    // Get the object
    var objElement = getElement(unescape(elementID));
    if (!objElement || !objElement.style) { return; }

    // Move the element to the center
    moveElement(elementID, xAdd, yAdd);
}

// This function moves an elemeent
function moveElement(elementID, xLocation, yLocation) {
    // Make sure the parameters are valid
    if (!elementID) { return; }
    var objElement = getElement(unescape(elementID));

    // Make sure we don't move an element beyond the border
    if (xLocation < 20) { xLocation = 20; }
    if (yLocation < 20) { yLocation = 20; }

    // Update the element
    objElement.style.left = xLocation + 'px';
    objElement.style.top = yLocation + 'px';
    objElement.style.position = 'absolute';
}

// This function saves a value to a cookie
function saveCookie(_cookieName, _cookieValue, _expMinutes) {
    // Parameters:
    //      _cookieName = the name of the cookie to save
    //      _cookieValue = the value for the cookie
    //      _expMinutes = the number of minutes before the cookie will expire


    // Step 1.  Make sure the parameters are valid
    if (!_cookieName) { return; }
    if (!_cookieValue || !_expMinutes) {
        // They want to remove the cookie
        removeCookie(_cookieName);
        return;
    }
    var nExpMinutes = parseInt(_expMinutes, 10);
    if (!nExpMinutes || nExpMinutes < 1) { removeCookie(_cookieName); return; }


    // Step 2.  Create the expiration date    
    var dtDate = new Date();
    dtDate.setTime(dtDate.getTime() + (nExpMinutes * 60 * 1000));


    // Step 3.  Make sure we don't have bad characters in the cookie value
    _cookieValue = escape(_cookieValue);


    // Step 4.  Save the cookie
    var szCookie = _cookieName + "=" + _cookieValue + "; expires=" + dtDate.toGMTString() + "; path=/";
    document.cookie = szCookie;
}

// This function removes a cookie
function removeCookie(_cookieName) {
    // Parameters:
    //      _cookieName = the name of the cookie to remove


    // Step 1.  Make sure the parameter is valid
    if (!_cookieName) { return; }


    // Step 2.  Create a date in the past to remove the cookie
    var dtDate = new Date();
    dtDate.setTime(dtDate.getTime() + (-1 * 24 * 60 * 60 * 1000));


    // Step 3.  Remove the cookie
    var szCookie = _cookieName + "=; expires=" + dtDate.toGMTString() + "; path=/";
    document.cookie = szCookie;
}

// This function gets a cookie value (default value: empty string)
function getCookieValue(_cookieName) {
    // Parameters:
    //      _cookieName = the name of the cookie to get the value from


    // Step 1.  Make sure the parameter is valid
    if (!_cookieName) { return ""; }


    // Step 2.  Get the cookie value
    if (document.cookie.length > 0) {
        var c_start = document.cookie.indexOf(_cookieName + "=");
        if (c_start != -1) {
            var c_start = c_start + _cookieName.length + 1;
            var c_end = document.cookie.indexOf(";", c_start);
            if (c_end == -1) c_end = document.cookie.length;
            return unescape(document.cookie.substring(c_start, c_end));
        }
    }
    return "";
}
// This function changes the class attribute on an object
function changeClass(_objID, _newClassname) {
    // Parameters:
    //      _objID = the ID of the XHTML tag to modify the class attribute on
    //      _newClassname = the new value for the class attribute

    // Make sure the parameters are valid
    if (!_objID) { return; }

    // Get the object
    var objElement = getElement(_objID);
    if (!objElement || objElement.className == _newClassname) { return; }

    // Update the class name
    objElement.className = _newClassname;
}

// -------------- AJAX Functions ------------- //
var g_szAjaxFile = "/aux_incl/ajax/default.aspx?";

// This is a global parameter used by the send e-mail function to perform AJAX calls
var g_objAjax = new BellwetherAjax(); // make sure the AJAX functions javascript is included before this file

// This function shows a status message, creating the object if it does not yet exist
function ShowStatusMessage(parentElementID, elementID, statusMessage) {
    // Paramaters:
    //      parentElementID = the ID of the parent tag to create the status message in (if it does not yet exist)
    //      elementID = the ID of the status message tag to show or create
    //      statusMessage = the new status message to show

    // Make sure the parameters are valid
    if (arguments.length < 3 || !parentElementID || !elementID) { return; }
    ShowStatusMessage_Common(parentElementID, elementID, statusMessage);

    // Show the message
    if (statusMessage) {
        showElement(elementID);
    } else {
        // We don't have a value, so hide the status message
        hideElement_NoFade(elementID);
    }
}

// This function shows a status message, creating the object if it does not yet exist
function ShowStatusMessage_NoFade(parentElementID, elementID, statusMessage) {
    // Paramaters:
    //      parentElementID = the ID of the parent tag to create the status message in (if it does not yet exist)
    //      elementID = the ID of the status message tag to show or create
    //      statusMessage = the new status message to show

    // Make sure the parameters are valid
    if (arguments.length < 3 || !parentElementID || !elementID) { return; }
    ShowStatusMessage_Common(parentElementID, elementID, statusMessage);

    // Show the message
    if (statusMessage) {
        showElement_NoFade(elementID);
    } else {
        // We don't have a value, so hide the status message
        hideElement_NoFade(elementID);
    }
}

// This function shows a status message, creating the object if it does not yet exist
function ShowStatusMessage_Common(parentElementID, elementID, statusMessage) {
    // Paramaters:
    //      parentElementID = the ID of the parent tag to create the status message in (if it does not yet exist)
    //      elementID = the ID of the status message tag to show or create
    //      statusMessage = the new status message to show

    // Make sure the parameters are valid
    if (arguments.length < 3 || !parentElementID || !elementID) { return; }
    parentElementID = unescape(parentElementID);
    elementID = unescape(elementID);

    // Get the elements
    var objParent = getElement(parentElementID);
    if (!objParent) { return; } // make sure we're adding a status message to something that exists
    
    // Get/Create the status message
    var szDefaultValue = '<span id="' + elementID + '" class="invis ajaxmessage"></span>';
    var objMessage = getElementOrCreate(objParent, elementID, szDefaultValue, true);

    // Update the status message
    setInnerHTML(objMessage, statusMessage);
}

// -------------- AJAX DropDown Functions ------------- //
function DropDown_GetData(dropdownID, populateFunction) {
    // Parameters:
    //      dropDownID = the ID of the dropdown to get the data for
    //      populateFunction = the name of the function to use to populate the data
    //      queryStringData = arguments[2] (optional) = an array of the IDs whose values to include with data request
    //      childDropDowns = arguments[3] (optional) = an array of the IDs and loading messages for dropdowns to disable

    // Make sure the parameters are valid
    if (!dropdownID || !populateFunction) { return; }

    // Get the objects
    var objDropDown = getElement(dropdownID);
    if (!objDropDown) { return; }

    populateFunction = escape(unescape(populateFunction));

    // Create the query string data
    var szQueryStringData = "&ddl=" + escape(unescape(dropdownID));

    // Get the existing values
    var nLength = 0; var i = 0;
    if (arguments.length > 2) {
        var aQueryStringData = arguments[2];
        if (aQueryStringData && aQueryStringData.length > 0) {
            var szQueryElementID = "";
            var bValid = true;

            i = 0; nLength = aQueryStringData.length;

            for (i = 0; i < nLength; i++) {
                // Make sure the element is valid
                szQueryElementID = aQueryStringData[i];
                if (checkElement(szQueryElementID, true)) {
                    // Add the post data
                    szQueryStringData += "&" + szQueryElementID + "=" + escape(getValue(getElement(szQueryElementID)));
                } else {
                    bValid = false;
                }
            }

            if (!bValid) { return; }
        }
    }
    
    // Show the loading message
    disableDropDown(dropdownID, "Loading...");

    // Generate the Ajax Request String
    var szAjaxRequest =
        g_szAjaxFile + "cmd=dropDown_getData&d=" + populateFunction + szQueryStringData + "&a=" + getRandomString(25);

    // Create an ajax object
    g_objAjax.AjaxRequest(szAjaxRequest);

    // Disable child dropdowns that depend on this ones value
    if (arguments.length > 3) {
        var aChildDropDowns = arguments[3];

        if (aChildDropDowns && aChildDropDowns.length) {
            var nLength = aChildDropDowns.length;
            var i = 0;
            var objChild = null;

            for (i = 0; i < nLength; i++) {
                objChild = aChildDropDowns[i];
                if (!objChild || !objChild[0] || !objChild[1]) { continue; }

                // Disable the child dropdown
                disableDropDown(objChild[0], objChild[1]);
            }
        }
    }

    // All set
    return;
}

// -------------- AJAX Miscellaneous Functions ------------- //
// E-mails newsletter signup
function Site_EmailSignup(emailID, type, parentID) {
    // Parameters:
    //      emailID = the ID of the <input> tag containing the email address value
    //      type = the signup type
    //      parentID = the ID of the tag to show the confirmation message inside

    // Make sure the parameters are valid
    if (arguments.length < 3 || !emailID || !parentID) { return; }

    // Get the values
    var szEmail = escape(getValue(getElement(emailID)));
    var szType = "";
    if (type) { szType = escape(unescape(type)); }

    // Show the status message
    var szMessageID = "rightnav_email_signup_confirm";
    ShowStatusMessage(parentID, szMessageID, 'Signup Complete');
    hideElementWithDelay(szMessageID, 5000);
    
    var objEmail = getElement(emailID);
    if (objEmail) { objEmail.value = ''; }

    // Generate the Ajax Request String
    var szAjaxRequest =
        g_szAjaxFile + "cmd=site_emailSignup&e=" + escape(szEmail) +
        "&t=" + szType + "&a=" + getRandomString(25);

    // Create an ajax object
    g_objAjax.AjaxRequest(szAjaxRequest);
}

// -------------- AJAX Customer Functions ------------- //
// Sends the verification email to a customer
function Customer_SendVerification(messageID) {
    // Parameters:
    //      customerID = (not a parameter, but will be passed via cookies)
    //      messageID = the identifier for the XHTML tag to populate with response messages

    // Make sure the parameters are valid
    if (!messageID) { return; }
    messageID = escape(unescape(messageID));
    
    // Generate the Ajax Request String
    var szAjaxRequest =
        g_szAjaxFile + "cmd=customer_sendVerification&m=" + messageID + "&a=" + getRandomString(25);

    // Create an ajax object
    g_objAjax.AjaxRequest(szAjaxRequest);
}
