    var arrCascadingLevels = ['CountryCode', 'StateCode', 'ClusterCode'];
    var oUsage;
    var oCountryOfResidence;
    var oCountryCode;
    var oStateCode;
    var oClusterCode;
    var oPromotionCode;
    var oLanguageCode;
    var oCardType;
    var sCulture;
    var bAccordion;
    var sLastProduct;

    function initPricing() {
    
        oUsage = $('#UsageCode');
        oCountryOfResidence = $('#Country');
        oPromotionCode = $('#PromotionCode');
        oStateCode = $('#StateCode');
        oClusterCode = $('#ClusterCode');
        oCountryCode = $('#CountryCode');
        oLanguageCode = $('#LanguageCode');
        oCardType = $('#CardTypeID');
        sCulture = $('#Culture').attr('value');

        logBasketEvent('scOpen,prodView,scAdd', false);

        var bPostedProduct = $('#PostedProduct').attr('value') != '';
        var bHideBlue = $('#HideBlue').attr('value') == 'True';

        if (bPostedProduct) {
            updateProduct($('input.card:checked').attr('value'));
            updatePricing(oClusterCode);
        }
        else if (bHideBlue) {
            updateProduct($('input.card:checked').attr('value'));
            updatePricing(oClusterCode);
        }
        else {
            clearCascade('CountryCode');
        }
        
        $('#CountryCode, #StateCode, #ClusterCode, #UsageCode, #Country').change(function() {
            logBasketEvent('scRemove',true);
            updatePricing(this);
            logBasketEvent('prodView,scAdd',false);
        });
        $('#AccountCustomer, #ApplyPromotion, input.card').click(function() {
            logBasketEvent('scRemove',true);
            updatePricing(this);
            logBasketEvent('prodView,scAdd', false);            
        });

        if (!bHideBlue) {
            var iProductID = $('input.card[checked]').attr('value');
            updateProduct(iProductID);
        }
        var iVal = $('#PaymentMethod[checked],#PaymentMethod2[checked]').attr('value');
        updateDebit(iVal);

        $('#contactLength').change(function() {
            $('.contactlengthhint').hide();
            $('#contactlengthhint' + $('#contactLength').val()).show();
        });
        $('.contactlengthhint').hide();
        $('#contactlengthhint' + $('#contactLength').val()).show();
    }

    function logBasketEvent(sEvent,bLast) {
        try
        {
            var sProd = $('input.card:checked').attr('value')
            var sBWProduct = 'BW' + sProd;
            if (parseInt(sProd) > 4) sBWProduct += '_' + oUsage.val() + '_' + oCountryCode.val();

            var sTrackingProduct = sBWProduct;
            if (bLast) sTrackingProduct = sLastProduct;

            sLastProduct = sBWProduct;

            if ($('#UseAccordion').attr('value') == 'True') {
                s.events = sEvent;
                s.products = ';' + sTrackingProduct;
                s.linkTrackVars = 'events,products';
                s.linkTrackEvents = sEvent;
                s.tl(true, 'o', 'BW Package Change');
            }
        }
        catch (ex) { }
    }

    function initOther() {
        $('#Country').change(function() {
            updateStates($(this), $('#ContactCounty'), $('#ContactState'));
        });

        updateStates($('#Country'), $('#ContactCounty'), $('#ContactState'));
    }

    function initLayout() {
        bAccordion = $('#UseAccordion').attr('value') == 'True';

        if (!bAccordion) {
            $('#PromotionCode').blur(function() {
                if ($(this).val().length > 0 && confirm('Are you sure you want to apply a promo code')) {
                    updatePricing(this);
                }
            });
        }

        if (bAccordion) {
            $('#accordion h4').click(function() {
                return false;
            }).next('*:gt(0)').hide();

            $('#accordion .section').not(':last').append('<div class="next"><a>' + $('#nextText').val() + '</a></div>');
            $('#accordion .section .next').click(function() {
                if (!validateForm()) return false;
                $(this).parent().slideUp();
                $(this).parent().prev().click(function() {
                    $(this).next().slideDown();
                    $('#accordion h4').next(':not(:animated)').slideUp();
                    return false;
                })
                $(this).parent().parent().nextAll().children('h4:visible').eq(0).next().slideDown();
            })
        }
    }
    
    function updateStates(oSender, oTextTarget, oDDTarget) {
        
        if (oSender.attr('value') == 'US') {
            oTextTarget.attr('disabled', true);
            oTextTarget.hide();
            oDDTarget.attr('disabled', false);
            oDDTarget.show();
            $('#CanadaState').attr('disabled', true);
            $('#CanadaState').hide();
            $('#RequireState').show();
        }
        else if (oSender.attr('value') == 'CA') {
            oDDTarget.attr('disabled', true);
            oDDTarget.hide();
            oTextTarget.attr('disabled', true);
            oTextTarget.hide();
            $('#CanadaState').attr('disabled', false);
            $('#CanadaState').show();
            $('#RequireState').show();
        }
        else {
            oDDTarget.attr('disabled', true);
            oDDTarget.hide();
            oTextTarget.attr('disabled', false);
            oTextTarget.show();
            $('#CanadaState').attr('disabled', true);
            $('#CanadaState').hide();
            $('#RequireState').hide();
        }
    }


    function updatePricing(oSender) {
        debugOut('sender', oSender);

        clearCascade(oSender.id);

        var sSender = oSender.id;
        var iProductID = $('input.card:checked').attr('value');
        var sUsage = oUsage.attr('value');
        var sCountryCode = oCountryCode.attr('value');
        var sStateCode = oStateCode.attr('value');
        var sClusterCode = oClusterCode.attr('value');
        var sCountryOfResidence = oCountryOfResidence.attr('value');
        var sPromotionCode = oPromotionCode.attr('value');
        var bInternal = $('#UseAccordion').attr('value') == 'False';
        var sDiscount = $('#Discount').val();

        if (sCountryCode == null) sCountryCode = "";
        if (sStateCode == null) sStateCode = "";
        if (sClusterCode == null) sClusterCode = "";
                       
        var sUrl = '/zsys/ncms/_global_ajax/ajax_pricing.aspx?Sender=' + sSender + '&PromotionCode=' + sPromotionCode + '&ContactCountryCode=' + sCountryOfResidence + '&ProductID=' + iProductID + '&UsageCode=' + sUsage + '&CountryCode=' + sCountryCode + '&StateCode=' + sStateCode + '&ClusterCode=' + sClusterCode + '&Culture=' + sCulture + '&Internal=' + bInternal + '&discount=' + sDiscount;

        debugOut("Url", sUrl);

        // Set loading
        setPrices('annual', 'Loading...');
        setPrices('monthly', 'Loading...');
        $('.promotionplaceholder').hide();
        $('.invalidpromo').hide();
        $('.validpromo').hide();     

        debugOut('JSON URL', sUrl);

        $.getJSON(sUrl, function(data, status) {
            debugOut('Annual', data.Annual);
            debugOut('Monthly', data.Monthly);
            debugOut('Promo', data.Promo);
            debugOut('StateOptions', data.StateOptions);
            debugOut('ClusterOptions', data.ClusterOptions);


            if (data.Error == 'false') {
                setPrices('annual', data.Annual);
                setPrices('monthly', data.Monthly);
                setPrices('quarterly', data.Quarterly);

                $('#StateCode').attr('disabled', data.StateOptions == null);
                $('#ClusterCode').attr('disabled', data.ClusterOptions == null);

                // Only re-populate if these were cleared in the first place
                populateDropDown(oStateCode, data.StateOptions);
                populateDropDown(oClusterCode, data.ClusterOptions);

                var bAllowInvoice = (data.AllowInvoice == 'true');
                if (bAllowInvoice) {
                    $('#PaymentRow').show();
                    if (document.getElementById('PaymentMethod').checked == true) {
                        updateDebit('creditcard');
                    }
                    else updateDebit('invoice');

                }
                else {
                    $('#PaymentRow').hide();
                    document.getElementById('PaymentMethod').checked = true;
                    document.getElementById('PaymentMethod2').checked = false;
                    updateDebit('creditcard');
                }

                if (data.Promo == null && sPromotionCode != '') {
                    $('.invalidpromo').show();
                    $('.validpromo').hide();
                }

                if (data.Promo != null && sPromotionCode != '') {
                    $('.invalidpromo').hide();
                    $('.validpromo').show();
                }

                if (data.Promo != null) {
                    // Promo successful
                    $('.promotionplaceholder .value').text(data.Promo);
                    $('.promotionplaceholder').show();

                    if (document.getElementById('AccountCustomer') != null) {
                        if (document.getElementById('AccountCustomer').checked == false && data.Promo == "100%") {
                            $('#PaymentRow').hide();
                            $('#creditDebit').hide();
                            $('#directDebit').hide();
                        }
                    }
                    else if (data.Promo == "100%") {
                        $('#PaymentRow').hide();
                        $('#creditDebit').hide();
                        $('#directDebit').hide();
                    }
                }
                else {
                    // Promo failed
                    $('.promotionplaceholder').hide();
                }

                clearAll('LanguageCode');
                populateDropDown(oLanguageCode, data.LanguageOptions);

                clearAllButFirst('CardTypeID');
                populateDropDown(oCardType, data.Cards);

            }
            else {
                setPrices('annual', 'Error');
                setPrices('monthly', 'Error');
            }
        });
    }

    function setPrices(sPeriod, sValue) {
        if (sValue != null) {
            $('.' + sPeriod + 'costplaceholder .price').text(sValue);
            $('.' + sPeriod + 'costplaceholder').show();
        }
        else {
            $('.' + sPeriod + 'costplaceholder').hide();
        }
    }

    function populateDropDown(oTarget, arrOptions) {
        if (arrOptions != null && oTarget != null && $('option',oTarget).length <= 1) {
            for (var ii = 0; ii < arrOptions.length; ii++) {
                oTarget.append('<option value="' + arrOptions[ii].Value + '">' + arrOptions[ii].Name + '</option>'); 
            }
        }    
    }

    function clearCascade(sSource) {
        var bStartRemove = false;
        for (var ii = 0; ii < arrCascadingLevels.length; ii++) {
            if (bStartRemove) {
                clearAllButFirst(arrCascadingLevels[ii]);
            }
            if (arrCascadingLevels[ii] == sSource && !bStartRemove) bStartRemove = true;
        }
    }

    function clearAllButFirst(sSource) {
        debugOut("Clearing", sSource);
        var oCtrl = document.getElementById(sSource);
        if (oCtrl == null) return;
        for (var ii = oCtrl.options.length - 1; ii > 0; ii--) {
            oCtrl.options[ii] = null;
        }
    }

    function clearAll(sSource) {
        debugOut("Clearing", sSource);
        var oCtrl = document.getElementById(sSource);
        if (oCtrl == null) {
            return;
        }
        try {
            for (var ii = oCtrl.options.length - 1; ii >= 0; ii--) {
                oCtrl.options[ii] = null;
            }
        }
        catch (ex)
        { }
    }

    function debugOut(sTitle, sMessage) {
        try {
            if (console && console.log) {
                console.log(sTitle + ':', sMessage);
            }
        }
        catch (ex) { }
    }

    $(document).ready(function() {
        initLayout();
        initPricing();
        initOther();
    });



    //////////////////////////////////////////////////////////////////////////////////////////////////////////


    function updateProduct(sValue) {
    
        sDefaultCountry = $('#DefaultCountry').attr('value');
    
        if (sValue == "1") { // blue
            document.getElementById('paymentdetails').style.display = 'none';
            document.getElementById('paymentsSingle').style.display = 'none';
            document.getElementById('agreeTerms').style.display = 'none';
            document.getElementById('terms1').style.display = 'none';
            $('#contractLengthRow').hide();
            //document.getElementById('contactLength').selectedIndex = 1;
        }
        else {
            document.getElementById('paymentdetails').style.display = 'block';
            document.getElementById('agreeTerms').style.display = 'block';
            document.getElementById('terms1').style.display = 'inline';
            $('#contractLengthRow').show();
        }

        if (sValue == "2") {
            document.getElementById('paymentsSingle').style.display = 'none';
            document.getElementById('platinumOptions').style.display = 'block';
            document.getElementById('paymentsOptions').style.display = 'block';
            
            if (sDefaultCountry == 'GB' || sDefaultCountry == 'US') {
                document.getElementById('terms1').href = "/businessworld/gold/termsandconditions.html";
                document.getElementById('terms2').href = "/businessworld/gold/termsandconditions.html";
            }
            $('#UsageCode').val('UN');
            $('#UsageCode').attr("disabled", "disabled");
            
            //$('#contractLengthRow').hide();
            //document.getElementById('contactLength').selectedIndex = 1;
        }
        else {
            $('#UsageCode').removeAttr("disabled");
            document.getElementById('paymentsSingle').style.display = 'none';
        }

        if (sValue == "5" || sValue == "6") { // platinum
            document.getElementById('platinumOptions').style.display = 'block';
            document.getElementById('paymentsOptions').style.display = 'block';
            //$('#paymentsOptions .rowright').hide();
            
            if (sDefaultCountry == 'GB' || sDefaultCountry == 'US') {
                document.getElementById('terms1').href = "/businessworld/plat/termsandconditions.html";
                document.getElementById('terms2').href = "/businessworld/plat/termsandconditions.html";
            }
        }
        else if (sValue != "2") {
            document.getElementById('platinumOptions').style.display = 'none';
            document.getElementById('paymentsOptions').style.display = 'none';
        }
    }

    function updateDebit(sValue) {
        if (sValue == "creditcard") { //credit card
            document.getElementById('creditDebit').style.display = 'block';
        }
        else {
            document.getElementById('creditDebit').style.display = 'none';
        }

        if (sValue == "invoice") { //direct debit
            document.getElementById('directDebit').style.display = 'block';
        }
        else {
            document.getElementById('directDebit').style.display = 'none';
        }
        // AJAX call to update prices
    }

    function validate(sContainer) {

        var bOk = true;
        var errors = '';
        var emailRegEx = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
        var objRegExp = /(^-?\d\d*$)/;

        $((sContainer) + ' .required').each(function(index, item) {
            var oInput = ($('input', item));
            var sLabel = $('label', item).html();
            var oSelect = ($('select', item));

            if (
                (oInput.is(':visible') && oInput[0] != null && oInput[0].value == '') ||
                (oSelect[0] != null && oSelect[0].selectedIndex == 0 && oSelect.is(':visible')) ||
                (oSelect[1] != null && oSelect[1].selectedIndex == 0 && oSelect.is(':visible')) ||
                (oInput.is(':visible') && oInput != null && oInput[0] != null && oInput[0].type == 'checkbox' && oInput[0].checked != true)
            ) {
                $('label', item).addClass('validate');
                $(item).css({ background: "#EEE0E5" });

                //errors += "- " + sLabel.replace('<span class="req">*</span>', '').replace('<SPAN class=req>*</SPAN>', '') + "\r\n";
                errors += "- " + sLabel.replace(/<[^>]+>/g, '').replace('*', '') + "\r\n";

                bOk = false;
            }
            else {

                $('label', item).removeClass('validate');
                $(item).css({ background: "#fff" });
            }

        });

        if ($('#Email').is(':visible')) {

            str = document.getElementById('Email').value;

            if (!str.match(emailRegEx)) {
                errors += "- " + $('#ErrorValidEmail').attr('value') + "\r\n";
                $('#validateEmail1').addClass('validate');
                $('#validateEmail1').css({ background: "#EEE0E5" });
                bOk = false;
            }
            else {
            }
            if ($('#Email').is(':visible') && $('#EmailCheck').is(':visible')) {
                if (document.getElementById('Email').value != document.getElementById('EmailCheck').value) {
                    errors += "- " + $('#ErrorEmailMatch').attr('value') + "\r\n";
                    $('#validateEmail1').addClass('validate');
                    $('#validateEmail1').css({ background: "#EEE0E5" });
                    $('#validateEmail2').addClass('validate');
                    $('#validateEmail2').css({ background: "#EEE0E5" });
                    bOk = false;
                }
                else {
                }
            }
        }
        else {
        }

        if ($('#CentreID').is(':visible')) {
            if (!document.getElementById('CentreID').value.match(objRegExp)) {
                errors += "- " + $('#ErrorValidCentre').attr('value') + "\r\n";
                $('#validateCentre').addClass('validate');
                $('#validateCentre').css({ background: "#EEE0E5" });
                bOk = false;
            }
        }
        else {
        }

        if ($('#CardNumber').is(':visible')) {
            number = document.getElementById('CardNumber').value;

            // Strip any non-digits (useful for credit card numbers with spaces and hyphens)
            var number = number.replace(/\D/g, '');
            if (number.length == 0) {
                bOk = false;
                $('#validateCardNumber').addClass('validate');
                $('#validateCardNumber').css({ background: "#EEE0E5" });
            }
            else {
                // Set the string length and parity
                var number_length = number.length;
                var parity = number_length % 2;

                // Loop through each digit and do the maths
                var total = 0;
                for (i = 0; i < number_length; i++) {
                    var digit = number.charAt(i);
                    // Multiply alternate digits by two
                    if (i % 2 == parity) {
                        digit = digit * 2;
                        // If the sum is two digits, add them together (in effect)
                        if (digit > 9) {
                            digit = digit - 9;
                        }
                    }
                    // Total up the digits
                    total = total + parseInt(digit);
                }

                // If the total mod 10 equals 0, the number is valid
                if (total % 10 == 0) {
                    $('#validateCardNumber').removeClass('validate');
                    $('#validateCardNumber').css({ background: "#fff" });
                } else {
                    errors += "- " + $('#ErrorValidCard').attr('value') + "\r\n";
                    $('#validateCardNumber').addClass('validate');
                    $('#validateCardNumber').css({ background: "#EEE0E5" });
                    bOk = false;
                }
            }
        }


        if ($('#CardExpiryMonth').is(':visible')) {
            var oNow = new Date();
            if (oNow.getFullYear() == $('#CardExpiryYear').val()) {
                if (oNow.getMonth() > document.getElementById('CardExpiryMonth').selectedIndex - 1) {
                    bOk = false;
                    errors += "- " + $('#CardExpiryYear').siblings('label').text() + "\r\n";
                    $('#CardExpiryYear').siblings('label').addClass('validate');
                    $('#CardExpiryYear').parent().css({ background: "#EEE0E5" });              
                }
            }
        }
        
        

        if (errors == '') {
        }
        else {
            alert($('#ErrorEnterFields').attr('value') + "\r\n" + errors);
        }


        return (bOk)
    }

    function validateForm() {
        var bOk = true;

        if (!validate('#applicationform')) {
            bOk = false;
        }
        else {
        }

        return bOk;
    }
    
    
    function SetNameOnCard()
    {
         var noc = document.getElementById('FirstName').value + ' ' + document.getElementById('LastName').value;
         
         if (noc.length > 26) {
            noc = document.getElementById('FirstName').value.substring(0,1) + ' ' + document.getElementById('LastName').value;
         }
         if (noc.length <= 26) {
            document.getElementById('NameOnCard').value = noc;
        }
        else {
            document.getElementById('NameOnCard').value = '';
        }
    }