
/*---------------- Util JS - Handy bits and pieces to make everything else work --------------------*/

function cccs_IsBrowserIE() {
    return (navigator.appName == "Microsoft Internet Explorer");
}

var cccs_mbFireCloseBrowserConfirmation = true;

var cccs_mbFireKillSession = false;

/******************************************************************************
* Please note that there are some moderate differences in the way a radiobutton
* list is rendered depending on whether the control is enabled or disabled.
*    
* When enabled the control is rendered thus:
*    <span>							-- grouping all buttons
*      <input>							-- single button
*      <label>
*      <input>							-- single button
*      <label>
*    </span>
*
* However when disabled the control is rendered as follows:
*    <span disabled="disabled">		-- grouping all buttons
*      <span disabled="disabled">		-- grouping single button
*        <input>						-- single button
*        <label>
*      </span>
*      <span disabled="disabled">		-- grouping single button
*        <input>						-- single button
*        <label>
*      </span>
*    </span>
*
* The scripting code below takes this into account, however should any 
* modifications be required in the future, please take the above into account.
*
*****************************************************************************/
function cccs_isNumeric(txtField, bBlankIsANumber) {
    // A call to parseInt will do it's best to convert a value into a number, so
    // if you enter "9nine" parseInt will just give you the 9 bit as say that's 
    // fine (bit like sprintf used to), which is fine under normal scenarios, but
    // we want the whole field to be numeric
    var arrValidChars = "0123456789,.";
    var isNum = true;
    var cChar;
    var decimalPointCount = 0

    if (txtField.length == 0) {
        if (!bBlankIsANumber) {
            isNum = false;
        }
    }
    else {
        for (var i = 0; i < txtField.length && isNum; i++) {

            if (decimalPointCount == 2) {
                isNum = false;
            }

            cChar = txtField.charAt(i);
            if (cChar == '.') {
                decimalPointCount++;
            }

            if (arrValidChars.indexOf(cChar) == -1) {
                isNum = false;
            }
        }
    }

    return isNum;
}


/*  track the mouse position...  */

var posx; var posy;
function getMouse(e) {
    posx = 0; posy = 0;
    var ev = (!e) ? window.event : e; //IE:Moz
    if (ev.pageX) {//Moz
        posx = ev.pageX + window.pageXOffset;
        posy = ev.pageY + window.pageYOffset;
    }
    else if (ev.clientX) {//IE
        posx = ev.clientX;
        posy = ev.clientY;
    }
    else { return false } //old browsers

}
document.onmousemove = getMouse;





function cccs_parseInteger(sInteger) {
    return parseInt(sInteger.toString().replace(/,/g, ""), 10);
}

function cccs_parseDecimal(sDecimal) {
    return parseFloat(sDecimal.toString().replace(/,/g, ""));
}

function cccs_isValidText(txtId, allowBlank, minLen, maxLen) {
    var bIsOK = true;
    var txtObj = document.getElementById(txtId);
    var txt = "";

    if (txtObj != null)
        txt = cccs_Trim(txtObj.value);

    if (allowBlank && txt.length == 0) {
        bIsOK = true;
    } else {
        if (minLen > -1) {
            if (txt.length < minLen)
                bIsOK = false;
        }
        if (maxLen > -1) {
            if (txt.length > maxLen)
                bIsOK = false;
        }
    }

    return bIsOK;
}

function cccs_isValidNumber(txtId, bBlankIsANumber) {
    var bIsNumber = true;
    try {
        var txtCtl = document.getElementById(txtId);
        var bIsNumeric = cccs_isNumeric(txtCtl.value, bBlankIsANumber);

        if (bBlankIsANumber) {
            // normal field, without a required answer, so blanks are allowed
            if (txtCtl.value.length > 0 && !bIsNumeric) {
                bIsNumber = false;
            }
        }
        else {
            // probably a mandatory field, so blanks aren't consider a number
            if (!bIsNumeric) {
                bIsNumber = false;
            }
        }
    }
    catch (err) {
        bIsNumber = false;
    }
    return bIsNumber;
}

function cccs_isNumberWithinLimits(txtId, bAllowNegative)
// ... note that < 0 is not considered a valid number for our purposes
{
    var bIsWithinLimits = true;
    try {
        var txtCtl = document.getElementById(txtId);
        var dNumber = cccs_parseInteger(txtCtl.value);

        if (txtCtl.value.length > 0)
        // ... will have already dealt with blank fields in the isNumberValid call that 
        // ... _always_ comes before this one, so disregard this
        {
            if (isNaN(dNumber)) {
                bIsWithinLimits = false;
            }
            else {
                // check the lower boundary
                if (bAllowNegative != "undefined" && bAllowNegative) {
                    if (dNumber < -2147483648)
                        bIsWithinLimits = false;
                } else {
                    if (dNumber < 0)
                        bIsWithinLimits = false;
                }

                // check the upper boundary
                if (dNumber > 2147483647)
                    bIsWithinLimits = false;
            }
        }
    }
    catch (err) {
        bIsWithinLimits = false;
    }
    return bIsWithinLimits;
}



function cccs_setfocus(ctlId, bSelectAll) {
    if (document.getElementById(ctlId)) {
        document.getElementById(ctlId).focus();
        if (bSelectAll) {
            document.getElementById(ctlId).select();
        }
    }
}


function cccs_GetXmlHttp() {
    var cccs_oXmlHttp = null;

    // -----> This method was provided from Jim Ley's website 
    /*@cc_on@*/
    /*@if (@_jscript_version >= 5)
    // JScript gives us Conditional compilation, we can cope with old IE versions.
    // and security blocked creation of the objects.
    try {
        cccs_oXmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
        try {
            cccs_oXmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (E) {
            cccs_oXmlHttp = false;
        }
    }
    /*@end@*/


    if (!cccs_oXmlHttp && typeof XMLHttpRequest != 'undefined') {
        cccs_oXmlHttp = new XMLHttpRequest();
    }

    return cccs_oXmlHttp;
}


function cccs_disableClosureEvents() {
    cccs_mbFireCloseBrowserConfirmation = false;
    cccs_mbFireKillSession = false;
}

function cccs_killSession() {
    if (!cccs_mbFireKillSession) {
        return;
    }

    var cccs_oXmlHttpKill = cccs_GetXmlHttp();

    // kill off any previous request
    if (cccs_oXmlHttpKill == null)
        return;

    cccs_oXmlHttpKill.abort();

    var sUrl = 'ScriptCheck.aspx?Action=1';

    // don't expect a result, so just fire and forget
    cccs_oXmlHttpKill.open("GET", sUrl, true);
    cccs_oXmlHttpKill.send(null);
}



function cccs_confirm_exit(evt) {


    if (typeof evt == 'undefined') {

        evt = window.event;
    }

    var blnWasClickOffScreen = false;

    // set blnWasClickOnScreen for firefox
    if (!window.event) {
        blnWasClickOffScreen = (posx < 0 || (posy - (this.outerHeight - this.innerHeight) <= 0))
    }
    else {
        //now for IE
        blnWasClickOffScreen = (window.event.clientX < 0 || window.event.clientY < 0)
    }


    if (blnWasClickOffScreen) {

        if (cccs_mbFireCloseBrowserConfirmation == true) {
            var cfmMsg = '';
            //JUT - 7660
            cfmMsg = "Please click the 'Save & Exit' button to save changes made and to view your web number in order to log back into CCCS Money Matters at a later time.";
            //cfmMsg = "If you are processing client information then you should exit via the 'Save & Exit' button to commit any changes made and then click the ‘logout’ button to close the application correctly.";
            return cfmMsg;
        }


    }
    return;




}

/******************************************************************************
* RadioList Methods
******************************************************************************/

function cccs_isRadioList(radListId) {
    var radListContainer = cccs_getListContainer(radListId, 'RADIO');
    return (radListContainer != null);
}


function cccs_isRadioListSet(radListId) {
    var isSet = false;
    var selectedRadioButton = cccs_getListSelectedItem(radListId, 'RADIO');

    if (selectedRadioButton != null) {
        isSet = true;
    }

    return isSet;
}

function cccs_getRadioListSelectedItem(radListId) {
    return cccs_getListSelectedItem(radListId, 'RADIO');
}


/******************************************************************************
* CheckBoxList Methods
******************************************************************************/

function cccs_isCheckList(chkListId) {
    var chkListContainer = cccs_getListContainer(chkListId, 'CHECKBOX');
    return (chkListContainer != null);
}

function isCheckListSet(chkListId) {
    var isSet = false;
    var selectedCheckButton = cccs_getListSelectedItem(chkListId, 'CHECKBOX');

    if (selectedCheckButton != null) {
        isSet = true;
    }

    return isSet;
}

function getCheckListSelectedItem(chkListId) {
    return cccs_getListSelectedItem(chkListId, 'CHECKBOX');
}


/******************************************************************************
* DropList Methods
******************************************************************************/

function cccs_isDropList(dropListId) {
    var ddlListContainer = cccs_getListContainer(dropListId, 'SELECT');
    return (ddlListContainer != null);
}

function cccs_isDropDownSet(dropListId) {
    var dropListObj = document.getElementById(dropListId);
    var isSet = false;

    if (dropListObj != null) {
        if (dropListObj.selectedIndex != null) {
            isSet = true;
        }
    }
    return isSet;
}


function cccs_isDropDownSelectedItemValid(dropListId, notSelectableCodeId) {
    var dropListObj = document.getElementById(dropListId);
    var isSet = true;

    if (!cccs_isDropDownSet(dropListId)) {
        return false;
    }

    if (notSelectableCodeId != null) {
        // Need to check if the selectedIndex is a particular code.
        // ... if it is then this is consider not set either (i.e. the item in the dropdown is not a selectedable item)
        if (dropListObj.options[dropListObj.selectedIndex].value == notSelectableCodeId) {
            isSet = false;
        }
    }

    return isSet;
}




/******************************************************************************
* TextBox Methods
******************************************************************************/

function cccs_isTextBox(txtId) {
    var txtObj = document.getElementById(txtId);
    var cccs_bisTextBox = false;

    if (txtObj && txtObj.tagName.toUpperCase() == "INPUT" && txtObj.type.toUpperCase() == "TEXT") {
        cccs_bisTextBox = true;
    }

    return cccs_bisTextBox;
}

function cccs_isTextBoxSet(txtId) {
    var isSet = false;

    if (cccs_isTextBox(txtId)) {
        var txtObj = document.getElementById(txtId);
        if (cccs_Trim(txtObj.value).length > 0) {
            isSet = true;
        }
    }

    return isSet;
}


/******************************************************************************
* Hidden Methods
******************************************************************************/

function cccs_isHiddenField(txtId) {
    var hidObj = document.getElementById(txtId);
    var cccs_isHidden = false;

    if (hidObj && hidObj.tagName.toUpperCase() == "INPUT" && hidObj.type.toUpperCase() == "HIDDEN") {
        cccs_isHidden = true;
    }

    return cccs_isHidden;
}

function cccs_isHiddenFieldSet(txtId) {
    var isSet = false;

    if (cccs_isHidden(txtId)) {
        var hidObj = document.getElementById(txtId);
        if (cccs_Trim(hidObj.value).length > 0) {
            isSet = true;
        }
    }

    return isSet;
}


/******************************************************************************
* Misc Util Methods
******************************************************************************/

function cccs_MagicUpdate(txtBox, newColor, origColor) {

    $(txtBox).animate({
        borderColor: newColor
    }, "fast");

    $(txtBox).animate({
        borderColor: origColor
    }, 3500);
}

function cccs_getListContainer(listCtlId, strCheckType) {
    // When looking at a list, the Id we get coming in might be one of the check list items, or
    // the top level span that contains the buttons, or a normal html list (i.e. a SELECT)
    // The purpose here therefore is to return the span and always the span if the list is
    // a radiobutton or checkboxlist and naturally the SELECT tag if the list is an html select
    var listCtlObj = document.getElementById(listCtlId);
    var firstChild = null;
    var listItemContainer = null;

    var aRadioButton = null;

    // The next bit is a hack to let checkbox validation work - if the control does not exist, just exit
    if (!listCtlObj) {
        return false
    }
    // End of checkbox hack - sorry bout that one...

    if (listCtlObj.tagName.toUpperCase() == 'SELECT' && strCheckType.toUpperCase() == 'SELECT') {
        // just a normal dropdown, can only be the SELECT tag we're looking at
        listItemContainer = listCtlObj;
    }
    else if (listCtlObj.tagName.toUpperCase() == 'INPUT' && listCtlObj.type.toUpperCase() == strCheckType.toUpperCase())
    // ... actually pointing at one of the check button children, so find the parent which should be the span
    {
        if (listCtlObj.parentNode.tagName.toUpperCase() == 'SPAN') {
            listItemContainer = listCtlObj.parentNode;

            // problem is if it's a disabled button, then the root span is two levels up!			
            var theFirstChild = getFirstChild(listItemContainer)
            if (listItemContainer.tagName.toUpperCase() == 'SPAN' && $(theFirstChild).attr('disabled') == "TRUE") {
                listItemContainer = listItemContainer.parentNode;
            }
        }
    }
    else if (listCtlObj.tagName.toUpperCase() == 'SPAN')
    // ... might be that we're already at the span container, but make sure it has check buttons in its kids 
    {
        if (listCtlObj.childNodes && listCtlObj.childNodes.length > 0) {
            if (hasChildrenButton(listCtlObj, strCheckType)) {
                // at the holding span on an enabled list
                listItemContainer = listCtlObj;
            }
            else if (hasChildrenButton(listCtlObj.firstChild, strCheckType)) {
                // child child has buttons so we have the holding span on a disabled list
                listItemContainer = listCtlObj;
            }
        }
    }

    return listItemContainer;
}

function hasChildrenButton(listCtl, strCheckType) {
    var hasButton = false;

    if ($(listCtl).children()) {
        for (var nChildNdx = 0; nChildNdx < listCtl.childNodes.length; nChildNdx++) {
            if (listCtl.childNodes[nChildNdx].tagName.toUpperCase() == 'INPUT' &&
				listCtl.childNodes[nChildNdx].type.toUpperCase() == strCheckType.toUpperCase()) {
                hasButton = true;
                break;
            }
        }
    }

    return hasButton;
}



function cccs_getListSelectedItem(listCtlId, strCheckType) {
    var listContainer = cccs_getListContainer(listCtlId, strCheckType);
    var childItem = null;

    if (listContainer == null) {
        return null;
    }

    if (strCheckType == 'SELECT') {
        // normal dropdown, just return the selectedIndex
        if (listContainer.selectedIndex != null) {
            return listContainer.options[listContainer.selectedIndex];
        }
    }
    else if (strCheckType == 'RADIO' || strCheckType == 'CHECKBOX') {
        if (listContainer.childNodes.length > 0) {
            // if the holding control has a "disabled" attribute we have to approach things a little differently, so separate the work out

            if ($(listContainer).attr("disabled"))
            // ... disabled button list
            {
                for (var nDisabledSpanNdx = 0; nDisabledSpanNdx < listContainer.childNodes.length; nDisabledSpanNdx++) {
                    var disabledSpan = listContainer.childNodes[nDisabledSpanNdx];


                    for (var nDisabledSpanChildNdx = 0; nDisabledSpanChildNdx < disabledSpan.childNodes.length; nDisabledSpanChildNdx++) {
                        var disabledCtl = disabledSpan.childNodes[nDisabledSpanChildNdx];
                        //alert(disabledSpan.childNodes[nDisabledSpanChildNdx].value);
                        if (disabledCtl.tagName.toUpperCase() == 'INPUT' && disabledCtl.type.toUpperCase() == strCheckType.toUpperCase()) {
                            // finally found a button, but is it checked?
                            if ($(disabledCtl).attr("checked")) {
                                return disabledCtl;
                            }
                        }
                    } // for
                } // for
            }
            else
            // ... enabled button list
            {
                for (var nChildNdx = 0; nChildNdx < listContainer.childNodes.length; nChildNdx++) {
                    childItem = listContainer.childNodes[nChildNdx];

                    if (childItem.tagName.toUpperCase() == 'INPUT' && childItem.type.toUpperCase() == strCheckType.toUpperCase()) {
                        if ($(childItem).attr("checked")) {
                            return childItem;
                        }
                    }
                } // for
            }
        }
    }

    // didn't find one ticked, so return null
    return null;
}


// retrieves the current selected value of a control, based on it's rendering type
// i.e. if its a textbox, the text is returned, for a ddl the selectedindex value (i.e. guid)
function cccs_getValue(ctlId) {
    if (cccs_isTextBox(ctlId)) {
        // TextBox
        return document.getElementById(ctlId).value;
    }
    else if (cccs_isHiddenField(ctlId)) {
        // Hidden field
        return document.getElementById(ctlId).value;
    }
    else if (cccs_isDropList(ctlId)) {
        // DropdownList
        if (!cccs_isDropDownSet(ctlId)) {
            // nothing selected
            return '';
        }
        else {
            return cccs_getListSelectedItem(ctlId, 'SELECT').value;
        }
    }
    else if (cccs_isRadioList(ctlId)) {
        // RadioList 
        if (!cccs_isRadioListSet(ctlId)) {
            return '';
        }
        else {
            return cccs_getListSelectedItem(ctlId, 'RADIO').value;
        }
    }
    else if (cccs_isCheckList(ctlId)) {
        // CheckList
        if (!cccs_isCheckList(ctlId)) {
            return '';
        }
        else {
            // this currently deals with a checkbox - not a check list.
            return $('#' + ctlId)[0].checked


            //          var list = document.getElementById(ctlId);
            //			var ndx = 0;
            //			for (ndx = 0; ndx < list.childNodes.length; ndx++)
            //			{
            //				return list.childNodes[ndx].value;
            //			}
        }
    }

    return '';
}


// retrieves the current selected text of a control, based on it's rendering type
// i.e. if its a textbox, the text is returned, for a ddl the selectedIndex TEXT is return (i.e. what the user sees)
function cccs_getText(ctlId) {
    if (cccs_isTextBox(ctlId)) {
        return document.getElementById(ctlId).value;
    }
    else if (cccs_isDropList(ctlId)) {
        // DropdownList
        if (!cccs_isDropDownSet(ctlId)) {
            // nothing selected
            return '';
        }
        else {
            return cccs_getListSelectedItem(ctlId, 'SELECT').text;
        }
    }
    else if (cccs_isRadioList(ctlId)) {
        // RadioList
        alert('RadioButton lists are not yet supported for "cccs_getText"');
    }
    else if (cccs_isCheckList(ctlId)) {
        // CheckList
        alert('CheckBox lists are not yet supported for "cccs_getText"');
    }

    return '';
}


/******************************************************************************
* Disabling Functions
******************************************************************************/
function cccs_isDisabled(ctlId) {
    // works out if a control is disabled
    // ... note the control can also be disabled on the row as well as the control itself
    var parent = document.getElementById(ctlId);

    if (parent.disabled) {
        return true;
    }

    if (parent.isDisabled) {
        return true;
    }

    while (parent != null && parent.tagName != 'TD' && parent.tagName != 'LI') {
        parent = parent.parentNode;
    }

    var cccs_bisDisabled = false;
    if (parent != null) {
        if (parent.disabled) {
            cccs_bisDisabled = true;
        }
    }
    return cccs_bisDisabled;
}


function cccs_disableControl(ctlId, bDisable) {
    // disable the li the control is on, and all it's children


    var parent = $('#' + ctlId);
    var exit = false;

    while (exit == false) {
        if (!parent.length) {
            exit = true;
        }
        else if (parent.attr("tagName") == "LI" || parent.attr("tagName") == "li") {
            exit = true;
        }
        else {
            parent = parent.parent();
        }
    }

    if (parent != null) {
        if (bDisable) {
            parent.attr("disabled", "disabled");
            parent.find("input, select").attr("disabled", "disabled");
            parent.find("input, select").removeClass("disabled");
            parent.addClass("disabled");

        }
        else {
            parent.removeAttr("disabled");
            parent.find("input, select").removeAttr("disabled");
            parent.find("input, select").removeClass("disabled");
            parent.removeClass("disabled");

        }
    }

}

/******************************************************************************
* Hiding Functions
******************************************************************************/
function cccs_isHidden(ctlId) {
    // works out if a control is hidden
    // ... note the control can also be hidden on the row as well as the control itself!
    var parent = document.getElementById(ctlId);

    if (parent.style.visibility == 'hidden' || parent.style.display == 'none') {
        return true;
    }

    while (parent != null && parent.tagName != 'LI') {
        parent = parent.parentNode;
    }

    var cccs_bisHidden = false;
    if (parent != null) {
        if (parent.style.visibility == 'hidden' || parent.style.display == 'none') {
            cccs_bisHidden = true;
        }
    }

    return cccs_bisHidden;
}

function cccs_hideControl(ctlId, bHide) {
    // hide the row the control is on, not the control itself
    var parent = document.getElementById(ctlId);

    // FJ: Haven't a clue why this is here (no doubt we'll remember when we integrate eDR)!
    //	while (parent != null && parent.tagName != 'TR') {
    //		parent = parent.parentNode;
    //	}

    var strVisibility = (bHide) ? 'hidden' : 'visible';
    var strDisplay = (bHide) ? 'none' : 'block';

    if (parent.style.visibility != strVisibility) {
        parent.style.visibility = strVisibility;
    }
    if (parent.style.display != strDisplay) {
        parent.style.display = strDisplay;
    }
}

// used by the navigation control to hide it's buttons after submission

function cccs_toggleButtons(disableButtons) {
    if (!document)
        return;

    var docButtons = document.getElementsByTagName('input');

    for (var n = 0; n < docButtons.length; n++) {
        var button = docButtons[n];

        if (button.type.toLowerCase() == 'image') {
            if (disableButtons) {
                if (button.className.length > 0)
                    button.className = button.className + ' ' + 'disabled';
                else
                    button.className = 'disabled';
                //button.disabled = true;
            }
            else {
                button.className = button.className.replace(/disabled/, '');
                //button.disabled = false;
            }
        }
    }
    return true;
}




function cccs_disableButtons() {
    cccs_toggleButtons(true);
}

function cccs_enableButtons() {
    cccs_toggleButtons(false);
}


function cccs_OnPageValid() {



    // greyout the screen to tell the user we are loading and moving to the next page...	
    cccs_greyOut(true, { 'zindex': '50', 'bgcolor': '#000000', 'opacity': '30' });

    // add a loading message to the screen...
    var tbody = document.getElementsByTagName("body")[0];
    var tnode = document.createElement('div');         // Create the layer.      
    //tnode.style.display = 'none';                     // Start out Hidden
    tnode.id = 'loadingMsg'; 						 // Name it so we can find it later
    tnode.className = "loadingMsg"; 				// set the css class
    tnode.innerHTML = "Loading... <img src='midway/cccs/images/ajax-loader.gif' alt='loading' />"; // add some content   
    tbody.appendChild(tnode);  // Add it to the web page

    // centre the message...
    var winW = $(window).width();
    var centerDiv = $('#loadingMsg');
    centerDiv.css('left', winW / 2 - centerDiv.width() / 2);

    $("#loadingMsg").show("fast");
}

function cccs_OnPageInvalid() {
    // on error, scroll to the top of the window 
    // so you can see the error message...
    scroll(0, 60);
    cccs_mbFireCloseBrowserConfirmation = true;
}


/******************************************************************************
* General Functions
******************************************************************************/

function cccs_greyOut(vis, options) {
    // Pass true to grey out screen, false to ungray
    // options are optional.  This is a JSON object with the following (optional) properties
    // opacity:0-100         // Lower number = less greyout higher = more of a blackout 
    // zindex: #             // HTML elements with a higher zindex appear on top of the grey out
    // bgcolor: (#xxxxxx)    // Standard RGB Hex color code
    // greyOut(true, {'zindex':'50', 'bgcolor':'#0000FF', 'opacity':'70'});
    // Because options is JSON opacity/zindex/bgcolor are all optional and can appear
    // in any order.  Pass only the properties you need to set.
    var options = options || {};
    var zindex = options.zindex || 50;
    var opacity = options.opacity || 70;
    var opaque = (opacity / 100);
    var bgcolor = options.bgcolor || '#000000';
    var dark = document.getElementById('darkenScreenObject');
    if (!dark) {

        var tbody = document.getElementsByTagName("body")[0];
        var tnode = document.createElement('div');           // Create the layer.
        tnode.style.position = 'absolute';                 // Position absolutely
        tnode.style.top = '0px';                           // In the top
        tnode.style.left = '0px';                          // Left corner of the page
        tnode.style.overflow = 'hidden';                   // Try to avoid making scroll bars            
        tnode.style.display = 'none';                      // Start out Hidden
        tnode.id = 'darkenScreenObject';                   // Name it so we can find it later
        tbody.appendChild(tnode);                            // Add it to the web page
        dark = document.getElementById('darkenScreenObject');  // Get the object.
    }
    if (vis) {
        // Calculate the page width and height 
        if (document.body && (document.body.scrollWidth || document.body.scrollHeight)) {
            var pageWidth = document.body.scrollWidth + 'px';
            var pageHeight = document.body.scrollHeight + 'px';
        } else if (document.body.offsetWidth) {
            var pageWidth = document.body.offsetWidth + 'px';
            var pageHeight = document.body.offsetHeight + 'px';
        } else {
            var pageWidth = '100%';
            var pageHeight = '100%';
        }
        //set the shader to cover the entire page and make it visible.
        dark.style.opacity = opaque;
        dark.style.MozOpacity = opaque;
        dark.style.filter = 'alpha(opacity=' + opacity + ')';
        dark.style.zIndex = zindex;
        dark.style.backgroundColor = bgcolor;
        dark.style.width = pageWidth;
        dark.style.height = pageHeight;
        dark.style.display = 'block';
    } else {
        dark.style.display = 'none';
    }
}



//Stop text box entry being over certain length      
function LimitTo(vals) {
    if (vals != undefined) {
        if (vals.length > 0) {
            if (vals.control.val().length > vals.length) {
                vals.control.val(vals.control.val().substr(0, vals.length));
            }
        }
    }
}



function cccs_Trim(str) {
    // only try and cccs_Trim strings, otherwise you lose the underlying type
    if (typeof (str) != "string") {
        return str;
    }
    return cccs_LTrim(cccs_RTrim(str));
}

function cccs_LTrim(str) {
    // only try and cccs_Trim strings, otherwise you lose the underlying type
    if (typeof (str) != "string") {
        return str;
    }

    if (cccs_iswhitespace(str)) {
        return "";
    }

    var nFirstNonWs = 0;
    var n = 0;

    while (n != str.length && str.charAt(n) == " ") {
        n++;
    }

    if (n < str.length) {
        nFirstNonWs = n;
    }

    return str.substring(nFirstNonWs, str.length);
}

function cccs_iswhitespace(str) {
    var bHasNonWs = false;
    for (var i = 0; i < str.length; i++) {
        if (str.charAt(i) != " ") {
            return false;
        }
    }
    return true;
}

function cccs_RTrim(str) {
    // only try and cccs_Trim strings, otherwise you lose the underlying type
    if (typeof (str) != "string") {
        return str;
    }

    if (cccs_iswhitespace(str)) {
        return "";
    }

    var nLastNonWs = str.length;
    var n = str.length - 1;

    while (n != 0 && str.charAt(n) == " ") {
        n--;
    }

    if (n > 0) {
        nLastNonWs = n + 1;
    }

    return str.substring(0, nLastNonWs);
}

function cccs_toUpper(ctlId) {
    if (!cccs_isTextBox(ctlId)) {
        return;
    }

    var txtbox = document.getElementById(ctlId);

    if (txtbox) {
        txtbox.value = txtbox.value.toUpperCase();
    }
}

function cccs_toLower(ctlId) {
    if (!cccs_isTextBox(ctlId)) {
        return;
    }

    var txtbox = document.getElementById(ctlId);

    if (txtbox) {
        txtbox.value = txtbox.value.toLowerCase();
    }
}

function cccs_toTrim(ctlId) {
    if (!cccs_isTextBox(ctlId)) {
        return;
    }

    var txtbox = document.getElementById(ctlId);

    if (txtbox) {
        txtbox.value = cccs_Trim(txtbox.value);
    }
}

function cccs_commafy(val) {
    var pos;
    var isNeg = false;

    val = val.split(",").join(""); // remove existing commas if present.

    if (val.indexOf("-") >= 0) {
        isNeg = true;
        val = val.replace(/-/gi, "");
    }

    var dot = val.indexOf("."); // locate decmal
    if (dot < 0) {
        dot = val.length; // use end if no decimal
    }

    var r = "";
    for (pos = dot - 3; pos >= 1; pos -= 3) { // put commas in 
        r = "," + val.substr(pos, 3) + r;
    }
    r = val.substring(0, pos + 3) + r; // put start of string on
    dot = val.indexOf("."); // check for decimal
    if (dot > 0) {
        r += val.substring(dot); // put fraction part on
    }

    // was this originally negative?
    if (isNeg)
        r = "-" + r;

    return r;
}

function cccs_removeIllegalChars(strNum) {
    // just rmeoves spaces and £-signs and commas for the time being
    return strNum.toString().replace(/[£ ,]/g, "");
}

function cccs_reformatNumber(ctl) {

    //ctl is the name of the control which should have it's number reformatted
    var stVal;
    stVal = document.getElementById(ctl).value;

    if (stVal != '0') {
        stVal = stVal.replace(/^[0]+/g, "");
    }

    stVal = cccs_removeIllegalChars(stVal);
    stVal = cccs_getTypedValue(stVal, 'INT');



    if (isNaN(stVal) == false) {
        stVal = cccs_commafy(cccs_getTypedValue(stVal, 'CHAR'));
        document.getElementById(ctl).value = stVal;
    }
}

function cccs_reformatNumberOfText(strNumber) {
    strNumber = cccs_removeIllegalChars(strNumber);
    strNumber = cccs_commafy(strNumber);

    return strNumber;
}

function cccs_daysInMonth(dd, yyyy) {
    switch (dd) {
        case 4:
        case 6:
        case 9:
        case 11:
            return 30;

        case 2:
            return cccs_daysInFebruary(yyyy);

        default:
            return 31;
    }
}

function cccs_daysInFebruary(year) {
    // February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (((year % 4 == 0) && ((!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28);
}

function cccs_isValidDate(strYYYY, strMM, strDD) {
    var dd = cccs_parseInteger(strDD);
    var mm = cccs_parseInteger(strMM);
    var yyyy = cccs_parseInteger(strYYYY);

    if (mm < 0 || mm > 12) {
        return false;
    }
    if (dd < 0 || dd > 31) {
        return false;
    }
    if (dd > cccs_daysInMonth(mm, yyyy)) {
        return false;
    }

    return true;
}



function cccs_NewWindow(mypage, myname, maxWidth, maxHeight, pos, overrides) {
    var myleft; var mytop; var settings; var myNewWindow; var features = "";

    // assume for now we want whatever's available
    var width = screen.availWidth;
    var height = screen.availHeight - 30; // 30 to compensate for the title bar

    if (maxWidth != null && maxWidth < width)
        width = maxWidth;
    if (maxHeight != null && maxHeight < height) {
        height = maxHeight;
    }

    if (pos == "random") {
        myleft = (screen.width) ? Math.floor(Math.random() * (screen.width - width)) : 100;
        mytop = (screen.height) ? Math.floor(Math.random() * ((screen.height - height) - 75)) : 100;
    }
    if (pos == "center") {
        myleft = (screen.width) ? (screen.width - width) / 2 : 100;
        mytop = (screen.height) ? (screen.height - height) / 2 : 100;
    }
    else if ((pos != 'center' && pos != "random") || pos == null) {
        myleft = 0;
        mytop = 0;
    }

    if (overrides == null || typeof overrides != "object") {
        overrides = new Object();
    }

    if (overrides['scrollbars'] == undefined) overrides['scrollbars'] = "no";
    if (overrides['location'] == undefined) overrides['location'] = "no";
    if (overrides['directories'] == undefined) overrides['directories'] = "no";
    if (overrides['status'] == undefined) overrides['status'] = "no";
    if (overrides['menubar'] == undefined) overrides['menubar'] = "no";
    if (overrides['toolbar'] == undefined) overrides['toolbar'] = "no";
    if (overrides['resizable'] == undefined) overrides['resizable'] = "no";

    features =
		"scrollbars=" + overrides['scrollbars'] + "," +
		"location=" + overrides['location'] + "," +
		"directories=" + overrides['directories'] + "," +
		"status=" + overrides['status'] + "," +
		"menubar=" + overrides['menubar'] + "," +
		"toolbar=" + overrides['toolbar'] + "," +
		"resizable=" + overrides['resizable'];

    settings =
		"width=" + width +
		",height=" + height +
		",top=" + mytop +
		",left=" + myleft +
		"," + features;

    myNewWindow = window.open(mypage, myname, settings);
    myNewWindow.focus();

    return myNewWindow;
}






/*------------------ Validation JS - Custom validators - Franz' Clever OO business ------------------*/

// javascript enums
var cccs_eStateType = {
    Unknown: 255,
    Valid: 0,
    Ignored: 1,
    OutOfRange: 2,
    Mandatory: 3,
    TypeInvalid: 4,
    AreYouSure: 5,
    Invalid: 6,
    MandatorySuggExp: 7,
    DateInvalid: 8,

    fromString:
		function(strStateType) {
		    var numStateType = cccs_parseInteger(strStateType);

		    if (numStateType < cccs_eStateType.Valid || numStateType > cccs_eStateType.DateInvalid) {
		        // dunno what this is
		        numStateType = cccs_eStateType.Unknown;
		    }

		    return numStateType;
		}
}

var cccs_eDirType = {
    Unknown: -1,
    Forward: 0,
    Backward: 1,
    Finish: 2,
    Away: 3,
    Refresh: 4,

    fromString:
		function(strDirType) {
		    var numDirType = cccs_parseInteger(strDirType);

		    if (numDirType < cccs_eDirType.Unknown || numDirType > cccs_eDirType.Refresh) {
		        // dunno what this is!
		        numDirType = cccs_eDirType.Unknown;
		    }

		    return numDirType;
		}
}

function cccs_directionType(sender) {
    var strDirType = cccs_eDirType.Unknown;
    if (!e) var e = window.event

    if (e != null) {
        if (e.srcElement && e.srcElement.attributes && e.srcElement.attributes.length > 0 && e.srcElement.attributes['directionType']) {
            if (e.srcElement.attributes['directionType'].nodeValue) {
                strDirType = e.srcElement.attributes['directionType'].nodeValue;
            }
            else {
                strDirType = cccs_eDirType.Unknown;
            }
        }
        else {
            strDirType = cccs_eDirType.Unknown;
        }
    } else if (currentButton) {
        strDirType = currentButton.attributes["directionType"].value;
    }

    return cccs_eDirType.fromString(strDirType);
}

/******************************************************************************
* Class Definition: cccs_classErrorMessages
******************************************************************************/
var cccs_moErrorMessages = new cccs_classErrorMessages();
function cccs_classErrorMessages() {
    this.m_arrMessageText = new Object();
    this.m_strValidatorId = null;
}

cccs_classErrorMessages.prototype.addErrorMessageText =
	function(errMsgNumber, errMsgText) {
	    if (typeof (errMsgNumber) == "string") {
	        errMsgNumber = cccs_parseInteger(errMsgNumber);
	    }

	    this.m_arrMessageText[errMsgNumber] = errMsgText;
	};

cccs_classErrorMessages.prototype.cccs_getText =
function(errMsgNumber) {
    if (typeof (errMsgNumber) == "string") {
        errMsgNumber = cccs_parseInteger(errMsgNumber);
    }

    if (this.m_arrMessageText[errMsgNumber] != null) {
        return this.m_arrMessageText[errMsgNumber];
    }
    else {
        return '';
    }
};

cccs_classErrorMessages.prototype.set_validatorId =
	function(validatorId) {
	    this.m_strValidatorId = validatorId;
	};

cccs_classErrorMessages.prototype.get_validatorId =
	function() {
	    return this.m_strValidatorId;
	};



function cccs_showErrorMsg(errCtlId, nPageState) {
    var strErrMsg = '';
    var ctl = document.getElementById(errCtlId);
    var bShowMsg = true;

    if (typeof nPageState == "string")
    // OK must be a message generated by additional page validation, so override the whole StateTypeEnum and just use
    // the message
        strErrMsg = nPageState;
    else {
        strErrMsg = cccs_moErrorMessages.cccs_getText(nPageState);

        if (nPageState == cccs_eStateType.Ignored || nPageState == cccs_eStateType.AreYouSure) {
            bShowMsg = false;
        }
    }

    if (ctl != null && bShowMsg && strErrMsg.length > 0) {
        ctl.visibility = 'visible';
        ctl.display = 'block';
        ctl.style.visibility = 'visible';
        ctl.style.display = 'block';

        ctl.innerHTML = strErrMsg;
    }
    else {
        cccs_hideErrMsg(errCtlId);
    }
}

function cccs_showErrMsg(errCtlId) {
    var ctl = document.getElementById(errCtlId);

    if (ctl != null) {
        ctl.visibility = 'visible';
        ctl.display = 'block';
    }
}

function cccs_hideErrMsg(errCtlId) {
    var ctl = document.getElementById(errCtlId);

    if (ctl != null) {
        ctl.visibility = 'hidden';
        ctl.display = 'none';
        ctl.innerHTML = "";
    }
}


function cccs_setIndicator(indicatorId, strSetWith) {
    if (document.getElementById(indicatorId) != null) {
        document.getElementById(indicatorId).innerHTML = strSetWith;
    }
}

function cccs_setOkIndicator(indicatorId) {

    cccs_setIndicator(indicatorId, ' ');
}

function cccs_setErrorIndicator(indicatorId, strIndicator) {

    cccs_setIndicator(indicatorId, strIndicator);
    /*	$('#' + indicatorId).parent().parent('li').attr("style", "background-color:red"); */
}



/******************************************************************************
* Class Definition: classFreqMap
******************************************************************************/

var cccs_cnFreqMultiple_Weekly = 4.333333;
var cccs_cnFreqMultiple_Fortnightly = 2.166666;
var cccs_cnFreqMultiple_4Weekly = 1.083333;
var cccs_cnFreqMultiple_Monthly = 1;
var cccs_cnFreqMultiple_Quarterly = 0.333333;
var cccs_cnFreqMultiple_Annually = 0.083333;

var cccs_cstrFreqText_Weekly = "Weekly";
var cccs_cstrFreqText_Fortnightly = "Fortnightly";
var cccs_cstrFreqText_4Weekly = "4-weekly";
var cccs_cstrFreqText_Monthly = "Monthly";
var cccs_cstrFreqText_Quarterly = "Quarterly";
var cccs_cstrFreqText_Annually = "Annually";

function cccs_FrequencyNameToDesc(strFreqName) {
    switch (strFreqName) {
        case cccs_cstrFreqText_Weekly: return 'per week';
        case cccs_cstrFreqText_Fortnightly: return 'per fortnight';
        case cccs_cstrFreqText_4Weekly: return 'every 4 weeks';
        case cccs_cstrFreqText_Monthly: return 'per month';
        case cccs_cstrFreqText_Quarterly: return 'per quarter';
        case cccs_cstrFreqText_Annually: return 'per annum';
        default: return 'unknown frequency';
    }
}


/******************************************************************************
* Class Definition: cccs_classSearchReplace
******************************************************************************/
function cccs_classSearchReplace() {
    this.m_arrSearchReplaceMap = new Object();
}

cccs_classSearchReplace.prototype.addTokens =
	function(sSearchFor, sReplaceWith) {
	    this.m_arrSearchReplaceMap[sSearchFor] = sReplaceWith;
	};

cccs_classSearchReplace.prototype.getConversion =
	function(sSourceText) {
	    var strMsg = sSourceText;
	    var sSearchFor;
	    var sReplaceWith;

	    for (var i in this.m_arrSearchReplaceMap) {
	        sSearchFor = i;
	        sReplaceWith = this.m_arrSearchReplaceMap[i];

	        if (sReplaceWith == null) {
	            sReplaceWith = '';
	        }

	        var re = new RegExp(sSearchFor, '');
	        sReplaceWith = this.m_arrSearchReplaceMap[i];

	        strMsg = strMsg.replace(re, sReplaceWith);
	        re = null;
	    }

	    return strMsg;
	};


/******************************************************************************
* Class Definition: cccs_classTobaccoGuideline
******************************************************************************/
function cccs_classTobaccoGuideline(guidelineList, lowerRange, upperRange, literalReduction, percentReduction)
// record constructor
{
    this.OwnerList = guidelineList;
    this.LowerRange = lowerRange;
    this.UpperRange = upperRange;
    this.LiteralReduction = literalReduction;
    this.PercentReduction = percentReduction;
}

cccs_classTobaccoGuideline.prototype.getSuggestedExpenditure =
	function() {
	    var nSuggestedExpenditure = 0;

	    if (this.LiteralReduction != null) {
	        nSuggestedExpenditure = (this.OwnerList.m_nCurrentExpenditure + this.LiteralReduction);
	    }
	    else {
	        var fReductionPercentage = 0;

	        fReductionPercentage = (Math.abs(this.PercentReduction / 100.0));
	        nSuggestedExpenditure = this.OwnerList.m_nCurrentExpenditure * fReductionPercentage;
	    }

	    return cccs_reformatNumberOfText(Math.ceil(nSuggestedExpenditure));
	};


/******************************************************************************
* Class Definition: cccs_classTobaccoGuideline
******************************************************************************/
function cccs_classTobaccoGuidelines()
// list constructor
{
    this.count = 0;
    this.m_arrTobaccoGuidelines = new Object();
    this.m_nCurrentExpenditure = 0;
    this.m_bWarnClient = false;
}

cccs_classTobaccoGuidelines.prototype.addGuideline =
	function(lowerRange, upperRange, literalReduction, percentReduction) {
	    this.m_arrTobaccoGuidelines[this.count] = new cccs_classTobaccoGuideline(this, lowerRange, upperRange, literalReduction, percentReduction);
	    this.count += 1;
	};

cccs_classTobaccoGuidelines.prototype.getSuggestedReduction =
	function(pCurrentExpenditure) {
	    var gl = null;

	    this.m_nCurrentExpenditure = cccs_parseInteger(pCurrentExpenditure);

	    for (var index in this.m_arrTobaccoGuidelines) {
	        gl = this.m_arrTobaccoGuidelines[index];

	        if (this.m_nCurrentExpenditure >= gl.LowerRange && this.m_nCurrentExpenditure <= gl.UpperRange) {
	            this.m_bWarnClient = true;
	            return gl;
	        }
	    }
	    this.m_WarnClient = false;
	    return null;
	};

cccs_classTobaccoGuidelines.prototype.getCurrentExpenditure =
	function() {
	    return this.m_nCurrentExpenditure;
	};

function copyOrigTobaccoValue(tobFieldID) {
    var tobBox = document.getElementById(tobFieldID);
    var hidTobStart = document.getElementById('hidTobStartValue');

    if (hidTobStart.value.length == 0 || cccs_parseInteger(hidTobStart.value) == 0) {
        // only do this the first time something is entered (as this is what we're reducing from)
        hidTobStart.value = tobBox.value;
    }
}

function setTobaccoMax(maxValue) {
    var tobMaxF = document.getElementById('hidTobMaxValue');

    if (tobMaxF.value == 0) {
        tobMaxF.value = maxValue;
    }
}


/******************************************************************************
* Class Definition: cccs_classDbControlMap
******************************************************************************/

function cccs_classDbControlMap() {
    this.m_mapPageField2Control = new Object();
    this.m_mapControl2PageField = new Object();
    this.m_mapPageField2TiedPageField = new Object();
}

// probably not required as the constructor does the same thing
cccs_classDbControlMap.prototype.resetPageValidation = function() {
    this.m_mapPageField2Control = new Object();
    this.m_mapControl2PageField = new Object();
    this.m_mapPageField2TiedPageField = new Object();
};

cccs_classDbControlMap.prototype.getPageFieldIdFromMap = function(strControlId) {
    return this.m_mapControl2PageField[strControlId];
};

cccs_classDbControlMap.prototype.getControlIdFromMap = function(strPageFieldId) {
    return this.m_mapPageField2Control[strPageFieldId];
};

cccs_classDbControlMap.prototype.getTiedPageFieldFromMap = function(strPageFieldId) {
    return this.m_mapPageField2TiedPageField[strPageFieldId];
};


cccs_classDbControlMap.prototype.getTiedValue = function(strSrcPageFieldId) {
    var strValue = '';
    var tiedPageFieldId = this.getTiedPageFieldFromMap(strSrcPageFieldId);

    if (tiedPageFieldId != null) {
        var tiedCtlId = this.getControlIdFromMap(tiedPageFieldId);
        strValue = cccs_getValue(tiedCtlId);
    }
    return strValue;
};

cccs_classDbControlMap.prototype.getTiedText = function(strSrcPageFieldId) {
    var strText = '';
    var tiedPageFieldId = this.getTiedPageFieldFromMap(strSrcPageFieldId);

    if (tiedPageFieldId != null) {
        var tiedCtlId = this.getControlIdFromMap(tiedPageFieldId);
        strText = cccs_getText(tiedCtlId);
    }
    return strText;
};

cccs_classDbControlMap.prototype.addMapping = function(strPageFieldId, strControlId, strTiedPageFieldId) {
    // Use two maps so we can map:
    //    PageFieldID  -> Page control
    //	  Page control -> PageFieldID
    this.m_mapPageField2Control[strPageFieldId] = strControlId;
    this.m_mapControl2PageField[strControlId] = strPageFieldId;

    if (strTiedPageFieldId == '') {
        this.m_mapPageField2TiedPageField[strPageFieldId] = null;
    }
    else {
        this.m_mapPageField2TiedPageField[strPageFieldId] = strTiedPageFieldId;
    }
};



/******************************************************************************
* Class Definition: cccs_classTargets
******************************************************************************/
function cccs_classTargets() {
    this.arrTargets = null;
    this.nTargetCount = -1;
    this.nTargetIndex = -1;
}

cccs_classTargets.prototype.resetTargetsArray =
	function(nArrayCount) {
	    this.nTargetCount = nArrayCount;
	    this.nTargetIndex = 0;
	    this.arrTargets = null;
	    this.arrTargets = new Array(this.nTargetCount);
	};

cccs_classTargets.prototype.addTarget =
	function(gTargetPageFieldID) {
	    this.arrTargets[this.nTargetIndex] = gTargetPageFieldID;
	    this.nTargetCount++;
	    this.nTargetIndex++;
	};



/******************************************************************************
* Class Definition: cccs_classCondition
******************************************************************************/

function cccs_classCondition(sTypeRequired, sGateType, sLhs, sOperand, bIsBlank, gPageFieldDriverID, bUseTiedPageField) {
    this.typeRequired = sTypeRequired;
    this.gateType = sGateType;
    this.lhs = cccs_getTypedValue(sLhs, sTypeRequired);
    this.operand = sOperand;
    this.isBlank = bIsBlank;
    this.pageFieldDriverID = gPageFieldDriverID;
    this.useTiedPageField = bUseTiedPageField;
    //this.rhs = sRhs;
}

cccs_classCondition.prototype.isConditionSatisfied =
	function(oRhs) {
	    switch (this.typeRequired) {
	        case 'INT': return this.evaluate(oRhs);
	        case 'CHAR': return this.evaluate(oRhs);
	        case 'BOOL': return this.evaluate(oRhs);
	        case 'CURRENCY': return this.evaluate(oRhs);
	        case 'DATE': return this.evaluate(oRhs);
	        case 'CODEID': return this.evaluate(oRhs);
	    }
	};

cccs_classCondition.prototype.evaluate =
	function(oRhs) {
	    if (this.isBlank) {
	        switch (this.operand) {
	            // Note that a comparison between < Blank or > Blank doesn't really  
	            // make sense, so we only return true if the RHS is Blank, otherwise it's always false  
	            case '=':
	                // As RHS will be typed, it will be NaN if the Int is blank
	                return ((typeof (oRhs) == "string" && oRhs.length == 0) || (typeof (oRhs) == "number" && isNaN(oRhs)));
	            case '<':
	            case '>':
	            case '<=':
	            case '>=':
	            case '<>':
	            case '!=':
	                // As RHS will be typed, it will be NaN if the Int is blank
	                return ((typeof (oRhs) == "string" && oRhs.length != 0) || (typeof (oRhs) == "number" && !isNaN(oRhs)));
	        }
	    }
	    else {
	        switch (this.operand) {
	            case '=': return (oRhs == this.lhs);
	            case '<': return (oRhs < this.lhs);
	            case '>': return (oRhs > this.lhs);
	            case '<=': return (oRhs <= this.lhs);
	            case '>=': return (oRhs >= this.lhs);
	            case '<>':
	            case '!=': return (oRhs != this.lhs);
	        }
	    }
	};


/******************************************************************************
* Class Definition: cccs_classConditions
******************************************************************************/
function cccs_classConditions() {
    this.clear();
}

cccs_classConditions.prototype.clear =
	function() {
	    this.arrConditions = null;
	    this.arrConditions = new Object();
	    this.count = 0;
	};

cccs_classConditions.prototype.addCondition =
	function(sTypeRequired, sGateType, sLhs, sOperand, bIsBlank, gPageFieldDriverID, bUseTiedPageField) {
	    // create the new conditions object and add it into the array
	    this.arrConditions[this.count] = new cccs_classCondition(sTypeRequired, sGateType, sLhs, sOperand, bIsBlank, gPageFieldDriverID, bUseTiedPageField);

	    // and move the index along for the next allocation
	    this.count++;
	};


cccs_classConditions.prototype.evaluate =
	function(mobjDbControlMap) {
	    var driverCtlId;
	    var sRhsValue;
	    var nIndex;
	    var bContinue = true;
	    var bFullResult = false;
	    var bThisResult = false;
	    var bLastResult = false;
	    var ptrItem = null;
	    var strLastGateType = '';
	    var tiedPageFieldId = null;
	    var tiedCtlId = null;

	    nIndex = 0;
	    while (bContinue) {
	        ptrItem = this.arrConditions[nIndex];

	        // Find the control from the driver
	        driverCtlId = mobjDbControlMap.getControlIdFromMap(ptrItem.pageFieldDriverID);

	        // If this is field is tied to another field (i.e. it's tied to a frequency dropdown) then we need to do a little more work:
	        // ...
	        tiedPageFieldId = mobjDbControlMap.getTiedPageFieldFromMap(ptrItem.pageFieldDriverID);
	        tiedCtlId = mobjDbControlMap.getControlIdFromMap(tiedPageFieldId);
	        if (tiedPageFieldId != null && ptrItem.useTiedPageField) {
	            // tied field, so:
	            if (cccs_isDropList(tiedCtlId)) {
	                // ... and a dropdown
	                // 1 - Get the selected text from the tied dropdown
	                // 2 - Get the value from the input box
	                // 3 - Translate the value input into the monthly equivalent so it can be applied to the condition
	                var strText = cccs_getText(tiedCtlId);
	                sRhsValue = cccs_getMonthlyValue(strText, cccs_getValue(driverCtlId));
	            }
	            else if (cccs_isTextBox(tiedCtlId)) {
	                sRhsValue = cccs_getValue(tiedCtlId);
	            }
	        }
	        else {
	            // normal lookup, so just get the underlying value from the control
	            sRhsValue = cccs_getValue(driverCtlId);
	        }

	        // Ensure we have a typed version of the RHS (LHS will already be typed)
	        sRhsValue = cccs_getTypedValue(sRhsValue, ptrItem.typeRequired);

	        // the control that started this event is the control we need to evaluate for this condition, so evaluate it!
	        bThisResult = ptrItem.isConditionSatisfied(sRhsValue);

	        if (ptrItem.gateType == '') {
	            if (strLastGateType == '') {
	                // first time in and only one to evaluate
	                bFullResult = bThisResult;
	            }
	            else {
	                if (strLastGateType == 'AND') {
	                    // if we passed this time, and last time, AND is successfully evaluated, so allow progress
	                    if (bLastResult && bThisResult) {
	                        // allow continue, and flag we're OK so far
	                        bFullResult = true;
	                    }
	                    else {
	                        // one of the AND ops has failed, so all fails
	                        bFullResult = false;
	                        bContinue = false;
	                    }
	                }

	                if (strLastGateType == 'OR') {
	                    // if we passed this time OR last time we're OK
	                    if (bLastResult || bThisResult) {
	                        bFullResult = true;
	                    }
	                    else {
	                        bFullResult = false;
	                        bContinue = false;
	                    }
	                }

	            }
	        }

	        // for efficiency we can check for an AND failure on the first condition
	        if (ptrItem.gateType == 'AND') {
	            if (!bThisResult) {
	                bFullResult = false;
	                bContinue = false;
	            }
	        }

	        // and flag this result for comparison against it's partner operand in the next loop
	        bLastResult = bThisResult;

	        nIndex += 1;
	        strLastGateType = ptrItem.gateType;
	        if (nIndex == this.count) {
	            bContinue = false;
	        }
	    }

	    return bFullResult;
	};



function cccs_evaluateDate(oLhs, operand, oRhs) {
    var dateLhs = new Date(oLhs);
    var dateRhs = new Date(oRhs);

    return evaluate(dateLhs, operand, dateRhs);
}

function isGuid(value) {

    var pattern = "^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$";
    var exIsGuid = new RegExp();

    exIsGuid.compile(pattern);

    if (exIsGuid.test(value))
        return true;
    else
        return false;
}

function cccs_getTypedValue(sValue, sTypeRequired) {
    var sTypedValue = null;

    if (sTypeRequired == 'CODEID' || isGuid(sValue)) {
        sTypedValue = String(sValue);
        return sTypedValue;
    }

    switch (sTypeRequired) {
        case 'INT':
            if (isNaN(cccs_parseInteger(sValue))) {
                if (isNaN(cccs_parseInteger(Math.ceil(sValue)))) {
                    sTypedValue = cccs_parseInteger(sValue);
                }
                else {
                    if (sValue.length != 0) {
                        sTypedValue = cccs_parseInteger(Math.ceil(sValue));
                    }
                    else {
                        sTypedValue = "";
                    }
                }
            }
            else {
                sTypedValue = cccs_parseInteger(Math.ceil(sValue));
            }
            break;

        case 'CHAR':
            sTypedValue = String(cccs_Trim(sValue));
            break;

        case 'BOOL':
            // Keep in mind that a Bool can be represented by a Boolean flag OR a CodeId
            var sBoolValue = String(sValue);
            if (sBoolValue.length == 1 && (sBoolValue == '1' || sBoolValue == '0')) {
                // true boolean, so convert to a Bool
                if (sBoolValue == '1') {
                    sTypedValue = true;
                }
                else {
                    sTypedValue = false;
                }
            }
            else {
                // probably a CodeId pointing to a Bool, so go through as a string
                sTypedValue = false;
                if (sValue == 'True' || sValue == 'true' || sValue == true) {
                    sTypedValue = true;
                }
            }
            break;

        case 'CURRENCY':
            if (isNaN(cccs_parseInteger(sValue))) {
                sTypedValue = cccs_parseInteger(sValue);
            }
            else {
                sTypedValue = cccs_parseInteger(Math.ceil(cccs_parseInteger(sValue)));
            }
            break;

        case 'DATE':
            sTypedValue = Date.parse(sValue);
            break;
    }
    return sTypedValue;
}

function cccs_getMonthlyValue(strFreqName, strValue) {
    if (strValue == '') {
        // ... if there is no value, doesn't matter what frequency is selected, the answer is still blank
        return '';
    }

    var dValue = cccs_parseInteger(strValue);
    var dMultiple = 0;

    switch (strFreqName) {
        case cccs_cstrFreqText_Weekly: dMultiple = cccs_cnFreqMultiple_Weekly; break;
        case cccs_cstrFreqText_Fortnightly: dMultiple = cccs_cnFreqMultiple_Fortnightly; break;
        case cccs_cstrFreqText_4Weekly: dMultiple = cccs_cnFreqMultiple_4Weekly; break;
        case cccs_cstrFreqText_Monthly: dMultiple = cccs_cnFreqMultiple_Monthly; break;
        case cccs_cstrFreqText_Quarterly: dMultiple = cccs_cnFreqMultiple_Quarterly; break;
        case cccs_cstrFreqText_Annually: dMultiple = cccs_cnFreqMultiple_Annually; break;
    }

    return (dValue * dMultiple);
}


function cccs_getEventType() {
    if (!e) var e = window.event;
    if (e) {
        return e.type;
    }
    else {
        return '';
    }
}

function cccs_getEventTargetId() {
    var theTarget = null;
    if (!e) var e = window.event

    if (e) {
        if (e.srcElement) {
            // ie
            theTarget = e.srcElement;
        }
        else if (e.target) {
            // w3c
            theTarget = e.target;
        }

        // safari workaround (to do with events on text nodes pointing to the innerText rather than the Html control)
        if (theTarget.nodeType == 3) {
            theTarget = theTarget.parentNode;
        }
    }

    //debugger;
    if (theTarget != null) {
        return theTarget.id;
    }
    else {
        return '';
    }
}


// form highlighting...

$(function() {


    if (typeof document.body.style.maxHeight == "undefined") {
        // IE 6 Hack...
        $('.inputnum').removeAttr("style");
        $('input, select').removeAttr("style");
        $('input, select').prev('.poundImage').removeAttr("style");
    }

    // find out if any alement had focus when the page loaded - if so, highlight it
    if (currentButtonType === null) {
        currentButtonType = "nothing"
    }

    if (currentButtonType != "radio" && currentButtonType != "nothing" && currentButtonType != "checkbox" && currentButtonType != "image") {
        $('.intialFocus').attr("style", "border-color:#edb800");
        $('.intialFocus').prev().attr("style", "border-color:#edb800");
    }

    // highlight text boxes on focus
    $('.inputnum').blur(function() {
        $(this).removeAttr("style");
        $(this).prev().removeAttr("style");
    });

    $('.inputnum').focus(function() {
        $(this).attr("style", "border-color:#edb800");
        $(this).prev().attr("style", "border-color:#edb800")
    });

    // Highlight select menus on focus

    if (currentButtonType != "radio" && currentButtonType != "nothing" && currentButtonType != "checkbox" && currentButtonType != "image") {
        $('input, select').blur(function() {
            $(this).removeAttr("style");
        });
    }

    $('input, select').focus(function() {

        if (currentButtonType != "radio" && currentButtonType != "nothing" && currentButtonType != "checkbox" && currentButtonType != "image") {
            $(this).attr("style", "border-color:#edb800");
        }
    });

});


// get a reference to the last clicked button
var currentButton = null;
var currentButtonType = null;

$(document).ready(function() {
    $('input').click(function() {
        currentButton = this;
        currentButtonType = currentButton.getAttribute("type");

    })
    $('input').focus(function() {
        currentButton = this;
        currentButtonType = currentButton.getAttribute("type");
    })


});


function getFirstChild(elm) {
    if (!elm.childNodes.length) {
        return;
    }
    var children = elm.childNodes.length;
    for (var i = 0; i <= children; ++i) {
        if (elm.childNodes[i].nodeType == 1) {
            return elm.childNodes[i];
        }
    }
    return;
}



/******************************************************************************
* Save & Exit Confirm
******************************************************************************/

function saveAndExitConfirm() {

    var SaveAndConfirmAnswer = confirm("Are you sure you wish to exit CCCS Money Matters?");

    if (SaveAndConfirmAnswer) {
        // Close the clientnotes wimdow if it's open
        if (clientnotesWin) {
            clientnotesWin.close()
        }


        // now redirect to exit page    
        window.location = "SaveAndExit.aspx";
    }
    else {
        return false;
    }

}



/******************************************************************************
* are you sure validation
******************************************************************************/

function roundUpVal() {

    var thisForm = document.getElementById("bdy");
    var theMessage = "";



    for (i = 0; i < document.getElementsByTagName("input").length; i++) {

        var thisElement = document.getElementsByTagName("input")[i];
        var thisElementID = document.getElementsByTagName("input")[i].id;
        var thisElementType = document.getElementsByTagName("input")[i].getAttribute("type");

        if (thisElementType == "text") {

            var valRule = thisElement.getAttribute("maxlength");
            var theEntry = thisElement.value;
            var theEntry = theEntry.replace(/\,/g, "") // add the backslash so comma is taken as literal - the g means global, so all are removed
            var theLabelRef = thisElementID.replace(/iTextBox/, "label");
            var thisSelectMenuRef = thisElementID.replace(/iTextBox/, "iDropList");

            // should do this with regex
            thisSelectMenuRef = thisSelectMenuRef.replace(/0$/, '1');
            var thisSelectMenu = document.getElementById(thisSelectMenuRef);


            if (thisSelectMenu) {
                var thisSelectMenuValue = document.getElementById(thisSelectMenuRef).options[document.getElementById(thisSelectMenuRef).selectedIndex].text;

                // now lets do the calculating...
                if (thisSelectMenuValue == "Quarterly") {
                    valRule = valRule * 3;
                }
                if (thisSelectMenuValue == "Weekly") {
                    valRule = (valRule * 12) / 52;
                }
                if (thisSelectMenuValue == "4-weekly") {
                    valRule = (valRule * 12) / 13;
                }
                if (thisSelectMenuValue == "Fortnightly") {
                    valRule = (valRule * 12) / 26;
                }

                if (thisSelectMenuValue == "Annually") {
                    valRule = valRule * 12;
                }
            }


            // var theLabelText = document.getElementById(theLabelRef).innerText - CAN'T USE THIS FIREFOX DOESN'T LIKE IT
            var theLabelHTML = document.getElementById(theLabelRef).innerHTML;
            var theLabelStart = theLabelHTML.indexOf(">");
            var theLabelEnd = theLabelHTML.indexOf("</");
            var theLabelText = theLabelHTML.substring(theLabelStart, theLabelEnd).replace(/>/, "");


            if (parseInt(theEntry) > parseInt(valRule)) {
                theMessage += 'Are you sure "£' + theEntry + '" is the correct value for "' + theLabelText + '"? \n';
            }
        }
    }

    // loop is over - check the string
    if (theMessage.length > 0) {
        theMessage += '\n\nClick Cancel to adjust the amount or OK to continue without adjusting.'

        return confirm(theMessage);

        if (askConfirm) {
            return true;
        } else {
            return false;
        }

    }
    return true;
}


//function feedbackThirdRule() {

//    var txtEmail = document.getElementById("ctl00_ContentPlaceHolder1_txtEmail").value;
//    var txtConfirmEmail = document.getElementById("ctl00_ContentPlaceHolder1_txtConfirmEmail").value;
//    var thirdErrorMessage = document.getElementById("thirdErrorMessage");


//    if (txtEmail.length > 0 && txtConfirmEmail.length == 0) {
//        thirdErrorMessage.style.display = "block";
//        thirdErrorMessage.style.color = "red";
//        return false;
//    } else {
//        return true;
//    }

//    return true;
//}

//function thirdRule() {

//    var thisIsOK = true;

//    //Check if the first validation message is showing
//    //If it is we've already failed so dont bother with this check
//    //If it isn't we passed validation so far, carry out this validation
//    if ($("#ctl00_ContentPlaceHolder1_ValidationSummary1").css("display") == "none") {
//        thisIsOK = feedbackThirdRule();
//    }
//    else { //Hide the email address match message
//        var emailAddressErrorMsg = document.getElementById("thirdErrorMessage");
//        emailAddressErrorMsg.style.display = "none";
//    }
//        
//    if (!thisIsOK) { cccs_ePageState = cccs_eStateType.TypeInvalid; }
//    return thisIsOK;
//}

function ConfirmEmailValidation(source, args) {

    var emailVal = $("#ctl00_ContentPlaceHolder1_txtEmail").val();
    var confirmEmailVal = $("#ctl00_ContentPlaceHolder1_txtConfirmEmail").val();
    
    if(emailVal != confirmEmailVal) {
        args.IsValid = false;
    }
    else {
        args.IsValid = true;
    }
}
