/// <reference path="jquery-1.3.2.min.js" />
/// <reference path="ui.core.js" />
/// <reference path="effects.core.js" />
/// <reference path="effects.highlight.js" />

// function to create a drop down option
function ruleDependentFieldOption(val, text, parentNodeValue) {
    this.val = val;
    this.text = text;
    this.parentNodeValue = parentNodeValue;
}

// function to create a drop down option
function DropDownOption(val, text, isselected) {
    this.val = val;
    this.text = text;
    this.isselected = isselected;
}

function dataField(dataFieldName, sampleData) {
    this.dataFieldName = dataFieldName;
    this.sampleData = sampleData;
}

function vdpDataFileMap(variableID, variableName, dataFieldName, displayName, sampleData, displayOrder, required) {
    this.variableID = variableID;
    this.variableName = variableName;
    this.dataFieldName = dataFieldName;
    this.displayName = displayName;
    this.sampleData = sampleData;
    this.displayOrder = displayOrder;
    this.required = required;
}


// function to define a ruleDependent Array
function ruleDependentArray(ruleValue, dependentArray) {
    this.ruleValue = ruleValue;
    this.dependentArray = dependentArray;
}

function FixQuotes(textIs) {
    // first replace " with &quot;
    thelength = textIs.length;
    for (i = 0; i < thelength; i++) {
        if (textIs.charAt(i) == '"') {
            textIs = textIs.substring(0, i) + "&quot;"
            + textIs.substring(i + 1, thelength);
            thelength += 6;
            i += 6;
        }
    }
    // now replace &apos; with '
    var pos = 0;
    while (pos != -1) {
        pos = textIs.indexOf("&apos;");
        if (pos != -1)
            textIs = textIs.substring(0, pos) + "'" + textIs.substring(pos + 6);
    }
    return textIs;
}

//////////////////////////////////////////////
// function to open browse pictures (ie image gallery)
//////////////////////////////////////////////
function openBrowsePictures(jsVariableID, jsFormIndex, isOnChange, onChangeFunctionName, varHTMLId) {
    var formPrompt = getDialogTitleForField(allFormElementsIdMap[varHTMLId].elemdisplayname, 'image');
    var iFrameUrl = 'BrowseImagesFilter.aspx?CompanyID=' + companyid + '&templateID=' + templateID + '&userID=' + userID + '&variableID=' + jsVariableID + '&formIndex=' + jsFormIndex + '&isOnChange=' + isOnChange + '&onChangeFunctionName=' + onChangeFunctionName;
    
    var w = 650;
    var h = 550;
    var maxWidth = 720;
    var maxHeight = 620;
    var ddEl = document.getElementById(varHTMLId);
    if (ddEl && ddEl != null) {
        if (ddEl.length <= 5)
            maxHeight = 350;
        else if (ddEl.length <= 10)
            maxHeight = 450;
        if (ddEl.length <= 3)
            maxWidth = parseInt(maxWidth / 5.0 * ddEl.length);
    }
    if (typeof (jQuery) !== 'undefined') {
        w = parseInt(0.80 * jQuery(window).width());
        h = parseInt(0.80 * jQuery(window).height());
        if (w > maxWidth)
            w = maxWidth;
        if (h > maxHeight)
            h = maxHeight;
        iFrameUrl += '&if_w=' + w + '&if_h=' + h;
    }

    jQuery.fn.colorbox({ width: w, height: h, maxWidth: maxWidth, maxHeight: maxHeight, iframe: true, href: iFrameUrl, open: true, overlayClose: false, scrollbars: false, opacity: 0.70, title: formPrompt });
}

// function to upload image
function uploadImage(jsVariableID, jsFormIndex, fWidth, fHeight, dpi, forceCmyk, varHTMLId) {   
    // by default we'll use the post message function to communicate between windows in different sub-domains
    if (typeof (postMessageEnabled) == 'undefined') {
        postMessageEnabled = true;
        // disable image resizing on IE7        		
        if (true == isIE7) {            
            postMessageEnabled = false;
        }
    }
    
    var elem = document.forms[0].elements[jsFormIndex];
    var elemid = elem.name;
    var formPrompt = getDialogTitleForField(allFormElementsIdMap[varHTMLId].elemdisplayname, 'image');
    var page = 'UploadImage.aspx';
    var w = true == postMessageEnabled ? "550" : "700";
    var h = true == postMessageEnabled ? "200" : "450";    
    if (dpi && dpi > 0) {
        w = true == postMessageEnabled ? "725" : "850";
        h = true == postMessageEnabled ? "350" : "700";      
    }
    var iFrameUrl = page + '?CompanyID=' + companyid + '&templateID=' + templateID + '&userID=' + userID + '&variableID=' + jsVariableID + '&formIndex=' + jsFormIndex + '&elemid=' + elemid + '&frameWidth=' + fWidth + '&frameHeight=' + fHeight + '&dpi=' + dpi + '&forceCmyk=' + forceCmyk + '&doPost=' + postMessageEnabled;
    jQuery.fn.colorbox({ width: "90%", maxWidth: w, height: h, iframe: true, href: iFrameUrl, open: true, overlayClose: false, scrollbars: false, opacity: 0.70, title: formPrompt });
}

function closeDialog() {
    jQuery.fn.colorbox.close();
}

function resizeDialog(w, h, customCallback) {    
    jQuery.fn.colorbox.resizeManual({ width: w, height: h }, customCallback);
}

function getDialogTitleForField(formPrompt, fieldType) {
    // make sure the title is not too long
    if (formPrompt.length > 50)
        formPrompt = formPrompt.substring(0, 47) + "...";
    return formPrompt;
}

function removeLocalImage(frmIndex) {
    var elmName = document.forms[0].elements[frmIndex].name + 'Div';
    if (navigator.appName == 'Netscape') {
        var element = document.getElementById(elmName);
        element.style.display = 'none';
        element.style.visibility = 'hidden';
    }
    else {
        document.all[elmName].style.display = 'none';
        document.all[elmName].style.visibility = 'hidden';
    }
    document.forms[0].elements[frmIndex].value = '';
    document.forms[0].elements[frmIndex + 2].value = '';
    document.forms[0].elements[frmIndex + 2].display = 'none';
    document.forms[0].elements[frmIndex + 2].visibility = 'hidden';

}

function FormElement(elemname, elemdisplayname, elemtype, elemcheckfor, elemwarning, elemerrmessage, elemdefaultvalue, elemisrequired, elemonchange, sectionIdx) {
    this.elemname = elemname;
    this.elemdisplayname = elemdisplayname;
    this.elemtype = elemtype;
    this.elemcheckfor = elemcheckfor;
    this.elemwarning = elemwarning;
    this.elemerrmessage = elemerrmessage;
    this.elemdefaultvalue = elemdefaultvalue;
    this.elemisrequired = elemisrequired;
    this.elemonchange = elemonchange;
    this.sectionIndex = sectionIdx;
    this.conditionalparent = null;
}

// check for blank value
function isBlank(varstr) {

    if (varstr.length != 0)
        for (var i = 0; i < varstr.length; i++) {
        var ch = varstr.substring(i, i + 1);
        if (ch != " ") {
            return true;
            break;
        }
        else {
            return false;
            break;
        }
    }

    // FOR LOOP
    else
        return false;
}

// function to check valid number

function isNumber(inStr) {
    inLen = inStr.length
    for (var i = 0; i < inLen; i++) {
        var ch = inStr.substring(i, i + 1)
        if ((ch < "0" || "9" < ch) && (ch != "-")) {
            return false;
            break;
        }
    }
    return true;
}

// function to check for Positive number

function isPositive(inStr) {
    inLen = inStr.length
    for (var i = 0; i < inLen; i++) {
        var ch = inStr.substring(i, i + 1)
        if (ch < "0" || "9" < ch) {
            return false;
            break;
        }
    }
    if (parseInt(inStr) <= 0)
        return false;
    return true;

}

//function to trim the value passed to it

function trim(strMessage) {
    var strResult;
    var charTemp;
    var i;
    strResult = "";
    //remove the left space
    for (i = 0; i < strMessage.length; i++) {
        charTemp = strMessage.charAt(i);
        if (charTemp != " ") {
            strResult = strMessage.substring(i);
            break;
        }
    }
    //remove the right space
    for (i = strResult.length - 1; i >= 0; i = i - 1) {
        charTemp = strResult.charAt(i);
        if (charTemp != " ") {
            strResult = strResult.substring(0, i + 1);
            break;
        }
    }
    return (strResult);

}

function isValidEmailAddress(strEmailAddress) {
    var filter = /^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
    if (!filter.test(strEmailAddress))
        return false;
    return true;
}

// function to return element index for a form
function returnindex(callingfield, callingform) {
    var elementId;
    for (var i = 0; i < document.forms[0].elements.length; i++) {
        elementId = typeof (document.forms[0].elements[i].id) === "undefined"
            ? document.forms[0].elements[i].name
            : document.forms[0].elements[i].id;

        if (elementId == callingfield)
            return i;
    }
    return -1;
}

// function to check if the character passed is numeric
function IsDigit(chVal) {
    var numStr = "0123456789";
    if (numStr.indexOf(chVal) != -1) {
        return true;
    }
    return false;
}

// function to check if the passed value is a valid currency

function isValidCurrency(curStr) {
    var data = curStr;
    if (data.length == 0)
        return false;

    var nState = 0;
    var chCur = data.charAt(0);
    var nCurChar = 0;

    while (nCurChar < data.length) {
        //alert("character at position " + nCurChar + " is " + chCur);
        //alert("nState at position " + nCurChar + " is " + nState);
        switch (nState) {
            case 0:
                if (chCur == "$")
                    nState = 1;
                else if (IsDigit(chCur))
                    nState = 1;
                else
                    return false;
                break;
            case 1:
                if (IsDigit(chCur))
                    nState = 2;
                else if (chCur == ",")
                    nState = 8;
                else if (chCur == ".")
                    nState = 5;
                else
                    return false;
                break;
            case 2:
                if (IsDigit(chCur))
                    nState = 3;
                else if (chCur == ",")
                    nState = 8;
                else if (chCur == ".")
                    nState = 5;
                else
                    return false;
                break;
            case 3:
                if (IsDigit(chCur))
                    nState = 3;
                else if (chCur == ",")
                    nState = 8;
                else if (chCur == ".")
                    nState = 5;
                else
                    return false;
                break;
            case 4:
                if (IsDigit(chCur))
                    nState = 12;
                else if (chCur == ",")
                    nState = 8;
                else if (chCur == ".")
                    nState = 5;
                else
                    return false;
                break;
            case 5:
                if (IsDigit(chCur))
                    nState = 6;
                else
                    return false;
                break;
            case 6:
                if (IsDigit(chCur))
                    nState = 7;
                else
                    return false;
                break;
            case 7:
                //return false;
                if (IsDigit(chCur))
                    nState = 8;
                else
                    return false;
                break;
            case 8:
                if (IsDigit(chCur))
                    nState = 9;
                else
                    return false;
                break;
            case 9:
                if (IsDigit(chCur))
                    nState = 10;
                else
                    return false;
                break;
            case 10:
                if (IsDigit(chCur))
                    nState = 11;
                else
                    return false;
                break;
            case 11:
                if (chCur == ",")
                    nState = 8;
                else if (chCur == ".")
                    nState = 5;
                else
                    return false;
                break;
            case 12:
                if (IsDigit(chCur))
                    nState = 12;
                else if (chCur == ".")
                    nState = 5;
                else
                    return false;
        };

        nCurChar++;
        chCur = data.charAt(nCurChar);
    }
    if ((nState == 5) || (nState == 6))
        return false;

    return true;
}

// function to check if the passed value is a valid decimal value

function isReal(inStr) {
    inLen = inStr.length
    for (var i = 0; i < inLen; i++) {
        var ch = inStr.substring(i, i + 1)
        if (ch != ".")
            if (ch < "0" || "9" < ch) {
            return false;
            break;
        }
    }
    return true;
}

// function to check if valid date

function isDate(date) {
    var dt;
    dt = new Date();
    var stMonth = parseInt(dt.getMonth() + 1);
    var stDate = parseInt(dt.getDate());
    var stYear = parseInt(dt.getYear());

    var s = "" + date;
    var str1 = "";
    var s3 = ""; var s4 = "";

    if (s.charAt(1) == '/' || s.charAt(1) == '-') {
        s = "0" + s;
    }

    if (s.charAt(4) == '/' || s.charAt(4) == '-') {
        s = s.substring(0, 3) + "0" + s.substring(3)
    }

    if (s.length == 10 || s.length == 8) {
        var validnum2 = isNumber(s.substring(0, 2));
        var validnum1 = isNumber(s.substring(3, 5));
        var validnum5 = isNumber(s.substring(6));
        if (validnum2 == false || validnum1 == false || validnum5 == false)
            str1 = "Wrong Date";
        else {
            var s2 = parseInt(s.substring(0, 2));
            var s1 = parseInt(s.substring(3, 5));
            var a1 = "";
            a1 = s.substring(6);
            if (a1.length == 2) {
                a1 = "20" + a1;
            }
            var s5 = parseInt(a1);
            s4 = s.substring(0, 2);
            s3 = s.substring(3, 5);
            if ((s.charAt(2) == '/' || s.charAt(2) == '-') && (s.charAt(5) == '/' || s.charAt(5) == '-')) {
                if (s1 > 31 || s2 > 12 || s3 == "00" || s4 == "00") {
                    str1 = "Wrong Date ";
                }
                else {
                    if (!(((s4 == "04") || (s4 == "06") || (s4 == "09") || (s4 == "11")) && (s1 > 30))) {
                        if (s4 == "02") {
                            if (s1 > 29) {
                                str1 = "Wrong Date";
                            }
                            else {
                                if (!(s5 % 4 == 0) && (s1 > 28)) {
                                    str1 = "Wrong Date";
                                }
                                else {
                                    str1 = "This is a perfect Date";
                                }
                            }
                        }
                        else {
                            str1 = "This is a perfect Date";
                        }
                    }
                    else {
                        str1 = "Wrong Date";
                    }
                }
            }
            else {
                str1 = "Wrong Format ";
            }
        }
    }

    if (str1 != "This is a perfect Date") {
        //alert(str1 + " Please enter a valid Date");
        return false;
    }
    else {
        //alert("Perfect Date!!!");
        return true;
    }
}

// Deletes all the items from the Drop-Down List supplied

function delAllDropDownItems(selField) {
    for (var i = 0; i < selField.length; i++) {
        selField.options[i] = null;
        i--;
    }
}

// function matches element name and returns allFormElements index true if found
function allFormElementsIndex(elementName) {
    for (var j = 0; j < allFormElements.length; j++) {
        if (elementName == allFormElements[j].elemname)
            return j;
    }
    return -1;
}

/* function that checks if all elements are good to go...

values for elemcheckfor

1 - check for blank, depends on element type
if text or textarea then call isBlank function
if include or select check for selectedindex as it is dropdown
2 - check for number (int no decimals)
3 - check for currency (can be of format 0 or $0 or 0.0 or $0.0 or 0.00 or $0.00
4 - check for decimal value
5 - check for valid date
6 - check for positive number > 0

elemerrmessage can hold the error message for the field
so if not empty then display that error message else display the default error message

elemwarning tells if we should warn the user, if an entered value is incorrect
the warning will be displayed only to the fields that are NOT required
and that have been set in the xml to display warning
elemdefaultvalue holds the default value that the field value must be set
if it is incorrect
*/

function checkAll(formname) {
    var ret = true;

    // first check for required elements
    if (typeof (allFormElements) == 'undefined')
        return true;

    for (var j = 0; j < allFormElements.length; j++) {
        var formelem = allFormElements[j];
        var validationResult = checkformelem(formelem, formname);

        if (!validationResult.isvalid) {
            // check if this is a conditional child and if it is hidden then we're all good
            if (formelem.elemconditionalparent != null) {
                var jqObj = jQuery("#" + formelem.elemname);
                // this element is only visible if it's containing table cell and table row are not hidden ;
                //  so if any are hidden or display:none then this child is hidden as well
                var isHidden = jqObj.css('display') == 'none'
	                        || jqObj.css('visibility') == 'hidden'
	                        || jqObj.parent().css('display') == 'none'
	                        || jqObj.parent().css('visibility') == 'hidden'
	                        || jqObj.parent().parent().css('display') == 'none'
	                        || jqObj.parent().parent().css('visibility') == 'hidden';

                // conditional children are not required if they are hidden (ie the parent value was not selected)
                if (isHidden)
                    continue;
            }

            activateSection(formelem);
            alert(validationResult.message);

            $(formelem.elemname).focus();
            ret = false;
            break;
        }
    }
    return ret;
}

function checkformelem(formelem, formname) {
    var ret = true;
    var errorMsg = '';
    var elementObj;
    var localImageUpload = false; // for upload local images    
    var str = formelem.elemtype.toLowerCase();

    if (formelem.elemisrequired == 1) {
        if (str == 'text' || str == 'textarea' || str == 'tpa_single' || str == 'tpa_multi' || str == 'password' || str == 'labeldropdown') {
            elementObj = $(formelem.elemname);
            if (formelem.elemcheckfor == 1) // check for blank
            {
                if (isBlank(trim(elementObj.value)) == false) {
                    if (formelem.elemerrmessage == '')
                        errorMsg = formelem.elemdisplayname + GetStringContent('EmptyFieldMessage');
                    else
                        errorMsg = formelem.elemerrmessage;
                    ret = false;
                }
            }
            if (formelem.elemcheckfor == 2) // check for number
            {
                if (isBlank(trim(elementObj.value)) == false || isNumber(trim(elementObj.value)) == false) {
                    if (formelem.elemerrmessage == '')
                        errorMsg = formelem.elemdisplayname + GetStringContent('ValidNumberMessage');
                    else
                        errorMsg = formelem.elemerrmessage;
                    ret = false;
                }
            }
            if (formelem.elemcheckfor == 3) // check for valid currency
            {
                if (isValidCurrency(trim(elementObj.value)) == false) {
                    if (formelem.elemerrmessage == '')
                        errorMsg = formelem.elemdisplayname + GetStringContent('ValidCurrencyMessage');
                    else
                        errorMsg = formelem.elemerrmessage;
                    ret = false;
                }
            }
            if (formelem.elemcheckfor == 4) // check for valid currency
            {
                if (isReal(trim(elementObj.value)) == false) {
                    if (formelem.elemerrmessage == '')
                        errorMsg = formelem.elemdisplayname + GetStringContent('ValidDecimalMessage');
                    else
                        errorMsg = formelem.elemerrmessage;
                    ret = false;
                }
            }
            if (formelem.elemcheckfor == 5) // check for valid date
            {
                if (isDate(trim(elementObj.value)) == false) {
                    if (formelem.elemerrmessage == '')
                        errorMsg = formelem.elemdisplayname + GetStringContent('ValidDateMessage');
                    else
                        errorMsg = formelem.elemerrmessage;
                    ret = false;
                }
            }
            if (formelem.elemcheckfor == 6) // check for positive number
            {
                if (isBlank(trim(elementObj.value)) == false || isPositive(trim(elementObj.value)) == false) {
                    if (formelem.elemerrmessage == '')
                        errorMsg = formelem.elemdisplayname + GetStringContent('ValidPositiveNumberMessage');
                    else
                        errorMsg = formelem.elemerrmessage;
                    ret = false;
                }
            }
        }

        // if type is include or select ..meaning dropdown
        if (str == 'include' || str == 'select' || str == 'libraryselect' || str == 'image' || str == 'executefunction' || str == 'imagecollection') {
            elementObj = $(formelem.elemname);
            frmindex = returnindex(formelem.elemname, formname);
            if (formelem.elemcheckfor == 1) {
                if (document.forms[0].elements[frmindex + 1].name == formelem.elemname + '__uploadImage') {
                    if (document.forms[0].elements[frmindex + 1].value == '');
                    else
                        localImageUpload = true;
                }
                if (localImageUpload == false) {
                    if (document.forms[0].elements[frmindex + 2].name == formelem.elemname + '__uploadImage') {
                        if (document.forms[0].elements[frmindex + 2].value == '');
                        else
                            localImageUpload = true;
                    }
                }
                if (localImageUpload == false) {
                    if (document.forms[0].elements[frmindex].selectedIndex == -1 || document.forms[0].elements[frmindex].options[document.forms[0].elements[frmindex].selectedIndex].value == '') {
                        if (formelem.elemerrmessage == '')
                            errorMsg = GetStringContent('ValidDropdownValueMessage') + formelem.elemdisplayname + '.';
                        else
                            errorMsg = formelem.elemerrmessage;

                        ret = false;
                    }
                }
            }
        }
    }
    else // now check for other elements and warn if entered incorrectly
    {
        if (str == 'text' || str == 'textarea' || str == 'tpa_single' || str == 'tpa_multi' || str == 'labeldropdown') {
            elementObj = $(formelem.elemname);
            if (formelem.elemcheckfor == 2 && formelem.elemwarning == 1) // check for number
            {
                if (isBlank(trim(elementObj.value)) == true && isNumber(trim(elementObj.value)) == false) {
                    activateSection(formelem);
                    if (formelem.elemerrmessage == '')
                        ret = confirm(formelem.elemdisplayname + ' if entered, should be a valid number.\nPress "OK" to set the default value or "Cancel" to enter the appropriate value.');
                    else
                        ret = confirm(formelem.elemerrmessage);
                    if (ret == false) {
                        ;
                    }
                    else
                        elementObj.value = formelem.elemdefaultvalue;

                }
            }
            if (formelem.elemcheckfor == 3 && formelem.elemwarning == 1) // check for valid currency
            {
                if (isBlank(trim(elementObj.value)) == true && isValidCurrency(trim(elementObj.value)) == false) {
                    activateSection(formelem);
                    if (formelem.elemerrmessage == '')
                        ret = confirm(formelem.elemdisplayname + ' if entered, should be a numeric currency value.\nPossible values can be like 0 or $0 or $0.00\nPress "OK" to set the default value or "Cancel" to enter the appropriate value.');
                    else
                        ret = confirm(formelem.elemerrmessage);
                    if (ret == false) {
                        ;
                    }
                    else
                        elementObj.value = formelem.elemdefaultvalue;
                }
            }
            if (formelem.elemcheckfor == 4 && formelem.elemwarning == 1) // check for valid currency
            {
                if (isBlank(trim(elementObj.value)) == true && isReal(trim(elementObj.value)) == false) {
                    activateSection(formelem);
                    if (formelem.elemerrmessage == '')
                        ret = confirm(formelem.elemdisplayname + ' if entered, should be a valid decimal value.\nPossible values can be like 0 or 0.0\nPress "OK" to set the default value or "Cancel" to enter the appropriate value.');
                    else
                        ret = confirm(formelem.elemerrmessage);
                    if (ret == false) {
                        ;
                    }
                    else
                        elementObj.value = formelem.elemdefaultvalue;
                }
            }
            if (formelem.elemcheckfor == 5 && formelem.elemwarning == 1) // check for valid currency
            {
                if (isBlank(trim(elementObj.value)) == true && isDate(trim(elementObj.value)) == false) {
                    activateSection(formelem);
                    if (formelem.elemerrmessage == '')
                        ret = confirm(formelem.elemdisplayname + ' if entered, should be a valid date.\nPress "OK" to set the default value or "Cancel" to enter the appropriate value.');
                    else
                        ret = confirm(formelem.elemerrmessage);
                    if (ret == false) {
                        ;
                    }
                    else
                        elementObj.value = formelem.elemdefaultvalue;
                }
            }
            if (formelem.elemcheckfor == 6 && formelem.elemwarning == 1) // check for positive number
            {
                if (isBlank(trim(elementObj.value)) == true && isPositive(trim(elementObj.value)) == false) {
                    activateSection(formelem);
                    if (formelem.elemerrmessage == '')
                        ret = confirm(formelem.elemdisplayname + ' if entered, should be a positive number greater than 0.\nPress "OK" to set the default value or "Cancel" to enter the appropriate value.');
                    else
                        ret = confirm(formelem.elemerrmessage);
                    if (ret == false) {
                        ;
                    }
                    else
                        elementObj.value = formelem.elemdefaultvalue;

                }
            }
        }
    }
    return { isvalid: ret, message: errorMsg };
}

function removeWhiteSpace(strValue) {
    return strValue.replace(/\s+/g, '');
}

//------------------------------------------------ Cascading dropdown functions -----------------------------------
var cascadingTopFiltered = false;

function O(text, value, submenu) {
    this.text = text;
    this.value = value;
    this.length = 0;
    if (submenu != null) {
        // submenu is an array of options...
        for (var i = 0; i < submenu.length; ) {
            this[i] = submenu[i];
            this.length = ++i;
        }
    }
}

function updateCascadingDropDowns(elName, m, grpIndex, group) { // updates submenus - form(num)'s menu options, and all submenus
    // if refd form exists  
    with (document.forms[0].elements[elName]) {
        var selectedOption = 0;
        var selectedOptionText = '';

        for (var i = options.length - 1; 0 <= i; i--) {
            if (options[i].selected && i > 0) {
                //alert("@cascading-->" + group[grpIndex] + " has selected index " + i + " value = " + options[i].value);
                selectedOptionText = options[i].text;
            }
            options[i] = null; // null out options in reverse order (bug work-around)
        }
        for (var i = 0; i < m.length; i++) {
            options[i] = new Option(m[i].text, m[i].value); // fill up next menu's items
            if (removeWhiteSpace(m[i].text) == removeWhiteSpace(selectedOptionText)) {
                //alert(selectedOptionText);
                selectedOption = i; // to render child dropdown
                options[i].selected = true;
            }
        }

        /*
        if(options!=null && options.length) {
        options[selectedOption].selected = true; // default to 1st menu item, windows bug kludge
        }
        */
    }
    if (m[selectedOption] != null && m[selectedOption].length) {
        nxtElName = group[++grpIndex];
        updateCascadingDropDowns(nxtElName, m[selectedOption], grpIndex, group); // update subsequent form if any grandchild menu exists
    }

}

function updateTopDropDown(tree, group) {
    with (document.forms[0].elements[group[0]]) {
        var selectedOption = 0;
        var selectedOptionText = '';
        for (var i = options.length - 1; 0 <= i; i--) {
            if (options[i].selected && i > 0) {
                //alert("@update-->" + group[0] + " has selected index " + i);
                selectedOption = i;
                selectedOptionText = options[i].text;
            }
            options[i] = null; // null out options in reverse order (bug work-around)
        }

        for (var i = 0; i < tree.length; i++) {
            //alert(tree[i].text + " = " + tree[i].value);
            options[i] = new Option(tree[i].text, tree[i].value);
            if (removeWhiteSpace(tree[i].text) == removeWhiteSpace(selectedOptionText)) {
                //alert(selectedOptionText);
                selectedOption = i; // to render child dropdown
                options[i].selected = true;
            }
        }
        /*
        if (options!=null && options.length) {
        options[selectedOption].selected = true; // default to 1st menu item, windows bug kludge
        }
        */
    }
}

function relateCascadingDropDowns(tree, hierarchy, group) {

    if (!cascadingTopFiltered && tree != null) {
        cascadingTopFiltered = true;

        updateTopDropDown(tree, group);

    }

    var a = tree;        // set a to be the tree array      						

    var nxtElName;
    var grpIndex;

    for (grpIndex = 0; grpIndex < hierarchy; grpIndex++) {

        if (a == null) {
            break;
        }
        var sel = document.forms[0].elements[group[grpIndex]].selectedIndex;
        var selectedValue = document.forms[0].elements[group[grpIndex]].options[sel].value;
        if (grpIndex + 1 < group.length) {
            nxtElName = group[grpIndex + 1];
        }
        // get the child array using the selectedValue first and then if not found use the selectedIndex
        var treeFromValue = false;
        for (var i = 0; i < a.length; i++) {
            if (a[i].value == selectedValue) {
                a = a[i];
                treeFromValue = true;
                break;
            }
        }
        if (treeFromValue == false) {
            a = a[sel];
        }
    }

    if (a != null) {
        // if a array exists and it has elements,
        // feed update() w/ this record reference
        updateCascadingDropDowns(nxtElName, a, grpIndex, group);
        return;
    }

}


function RegisterDisableAdd(elementId) {
    var el = $(elementId);
    if (el && el.onchange)
        Event.observe(el, 'change', DisableAdd, false);
}

function submitForm() {
    //alert("about to submit form!!");
    document.forms[0].submit();
}

// limits the size of a textarea control.
// NOTE: this is required for the textarea control only.\n
function limitMaxLength(field, maxlimit) {
    if (field.value.length > maxlimit) // if too long...don't allow it!
        return false;

    return true;
}

// limits the size of a textarea control.
// NOTE: this is required for the textarea control only.\n
function trimMaxLength(field, maxlimit) {
    if (field.value.length > 0) {
        if (field.value.length > maxlimit) // if too long...trim it!
        {
            field.value = field.value.substring(0, maxlimit);
        }
    }
}

function showLocalImage(frmIndex) {
    var dropDownValue = document.forms[0].elements[frmIndex].value;
    var imageUrl = 'DownloadProcessor.ashx?downloadType=image&imageType=thumb&dropDownValue=' + dropDownValue;
    showImagePreview('previewContainer', 'previewImage', imageUrl, 'iframeDivFix');
}


function popLocalImage(frmIndex) {
    var dropDownValue = document.forms[0].elements[frmIndex].value;
    var imageUrl = 'DownloadProcessor.ashx?downloadType=image&imageType=browse&dropDownValue=' + dropDownValue;
    
    // popimage(imageUrl, 700, 750); // browse image is downsampled to 600x600 so we'll just add some extra space here
    jQuery.fn.colorbox({ photo: true, href: imageUrl, open: true, opacity: 0.70 });
}

// used for manually firing builtin browser events like onchange and onclick
// do not include the "on" prefix of the event name
function fireEvent(element, event) {
    //
    // example usage for manually firing a dropdown's onchange event:
    // var el = document.getElementById("myDropDown");
    // fireEvent(el, 'change');
    //
    if (document.createEvent) {
        // dispatch for firefox + others
        var evt = document.createEvent("HTMLEvents");
        evt.initEvent(event, true, true); // event type,bubbling,cancelable
        return !element.dispatchEvent(evt);
    }
    else {
        // dispatch for IE
        var evt = document.createEventObject();
        return element.fireEvent('on' + event, evt);
    }
}

/**
* COMMON DHTML FUNCTIONS
* These are handy functions I use all the time.
*
* By Seth Banks (webmaster at subimage dot com)
* http://www.subimage.com/
*
* Up to date code can be found at http://www.subimage.com/dhtml/
*
* This code is free for you to use anywhere, just keep this comment block.
*/

/**
* X-browser event handler attachment and detachment
*
* @argument obj - the object to attach event to
* @argument evType - name of the event - DONT ADD "on", pass only "mouseover", etc
* @argument fn - function to call
*/
function addEvent(obj, evType, fn) {
    if (obj.addEventListener) {
        obj.addEventListener(evType, fn, true);
        return true;
    } else if (obj.attachEvent) {
        var r = obj.attachEvent("on" + evType, fn);
        return r;
    } else {
        return false;
    }
}
function removeEvent(obj, evType, fn, useCapture) {
    if (obj.removeEventListener) {
        obj.removeEventListener(evType, fn, useCapture);
        return true;
    } else if (obj.detachEvent) {
        var r = obj.detachEvent("on" + evType, fn);
        return r;
    } else {
        alert("Handler could not be removed");
    }
}

/******************************************************************
* Begin Rich Text Editor Scripts
*******************************************************************/
function OpenTextEditor(varId, varHTMLId) {
    // bring up the editor in a modal dialog
    var iFrameUrl = "texteditor.aspx?varId=" + varId + "&HtmlId=" + varHTMLId;
    var formPrompt = getDialogTitleForField(allFormElementsIdMap[varHTMLId].elemdisplayname, 'text');
    
    var w = 550;
    var h = 435;
    var maxWidth = 760;
    var maxHeight = 600;
    if (typeof (jQuery) !== 'undefined') {
        w = parseInt(0.80 * jQuery(window).width());
        h = parseInt(0.80 * jQuery(window).height());
        if (w > maxWidth)
            w = maxWidth;
        if (h > maxHeight)
            h = maxHeight;
        iFrameUrl += '&if_w=' + w + '&if_h=' + h;
    }

    jQuery.fn.colorbox({ width: w, height: h, iframe: true, href: iFrameUrl, open: true, overlayClose: false, scrollbars: false, opacity: 0.70, title: formPrompt });    
}

function HideEditor(varHTMLId) {
    // close modal dialog editor is in
    closeDialog();    
}

function OnEditorSave(varHTMLId, outputText) {
    document.getElementById(varHTMLId).value = outputText;
    // call the onChange handler to register for DisableAdd which will force user to preview
    DisableAdd();
}

function OnEditorLoad(varHTMLId) {
    // load editor with form value    
    var content = document.getElementById(varHTMLId).value;
    return content;
}

String.prototype.replaceAll = function(pcFrom, pcTo) {
    var c = this;
    while (c.match(pcFrom)) {
        c = c.replace(pcFrom, pcTo);
    }
    return c;
}

function translateSpaceEntityToFP(content) {

    var pattern = new RegExp("(</[ ]*[ibu]>)([ ]+)([^<]*)", "i");

    var match = pattern.exec(content);
    while (match) {
        var spaces = match[2];

        var count = 1;
        while (/[ ]/.exec(spaces)) {
            var spacematch = /[ ]/.exec(spaces);
            if (count > 1)
                spaces = spaces.replace(spacematch[0], String.fromCharCode(19)); //&#19;
            else
                spaces = spaces.replace(spacematch[0], String.fromCharCode(32)); //&#32 which still comes out as " "

            count++;
        }

        content = content.replace(match[0], match[1] + spaces + match[3]);
        match = pattern.exec(content);
    }
    return content;
}
/******************************************************************
* End Rich Text Editor Scripts
*******************************************************************/

function activateSection(formelem, callback) {
    if (formelem.sectionIndex > -1) {
        if (jsPlugin == 'fieldsets')
            jsPluginObj[jsPluginActivate](formelem.sectionIndex);
        else
            jsPluginObj[jsPlugin](jsPluginActivate, formelem.sectionIndex);
    }
}
function openSections(index) {
    if (arguments.length == 0)
        index = -1;

    if (jsPlugin == 'fieldsets')
        jsPluginObj.expand(index);
    else if (jsPlugin == 'accordion' || jsPlugin == 'tabs')
        jsPluginObj[jsPlugin](jsPluginActivate, index);
    else
        jsPluginObj[jsPlugin]('expand', index);
}

function openRequiredSections() {
    openSections(getRequiredSections());
}

function gotoSection(index, htmlId) {
    openSections(index);
    if (htmlId)
        document.location.hash = htmlId;
}

function getRequiredSections() {
    var msg = "";
    var idList = "";
    var formelem;
    for (var j = 0; j < allFormElements.length; j++) {
        formelem = allFormElements[j];
        if (formelem.elemisrequired == 1 && formelem.sectionIndex > -1) {

            if (("," + idList + ",").indexOf("," + formelem.sectionIndex + ",") > -1)
                continue;

            if (idList.length > 0)
                idList += ",";

            idList += formelem.sectionIndex;
        }
    }
    return idList;
}

function closeSections(index) {
    if (arguments.length == 0)
        index = -1;

    if (jsPlugin == 'fieldsets')
        jsPluginObj.collapse(index);
    else
        jsPluginObj[jsPlugin]('collapse', index);
}

function addSection() {
    if (nextSectionIdx > dynamicSectionIds.length) {
        jQuery('#addSectionWrapper').hide();
        return;
    }

    var section = dynamicSectionIds[nextSectionIdx];
    jQuery('#' + section.id).show();
    if (jsPlugin == 'fieldsets')
        jsPluginObj[jsPluginActivate](section.index);
    else
        jsPluginObj[jsPlugin](jsPluginActivate, section.index);

    if (useQuickLinks) {
        // need to add the new section to the quicklinks dropdown
        var onclick = "javascript:gotoSection(" + nextSectionIdx + ",\"" + section.id + "\")";
        var html = "<p><a id='" + section.id + "__quickLink' href='" + onclick + "'>"
                    + " <span class='sectionNumber'>" + (nextSectionIdx + 1) + ".</span>" + section.formPrompt + "</a></p>";

        jQuery('#quickLinksContent').append(html);

        if (nextSectionIdx == 0)
            jQuery('#quickLinksWrapper').show();
    }
    
    nextSectionIdx += 1;
    if (nextSectionIdx >= dynamicSectionIds.length) {
        jQuery('#addSectionWrapper').hide();
        return;
    }
}

// For IE6 and IE7, we need to fix max width.
// Since most sections are initially hidden, and we can't calculate width until it's visible, 
//   we have to wait for tab changes and then run the fix when it's first opened.
// We'll track whether we've fixed each section so we only do once
function onSectionChange(event, ui) {
    var selectedIndex = ui.newIndex || ui.index;
    if (formFixedWidth > 0 && selectedIndex > -1 && typeof fixedSections[selectedIndex] === 'undefined') {
        fixedSections[selectedIndex] = true;
        var contentId = '';
        if (jsPlugin == 'accordion' || jsPlugin == 'sections')
            contentId = jQuery(ui.newHeader).parent().attr('id');
        else if (jsPlugin == 'tabs')
            contentId = jQuery(ui.panel).attr('id');

        if (contentId.length > 0)
            handleFormFixedWidth('#' + contentId);
    }
    recalcScrollProofIntoView();
}

function handleFormFixedWidth(parentId) {
    if (formFixedWidth <= 0)
        return;

    if (arguments.length == 0)
        parentId = "#w2p_form";

    var promptCellSelector = parentId + " table.poVariItemForm tr:first td:first";
    var inputCellSelector = parentId + " table.poVariItemForm tr:first td:second";
    if (1 == columns)
        inputCellSelector = parentId + " table.poVariItemForm tr:second td:first";

    var promptCellWidthOuter = jQuery(promptCellSelector).outerWidth(true);
    var inputCellWidthOuter = jQuery(inputCellSelector).outerWidth(true);
    var promptCellWidth = jQuery(promptCellSelector).width();
    var inputCellWidth = jQuery(inputCellSelector).width();

    var inputSelectors = parentId + " table.poVariItemForm tr td select"
                       + "," + parentId + " table.poVariItemForm tr td input[type=text]";
    jQuery(inputSelectors).each(function() {
        var element = jQuery(this);
        var w = parseInt(element.width());
        var outerW = parseInt(element.outerWidth(true));

        if (w > 0) {

            if (jsPlugin == 'fieldsets') {
                promptCellWidthOuter = 0;
                promptCellWidth = 0;
                // this element's parent is the input table cell
                inputCellWidthOuter = element.parent().outerWidth(true);
                inputCellWidth = element.parent().width();
                // for 2-column layouts, the prompt table cell is the parent's sibling
                //   (or the parent's parent's first child)
                if (columns == 2) {
                    promptCellWidthOuter = element.parent().siblings("td:first").outerWidth(true);
                    promptCellWidth = element.parent().siblings("td:first").width();
                }
            }

            var padding = (inputCellWidthOuter - inputCellWidth) + (outerW - w);
            var bow = 0;
            var uow = 0;
            if (imageControlsInline) {
                bow = jQuery("input.btnBrowseImage:first", element.parent()).outerWidth(true);
                if (bow && bow > 0)
                    padding += bow;

                uow = jQuery("input.btnUploadImage:first", element.parent()).outerWidth(true);
                if (uow && uow > 0)
                    padding += uow;
            }
            if (jsPlugin != '')
                padding += 42; // 21 on each side

            var widthToCheck = columns == 1 ? outerW : promptCellWidthOuter + outerW;
            if (widthToCheck > formFixedWidth) {
                var newWidth = formFixedWidth - promptCellWidthOuter - padding;
                if (1 == columns) {
                    newWidth = formFixedWidth - padding;
                }

                element.width(newWidth);
            }
        }
    });
}

function handleConditionalVisibility(parent, valuesToCheckFor, animationType, speed, childrenVisibility, children) {
    if (typeof (parent) == 'string')
        parent = jQuery("#" + parent)[0]; // the underlying HTML element - jquery is sorta funky here

    if (!parent.options || !children.length)
        return;

    var selectedValueInList = false;
    var i = 0;
    for (var i = 0; i < valuesToCheckFor.length; i++) {
        if (valuesToCheckFor[i] == parent.options[parent.selectedIndex].value
            || _stripExternalId(valuesToCheckFor[i]) == _stripExternalId(parent.options[parent.selectedIndex].value)) {
            selectedValueInList = true;
            break;
        }
    }

    // cache whether the fields are currently displayed or not
    var isHidden = jQuery("#" + children[0]).css('display') == 'none';
    // check if we want to show the child fields
    if (childrenVisibility) {
        if (selectedValueInList && !isHidden)
            return; // nothing to do since fields are visible

        // we want to show the fields when the selected value is in our list
        // otherwise the value is not in our "show" list, so hide them    
        for (var i = 0; i < children.length; i++) {
            if (selectedValueInList)
                handleConditionalVisibilityShow(children[i], animationType, speed);
            else
                handleConditionalVisibilityHide(children[i], animationType, speed);
        }
    } else {
        // otherwise we want to hide them
        if (selectedValueInList && isHidden)
            return; // nothing to do since fields are hidden

        // we want to hide the fields when the selected value is in our list
        // otherwise the value is not in our "hide" list, so show them
        for (var i = 0; i < children.length; i++) {
            if (selectedValueInList)
                handleConditionalVisibilityHide(children[i], animationType, speed);
            else
                handleConditionalVisibilityShow(children[i], animationType, speed);
        }
    }
}

function handleConditionalVisibilityShow(childId, animationType, speed) {
    var childRow = jQuery("#" + childId);
    var childTd;
    if (isIE6 || isIE7)
        childTd = jQuery("#" + childId + " td");

    switch (animationType) {
        case "fade":
            if (isLoaded) {
                if (childTd) {
                    childTd.hide();
                    childRow.show();
                    childTd.fadeIn(speed, function() { childRow.show(); removeTextAliasFilter(childTd); });
                }
                else
                    childRow.fadeIn(speed, function() { childRow.show(); removeTextAliasFilter(childRow); });
            }
            else
                childRow.show();
            break;
        case "slide":
            if (isLoaded) {
                if (childTd) {
                    childTd.hide();
                    childRow.show();
                    childTd.slideDown(speed, function() { childRow.show(); });
                }
                else
                    childRow.slideDown(speed, function() { childRow.show(); });
            }
            else
                childRow.show();
            break;
        case "highlight":
            childRow.show();
            if (isLoaded)
                childRow.effect("highlight", {}, speed);
            break;
        default:
            childRow.show();
            break;
    }
}

function handleConditionalVisibilityHide(childId, animationType, speed) {
    var childRow = jQuery("#" + childId);
    var childTd;
    if (isIE6 || isIE7)
        childTd = jQuery("#" + childId + " td");

    switch (animationType) {
        case "fade":
            if (isLoaded) {
                if (childTd)
                    childTd.fadeOut(speed, function() { childRow.hide(); });
                else
                    childRow.fadeOut(speed, function() { childRow.hide(); });
            }
            else
                childRow.hide();
            break;
        case "slide":
            if (isLoaded) {
                if (childTd)
                    childTd.slideUp(speed, function() { childRow.hide(); });
                else
                    childRow.slideUp(speed, function() { childRow.hide(); });
            }
            else
                childRow.hide();
            break;
        default:
            childRow.hide();
            break;
    }

    // clearing out child values
    if (isLoaded) {
        var childInputName = childId.replace(/_row_2/i, "").replace(/_row/i, "");
        var childUploadIndex = returnindex(childInputName + '__uploadImage', formName);

        if (childUploadIndex > -1)
            removeLocalImage(childUploadIndex);

        var jQueryObj = jQuery("#" + childInputName);
        if (jQueryObj && jQueryObj.length) {
            var type = jQueryObj[0].type;
            var tag = jQueryObj[0].tagName.toLowerCase(); // normalize case

            // it's ok to reset the value attr of text inputs,
            // password inputs, and textareas
            if (type == 'text' || type == 'password' || tag == 'textarea')
                jQueryObj[0].value = "";
            // checkboxes and radios need to have their checked state cleared
            // but should *not* have their 'value' changed
            else if (type == 'checkbox' || type == 'radio')
                jQueryObj[0].checked = false;
            // select elements need to have their 'selectedIndex' property set to -1 or 0
            // (this works for both single and multiple select elements)
            else if (tag == 'select')
                jQueryObj[0].selectedIndex = 0;
        }
    }
}

function removeTextAliasFilter(jQueryElem) {
    if (isIE && jQueryElem) {
        jQueryElem.each(function() {
            try {
                jQuery(this).get(0).style.removeAttribute('filter');
            } catch (smother) { }
        });
    }
}

var $lastScrollEvent = null;
var $scrollEventDelay = 0;
function scrollProofIntoViewWithDelay() {
    $lastScrollEvent = new Date();
    pollForScrollProofIntoView();
}

function pollForScrollProofIntoView() {
    $scrollEventDelay = new Date() - $lastScrollEvent;
    if ($scrollEventDelay >= 400)
        scrollProofIntoView();
    else
        setTimeout(pollForScrollProofIntoView, 200);
}

var $win;
var $winHeight;
var $proof = null;
var $proofHeight = 0;
var $proofTopOrig = 0;
var $proofClientId = "tblProof";
var $proofParentContainerId = "tdProof";
var $maxOffsetTop = 0;
function scrollProofIntoView() {
    if ($proof == null) {
        $win = jQuery(window);
        $winHeight = $win.height();
        $proof = jQuery("#" + $proofClientId);
        $proofHeight = $proof.height();
        $proofTopOrig = $proof.offset().top;
        $maxOffsetTop = jQuery("#" + $proofParentContainerId).height() - $proofHeight;

        // if the window gets resized let's re-init our viewport height
        $win.bind("resize", function() {
            recalcScrollProofIntoView();
        });
    }

    var viewportTop = $win.scrollTop();
    var viewportBottom = viewportTop + $winHeight;

    var proofTop = $proof.offset().top;
    var proofBottom = proofTop + $proofHeight;

    var targetOffsetTop = viewportTop - $proofTopOrig;
    if (targetOffsetTop < 0)
        targetOffsetTop = 0;
    else if (targetOffsetTop > $maxOffsetTop)
        targetOffsetTop = $maxOffsetTop;

    var isInView = $proofHeight <= $winHeight
        ? viewportTop <= proofTop && viewportBottom >= proofBottom
        : proofTop < viewportBottom && proofBottom > viewportTop;
    var canPositionAtTop = isInView
                            && viewportTop <= $proofTopOrig
                            && viewportBottom >= ($proofTopOrig + $proofHeight)
                            && proofTop > $proofTopOrig;

    if (!isInView) {
        $proof.stop().animate({ marginTop: targetOffsetTop, speed: "fast" });
    } else if (canPositionAtTop) {
        $proof.stop().animate({ marginTop: 0, speed: "fast" });
    }
}

function recalcScrollProofIntoView(execScrollIntoView) {
    if ($proof != null) {
        $winHeight = $win.height();
        $proofHeight = $proof.height();
        $maxOffsetTop = jQuery("#" + $proofParentContainerId).height() - $proofHeight;
        scrollProofIntoViewWithDelay();
    }
}

function _stripExternalId(word) {
    if (word.length == 0)
        return word;

    word = word.replace(/\*\*apos\*\*/g, "'").replace(/\\\"/g, '"');
    var idType = word.indexOf('_') > -1 ? word.substring(0, word.indexOf('_')) : "";
    if (true == _isExternalIdType(idType)) {
        var idValueStartIndex = word.length > idType.length
                                    ? word.indexOf('_', idType.length)
                                    : -1;
        var idValueEndIndex = idValueStartIndex > -1 && word.length > idValueStartIndex
                                    ? word.indexOf('_', idValueStartIndex + 1)
                                    : -1;

        if (idValueStartIndex > -1 && idValueEndIndex > idValueStartIndex && word.length > idValueEndIndex)
            return word.substring(idValueEndIndex + 1);
    }
    return word;
}
function _isExternalIdType(idType) {
    idType = idType.toUpperCase();
    return idType == "VALID"
        || idType == "LIT"
        || idType == "EXTRINSICID"
        || idType == "LIBRARYIMGID"
        || idType == "IMGID"
        || idType == "W2P_LISTITEMIMG"
        || idType == "STYLEID"
        || idType == "CLRID"
        || idType == "FONTID"
        || idType == "PROFILEID"
        || idType == "LIBRARYCLRID";
}