// Global vars
var cc_cpprefs_approval = [];
var nSaveAndContinue = 1;
var sOriginalText = '';

$(document).ready( function() {

    // ========================= LIST OF TAG PROPERTIES FOR LAYOUT & CONTROL ========================= //

    /*

	cclocaliseoutput		(boolean)		Tag property to prevent a radio button from updating the status of the parent fieldset. Used mainly for frequency radios.
	ccoverrideformtype		(string)		Override the form type specified in the fieldset (can be checkbox or radio).
	cciaid					(string)		Tag property to correspond with IA List ID (all CP tags should have this).
    ccmap					(string)		Tag property to map firm's taxonomy to CP tags/prefs.
	cchideinput				(boolean)		Tag property to hide the input tag and effectively create a sub heading in the fieldset.
    ccinnerjsonkey			(string)		Property on inner JSON nodes (to be added to the CRX) for things like alerterTags, hotTopics, contentTypes etc...
    ccrequiresapproval		(boolean)		Tag property to indicate that this option requires approval so we can register it on the cc_approval cookie to display the right messages in the message centre.
    cciaidcheck				(string[])		List of other form elements to select when this is selected
    cciaiduncheck			(string[])		List of other form elements to deselect when this is selected
    ccissubscribe			(boolean)		Use to mark an option as a subscribe switch
    ccdependenton			(string)		Add a single ID of another subscribe option that activates/deactivates this one. It adds a class to the containing <ul> that gets looped and activated when associates subscribe option is checked 
    cciaiduncheckonuncheck	(string[])		List of other form elements to uncheck when this element is unchecked
    ccistoplevel			(boolean)		Denotes a top level tag like sectors or legal areas to ensure titles render and children are visible by degfault
    ccaddleftpad			(boolean)		Adds left padding to the containing li so we can align form options without sliders switches with others that do have them
    ccisinternal			(boolean)		Only shows this option to internal users (e.g. Current Awareness) - not available in js layer but here for reference
    ccrequired				(string)		String denoting text to display when field left blank or unselected
    ccforceselection		(string)		ID of another fieldset that must contain a selection as a result of this input being checked (e.g. a jurisdiction must be selected because an Alerter has been selected)
    cciaidunsubscribe		(stirng[])		List of IA IDs to add to the optOut list when this element is checked
    cciaidunsubscribeOPTIN	(stirng[])		List of additional IA IDs to add to the optIn list when this element is checked (only introduced to add podcasts to publications)

    */

    // ==================================== START: CLICK FUNCTIONS =================================== //
    $('form#prefs_form').on('click', 'input#prefs_form_submit', function(e) {
        preparePreferenceForm();
		e.preventDefault();
    });

    $('form#prefs_form').on('click', 'input#unsubscribe_form_submit', function(e) {
        prepareUnsubscribeForm();
		e.preventDefault();
    });

    // ======================================= START: LISTENERS ====================================== //
    $('form#prefs_form').on('change', 'input.input_checkbox', function(e) {
        setInputCheckBox($(this));
        updateRelated($(this));
        updateChildrenStatic($(this));
        checkDependencies($(this));
		updateSelectionCount();
        evalMandatoryWarning($(this));
        e.preventDefault();
    });

    $('form#prefs_form').on('change', 'input.input_radio', function(e) {
        setInputRadioButton($(this));
        e.preventDefault();
    });

    $('form#prefs_form').on('keyup', 'input.input_text', function(e) {
		setInputText($(this));
        errorTrap($(this));
        e.preventDefault();
    });

	$('form#prefs_form fieldset ul li.cc_isnotsubscribe').on('change', '> input', function(e) {
        openSubMenus($(this).next().children('label'));
		e.preventDefault();
	});

    $('form#prefs_form fieldset').on('change', 'select#input_text_countryName', function(e) {
        loadStatesFromCountry($(this));
        setInputText($(this));
		e.preventDefault();
	});

    $('form#prefs_form fieldset').on('change', 'select#input_text_stateName', function(e) {
        setInputText($(this));
		e.preventDefault();
	});
	
	//alert($('form#prefs_form fieldset select#input_text_countryName').attr('data-original'));
	//$('form#prefs_form fieldset select#input_text_countryName option:selected').trigger('change');

    $('ul#ul_pref_crumb').on('click', 'li a', function(e) {
        switchFormPages($(this));
		e.preventDefault();
	});

	updateSelectionCount();
	
	sOriginalText = $('select#input_text_stateName option:first-child').text();

	//$('form#prefs_form fieldset ul li.cc_isnotsubscribe ul li').on('change', 'input', function(e) {
		//updateSelectionCount();
	//});

    // ================================= START: INITIAL STATES  ====================================== //

    if ($('form#prefs_form').length == 1) {
    	// loadingIcon(true, $('form#prefs_form').not('form.form_unsubscribe'), 'One moment please', 'We are retrieving your details from our database.');
        $('form#prefs_form.form_Internal input:text, form#prefs_form.form_Internal select').prop('disabled', true);
    }

});

// ============================= START: SUBMISSION JSON BUILD FUNCTIONS ============================== //

// Build static JSON nodes for direct text input
function buildJSONNodePersonalDetails(thisFieldset, iFieldset) {
	var sThisNode = "";
    sThisNode += '"' + thisFieldset.data('jsonkey') + '":{';
    sThisNode += '"firstName":"' + cleanUp($('input#input_text_firstName').val()) + '",';
	sThisNode += '"lastName":"' + cleanUp($('input#input_text_lastName').val()) + '",';
    sThisNode += '"jobTitle":"' + cleanUp($('input#input_text_jobTitle').val()) + '",';
    sThisNode += '"companyName":"' + cleanUp($('input#input_text_companyName').val()) + '",';
    sThisNode += '"aemGuid":"' + $('input#input_hidden_aemGuid').val() + '",';
    sThisNode += '"action":"' + thisFieldset.attr('data-fieldstatus') + '"';
    sThisNode += '},';
    return sThisNode;
}

// Build static JSON nodes for source folder
function buildJSONNodeSourceFolder(thisFieldset, iFieldset) {
	var sThisNode = "";
    sThisNode += '"' + thisFieldset.data('jsonkey') + '":{';
    sThisNode += '"id":"' + $('input#input_hidden_sourceFolder').val() + '"';
    sThisNode += '},';
    return sThisNode;
}

// Build static JSON nodes for direct text input
function buildJSONNodeBusinessAddress(thisFieldset, iFieldset) {
	var sThisNode = "";
    sThisNode += '"' + thisFieldset.data('jsonkey') + '":{';
    if (thisFieldset.attr('data-fieldstatus') != 'Delete') {
        sThisNode += '"uid":"' + $('input#input_hidden_businessAddress').val() + '",';
        sThisNode += '"street":"' + cleanUp($('input#input_text_street').val()) + '\\r\\n' + cleanUp($('input#input_text_street_2').val()) + '\\r\\n' + cleanUp($('input#input_text_street_3').val()) + '",';
        sThisNode += '"city":"' + cleanUp($('input#input_text_city').val()) + '",';
        sThisNode += '"postalCode":"' + cleanUp($('input#input_text_postalCode').val()) + '",';
        if ($('select#input_text_countryName').children("option:selected").val() != '0') {
            sThisNode += '"countryName":"' + $('select#input_text_countryName').children("option:selected").text() + '",';
            sThisNode += '"countryId":"' + $('select#input_text_countryName').children("option:selected").val() + '",';
        }
        if ($('select#input_text_stateName').children("option:selected").val() != '0') {
            sThisNode += '"stateCode":"' + $('select#input_text_stateName').children("option:selected").val() + '",';
        }
    } else {
		sThisNode += '"uid":"' + $('input#input_hidden_businessAddress').attr('data-original') + '",';
        sThisNode += '"street":"' + cleanUp($('input#input_text_street').attr('data-original')) + '\\r\\n' + cleanUp($('input#input_text_street_2').attr('data-original')) + '\\r\\n' + cleanUp($('input#input_text_street_3').attr('data-original')) + '",';
        sThisNode += '"city":"' + cleanUp($('input#input_text_city').attr('data-original')) + '",';
        sThisNode += '"postalCode":"' + cleanUp($('input#input_text_postalCode').attr('data-original')) + '",';
        if ($('select#input_text_countryName').attr('data-original') != '0') {
            $('select#input_text_countryName option').each( function() {
                if ($(this).attr('value') == $('select#input_text_countryName').attr('data-original')) {
					sThisNode += '"countryName":"' + $(this).text() + '",';
                }
            });
            sThisNode += '"countryId":"' + $('select#input_text_countryName').attr('data-original') + '",';
        }
        if ($('select#input_text_stateName').attr('data-original') != '0') {
            sThisNode += '"stateCode":"' + $('select#input_text_stateName').attr('data-original') + '",';
        }
    }
    sThisNode += '"action":"' + thisFieldset.attr('data-fieldstatus') + '"';
    sThisNode += '},';
    return sThisNode;
}

// Build static JSON nodes for direct text input
function buildJSONNodeBusinessEmail(thisFieldset, iFieldset) {
	var sThisNode = "";
    sThisNode += '"' + thisFieldset.data('jsonkey') + '":{';
    sThisNode += '"uid":"' + $('input#input_hidden_businessEmail').val() + '",';
	sThisNode += '"email":"' + cleanUp($('input#input_text_email').val()) + '",';
    sThisNode += '"action":"' + thisFieldset.attr('data-fieldstatus') + '"';
    sThisNode += '}';
    return sThisNode;
}

// Build simpler JSON nodes for things like sectors, jurisdictions and legal areas
function buildJSONNode(thisFieldset, iFieldset) {
    var sThisNode = "";
    sThisNode += (iFieldset > 0) ? ',' : ''; // Add a comma before the array if it's not the first one
    // Write null if there are no added or removed list items in the current field
	if (thisFieldset.find('.added').length == 0 && thisFieldset.find('.removed').length == 0 && thisFieldset.attr('data-fieldstatus') == 'null') {
		sThisNode += '"' + thisFieldset.data('jsonkey') + '":null';
    } else {
        sThisNode += '"' + thisFieldset.data('jsonkey') + '":{';
        sThisNode += '"optInFolders":[';
        var nLocalLoopCount = 0;
        thisFieldset.find('input.added').each( function(i) {
            // Check that the IA list ID is real (fake ones used for parent groups have dashes in them)
            if ($(this).val().indexOf('-') == -1) {
                sThisNode += (nLocalLoopCount > 0) ? ',' : ''; // Add a comma before the array if it's not the first one
                sThisNode += '{';
                sThisNode += '"id": "' + $(this).val() + '",';
                sThisNode += '"name": "' + $(this).data('name') + '"';
                sThisNode += '}';
                nLocalLoopCount++;
            }
        });
        sThisNode += '],';
        sThisNode += '"optOutFolders":[';
        nLocalLoopCount = 0;
        thisFieldset.find('input.removed').each( function(i) {
            // Check that the IA list ID is real (fake ones used for parent groups have dashes in them)
            if ($(this).val().indexOf('-') == -1) {
                sThisNode += (nLocalLoopCount > 0) ? ',' : ''; // Add a comma before the array if it's not the first one
                sThisNode += '{';
                sThisNode += '"id": "' + $(this).val() + '",';
                sThisNode += '"name": "' + $(this).data('name') + '"';
                sThisNode += '}';
                nLocalLoopCount++;
            }
        });
        sThisNode += ']';
        sThisNode += '}';
    }
    return sThisNode;
}

// Build more complex JSON nodes for things like sectors, jurisdictions and legal areas
function buildJSONNodeOptIn(thisFieldset, iFieldset, bStatus) {
	var sThisNode = "";
    var sThisUid = (thisFieldset.attr('data-uid') === undefined) ? 'null' : '"' + (thisFieldset.attr('data-uid') !== undefined) + '"'; // This will come with the get contact request and will be embedded in a data property of the node
    sThisNode += (iFieldset > 0) ? ',' : ''; // Add a comma before the array if it's not the first one
    if (thisFieldset.attr('data-fieldstatus') == 'null') {
		sThisNode += '"' + thisFieldset.data('jsonkey') + '":null';
    } else {
        sThisNode += '"' + thisFieldset.data('jsonkey') + '":{';
        sThisNode += '"optIn":{';
        sThisNode += '"uid":' + sThisUid + ','; 
        sThisNode += '"displayValue":"' + thisFieldset.attr('data-selectedoption') + '",'; // This is the selected value
        sThisNode += '"id":"' + (thisFieldset.attr('data-selectedoption') == 'Yes' ? '1' : '0') + '",'; // This is the selected value
        sThisNode += '"action":"' + thisFieldset.attr('data-fieldstatus') + '"'; // Must be based on p98 of the spec doc
        sThisNode += '},';
        sThisNode += '"optInFolders":[';
        var nLocalLoopCount = 0;
        thisFieldset.find('input.added').each( function(i) {
            // Check that the IA list ID is real (fake ones used for parent groups have dashes in them)
            if ($(this).val().indexOf('-') == -1) {
                sThisNode += (nLocalLoopCount > 0) ? ',' : ''; // Add a comma before the array if it's not the first one
                sThisNode += '{';
                sThisNode += '"id": "' + $(this).val() + '"';
                sThisNode += '}';
                nLocalLoopCount++;
            }
        });
        sThisNode += '],';
        sThisNode += '"optOutFolders":[';
        nLocalLoopCount = 0;
        thisFieldset.find('input.removed').each( function(i) {
            // Check that the IA list ID is real (fake ones used for parent groups have dashes in them)
            if ($(this).val().indexOf('-') == -1) {
                sThisNode += (nLocalLoopCount > 0) ? ',' : ''; // Add a comma before the array if it's not the first one
                sThisNode += '{';
                sThisNode += '"id": "' + $(this).val() + '"';
                sThisNode += '}';
                nLocalLoopCount++;
            }
		});
        sThisNode += ']';
        if (bStatus) {
            // Only add this property if required (normally for online services)
            if (thisFieldset.attr('data-selectedoption') == 'Yes') {
                sThisNode += ',"status":{';
                sThisNode += '"uid":' + (thisFieldset.attr('data-statusuid') != 'null' ? '"' + thisFieldset.attr('data-statusuid') + '"' : 'null') + ',';
				sThisNode += '"displayValue":"' + thisFieldset.attr('data-statusdisplayvalue') + '",';
				sThisNode += '"id":"' + thisFieldset.attr('data-statusid') + '",';
				sThisNode += '"action":"' + (thisFieldset.attr('data-statusuid') != 'null' ? 'DoNothing' : 'Add') + '"';
				sThisNode += '}';
            }
        }
        sThisNode += '}';
    }
    return sThisNode;
}

// Build more complex JSON nodes for things like sectors, jurisdictions and legal areas
function buildJSONNodeOptOut(thisFieldset, iFieldset) {
    var sThisNode = "";
    var sThisUid = (thisFieldset.attr('data-uid') === undefined) ? 'null' : '"' + (thisFieldset.attr('data-uid') !== undefined) + '"'; // This will come with the get contact request and will be embedded in a data property of the node
    sThisNode += (iFieldset > 0) ? ',' : ''; // Add a comma before the array if it's not the first one
    if (thisFieldset.attr('data-fieldstatus') == 'null') {
		sThisNode += '"' + thisFieldset.data('jsonkey') + '":null';
    } else {
        sThisNode += '"' + thisFieldset.data('jsonkey') + '":{';
        sThisNode += '"optOut":"' + thisFieldset.attr('data-selectedoption') + '",';
        sThisNode += '"optInFolders":[';
        // Only loop over the optIn items if the user has answered "yes" to optin
        // if (thisFieldset.attr('data-selectedoption') == 'Yes') {
            thisFieldset.find('input.added').each( function(i) {
                sThisNode += (i > 0) ? ',' : ''; // Add a comma before the array if it's not the first one
                sThisNode += '{';
                sThisNode += '"id": "' + $(this).val() + '"';
                sThisNode += '}';
            });
        // }
        sThisNode += '],';
        sThisNode += '"optOutFolders":[';
        // Only loop over the optOut items if the user has answered "No" to optin
        // if (thisFieldset.attr('data-selectedoption') == 'No') {
            thisFieldset.find('input.removed').each( function(i) {
                sThisNode += (i > 0) ? ',' : ''; // Add a comma before the array if it's not the first one
                sThisNode += '{';
                sThisNode += '"id": "' + $(this).val() + '"';
                sThisNode += '}';
            });
        // }
        sThisNode += ']';
        sThisNode += '}';
    }
    return sThisNode;
}

// Build more complex JSON nodes for things like sectors, jurisdictions and legal areas
function buildJSONNodeOptOutUNSUB(thisFieldset, iFieldset, bOptOut) {
	var sThisNode = "";
    sThisNode += (iFieldset > 0) ? ',' : ''; // Add a comma before the array if it's not the first one

    if (thisFieldset.find('input:checkbox:checked').length == 0) {

		sThisNode += '"' + thisFieldset.data('jsonkey') + '": null';

    } else {

        sThisNode += '"' + thisFieldset.data('jsonkey') + '":{';

        if (thisFieldset.find('input:checkbox:checked').length == 0) {
            sThisNode += '"optInFolders": null,';
            console.log("buildJSONNodeOptOutUNSUB 4");
        } else {
            sThisNode += '"optInFolders":[';
            thisFieldset.find('input:checkbox:checked').each( function(i) {
                sThisNode += (i > 0) ? ',' : ''; // Add a comma before the array if it's not the first one
                sThisNode += '{';
                sThisNode += '"id": "' + $(this).val() + '"';
                sThisNode += '}';
                if ($(this).attr('data-cciaidunsubscribeoptin') != undefined) {
                    console.log('FOUND Additional Opt-in Fields');
                    var aOptIn = $(this).attr('data-cciaidunsubscribeoptin').split(',');
                    var nOptIn = aOptIn.length;
                    for (var ii = 0; ii < nOptIn; ii++) {
                        sThisNode += ','; // Add a comma before the array if it's not the first one
                        sThisNode += '{';
                        sThisNode += '"id": "2i' + aOptIn[ii] + '"';
                        sThisNode += '}';
                    }
                }
            });
            sThisNode += '],';
            sThisNode += '"optOutFolders":[';
            if (thisFieldset.find('input:checkbox:checked').attr('data-cciaidunsubscribe') != undefined) {
                var aOptOut = thisFieldset.find('input:checkbox:checked').attr('data-cciaidunsubscribe').split(',');
                var nOptOut = aOptOut.length;
                for (var i = 0; i < nOptOut; i++) {
                    sThisNode += (i > 0) ? ',' : ''; // Add a comma before the array if it's not the first one
                    sThisNode += '{';
                    sThisNode += '"id": "2i' + aOptOut[i] + '"';
                    sThisNode += '}';
                }
            }
            sThisNode += ']';
        }
        sThisNode += '}';

    }

    return sThisNode;
}

// Build more complex JSON nodes for alerters
function buildJSONNodeAlerter(thisFieldset, iFieldset) {
	var sThisNode = "";
	sThisNode += (iFieldset > 0) ? ',' : ''; // Add a comma before the array if it's not the first one
    // Check if any updates have taken place (and that the subscribe option is checked)
    if (thisFieldset.find('.added').length == 0 && thisFieldset.find('.removed').length == 0) {
		sThisNode += '"' + thisFieldset.data('jsonkey') + '":null';
    } else {

        sThisNode += '"' + thisFieldset.data('jsonkey') + '":{';
    
        // Must work out how to determine opt in or opt out
        sThisNode += '"optInFolders":[';
        // if (thisFieldset.attr('data-selectedoption') == 'Yes') {
        thisFieldset.find('li.cc_issubscribe input.added').each( function(i) {
            // Check that the IA list ID is real (fake ones used for parent groups have dashes in them)
            if ($(this).val().indexOf('-') == -1) {
                sThisNode += '{';
                sThisNode += '"id":"' + $(this).val() + '"';
                sThisNode += '}';
            }
        });
        sThisNode += '],';
        sThisNode += '"optOutFolders":[';
        // if (thisFieldset.attr('data-selectedoption') == 'No') {
        thisFieldset.find('li.cc_issubscribe input.removed').each( function(i) {
            // Check that the IA list ID is real (fake ones used for parent groups have dashes in them)
            if ($(this).val().indexOf('-') == -1) {
                sThisNode += '{';
                sThisNode += '"id":"' + $(this).val() + '"';
                sThisNode += '}';
            }
        });
        sThisNode += '],';
        sThisNode += '"frequency":{';
        sThisNode += '"uid":' + (thisFieldset.attr('data-frequencyuid') !== undefined && thisFieldset.attr('data-frequencyuid') != 'null' ? '"' + thisFieldset.attr('data-frequencyuid') + '"' : 'null') + ',';
        sThisNode += '"displayValue":"' + thisFieldset.find('li.li_ccisfrequency input:checked').next().text() + '",';
		sThisNode += '"id":"' + thisFieldset.find('li.li_ccisfrequency input:checked').val() + '",';
        sThisNode += '"action":"' + thisFieldset.attr('data-frequencystatus') + '"';
        sThisNode += '},';
        // Begin formatting the inner property nodes (each inner property in the Aletrter and CA nodes needs listing - be careful of commas!!!)
        if (thisFieldset.find('ul.ul_alerterTags').length > 0) {
            sThisNode += buildJSONNodeInnerPropertyList('alerterTags', thisFieldset);
        }
        if (thisFieldset.find('ul.ul_hotTopics').length > 0) {
            sThisNode += buildJSONNodeInnerPropertyList('hotTopics', thisFieldset) + ', '; // Look out for commas to be added if there are multiple inner nodes
        }
        if (thisFieldset.find('ul.ul_contentType').length > 0) {
            sThisNode += buildJSONNodeInnerPropertyList('contentType', thisFieldset) + ', '; // Look out for commas to be added if there are multiple inner nodes
        }
        if (thisFieldset.find('ul.ul_language').length > 0) {
            sThisNode += buildJSONNodeInnerPropertyList('language', thisFieldset);
        }
        sThisNode += '}';
    }
    return sThisNode;
}

// Build the unusual inner nodes for Alerters and CA where the optin/out list is deeper than the standard legal areas or sectors.
function buildJSONNodeInnerPropertyList(sProperty, thisFieldset) {
	var sThisNode = "";
    var nLoopCount = 0;
    sThisNode += '"' + sProperty + '":[';
    // The sProperty must match the ccinnerjsonkey property of the parent node of the options we're looping over here
	thisFieldset.find('ul.ul_' + sProperty + ' li input.input_checkbox.added').each( function(i) {
        // Check that the IA list ID is real (fake ones used for parent groups have dashes in them)
        if ($(this).val().indexOf('-') == -1) {
            sThisNode += (nLoopCount > 0) ? ',' : ''; // Add a comma before the array if it's not the first one
            sThisNode += '{';
            sThisNode += '"uid":' + ($(this).attr('data-uid') !== undefined ? '"' + $(this).attr('data-uid') + '"' : 'null') + ',';
            sThisNode += '"id": "' + $(this).val() + '",';
            sThisNode += '"displayValue": "' + $(this).next().text() + '",';
            sThisNode += '"action": "Add"';
            sThisNode += '}';
            nLoopCount = nLoopCount + 1;
        }
    });
    thisFieldset.find('ul.ul_' + sProperty + ' li input.input_checkbox.removed').each( function(i) {
        // Check that the IA list ID is real (fake ones used for parent groups have dashes in them)
        if ($(this).val().indexOf('-') == -1) {
            sThisNode += (nLoopCount > 0) ? ',' : ''; // Add a comma before the array if it's not the first one
            sThisNode += '{';
            sThisNode += '"uid":' + ($(this).attr('data-uid') !== undefined ? '"' + $(this).attr('data-uid') + '"' : 'null') + ',';
            sThisNode += '"id": "' + $(this).val() + '",';
            sThisNode += '"displayValue": "' + $(this).next().text() + '",';
            sThisNode += '"action": "Delete"';
            sThisNode += '}';
            nLoopCount = nLoopCount + 1;
        }
    });
    sThisNode += ']';
    return sThisNode;
}

function preparePreferenceForm() {
    var sJSONPost = '{"action":"UpdateContact",';
	// Start by looping over the fieldsets to find all inputs
    $('form#prefs_form fieldset').each( function(i) {
        var sJSONKey = $(this).data('jsonkey');
		// Check if the field set is checkboxes, radios, text or other...
        if (sJSONKey == 'personalDetails') {
			sJSONPost += buildJSONNodePersonalDetails($(this), i);
        } else if(sJSONKey == 'sourceFolder') {
			sJSONPost += buildJSONNodeSourceFolder($(this), i);
		} else if(sJSONKey == 'businessAddress') {
			sJSONPost += buildJSONNodeBusinessAddress($(this), i);
		} else if(sJSONKey == 'businessEmail') {
			sJSONPost += buildJSONNodeBusinessEmail($(this), i);
		} else if(sJSONKey == 'globalOptOut') {
			sJSONPost += buildJSONNodeOptOut($(this), i);
        } else if(sJSONKey == 'publications' || sJSONKey == 'clientportal' || sJSONKey == 'events' || sJSONKey == 'podcasts') {
			sJSONPost += buildJSONNodeOptIn($(this), i, false);
        } else if(sJSONKey == 'onlineservices') {
			sJSONPost += buildJSONNodeOptIn($(this), i, true);
        } else if (sJSONKey == 'alerterEnergy' || sJSONKey == 'alerterFinance' || sJSONKey == 'alerterCM' || sJSONKey == 'ca') {
            sJSONPost += buildJSONNodeAlerter($(this), i);
        } else if ($(this).find('input.input_checkbox').length > 0) {
            sJSONPost += buildJSONNode($(this), i);
        } else if ($(this).find('input.input_radio').length > 0) {
    		sJSONPost += buildJSONNodeOptIn($(this), i, false);
        }
    });
    sJSONPost += '}';

	breadcrumbsAndFormPageSwitch('Down');

    // $('#aside_2col_container div.parsyscol2').append('<div>' + sJSONPost + '</div>');

    console.log('////////////////////////// JSON DATA CONVERTED FROM FORM ///////////////////////// ');
    console.log(JSON.parse(sJSONPost));

	// ========================================================================================
    // MAIN CALL TO THE UPDATE WRAPPER
	// ========================================================================================

    updateContact(sJSONPost);

    // ========================================================================================
}

function prepareUnsubscribeForm() {
    var sJSONPost = '{ "personalDetails": {"id":"' + $('form#prefs_form').attr('data-contactid') + '"},';
	// Start by looping over the fieldsets to find all inputs
    $('form#prefs_form fieldset').each( function(i) {
        var sJSONKey = $(this).data('jsonkey');
		// Check if the field set is checkboxes, radios, text or other...
        if (sJSONKey == 'globalOptOut') {
			sJSONPost += buildJSONNodeOptOutUNSUB($(this), i, true);
        } else {
			sJSONPost += buildJSONNodeOptOutUNSUB($(this), i, false);
        }
    });
    sJSONPost += '}';

    console.log('////////////////////////// JSON DATA CONVERTED FROM FORM ///////////////////////// ');
    console.log(JSON.parse(sJSONPost));

	// ========================================================================================
    // MAIN CALL TO THE UNSUBSCRIBE WRAPPER
	// ========================================================================================

    unsubscribeContact(sJSONPost);

    // ========================================================================================

}

// ================================== START: INDIVIDUAL INPUT PREP FUNCTIONS ================================= //

// React to input and set the form element up to report its update status to the submission function
function setInputCheckBox(thisInput) {
    // Log the update status of the fieldset
    var sThisStatus = 'DoNothing';
    // Hold a reference to the original state of the radios so we know of this is a first time addition
    var bOriginalsHadValue = false;

    // Loop over all the "radios" in the current fieldset
    thisInput.parent().parent().find('input').each( function() {
        // console.log('Comparing: ' + $(this).attr('id') + ': ' + $(this).attr('data-original') + ' v ' + thisInput.prop('checked'));
		// Check if the value of the input has changed
        if (($(this).attr('data-original') == 'true' ? true : false) != $(this).prop('checked')) {
            if ($(this).prop('checked')) {
                $(this).removeClass('removed unchanged').addClass('added');
            } else {
                $(this).removeClass('added unchanged').addClass('removed');
            }
            sThisStatus = 'Update';
        } else {
            $(this).removeClass('added removed').addClass('unchanged');
            sThisStatus = 'DoNothing';
        }
        // Update the log of original values to see if they were all unselected at the start so we know this field has to be an addition rather than an update
        bOriginalsHadValue = thisInput.data('original');
    });
	// Modify the sThisStatus based on finding that a value has changed but all radios were blank to begin with
    if (sThisStatus == 'Update' && !bOriginalsHadValue) {
		sThisStatus = 'Add';
    }

    // Update the data fieldset storage value if the checkbox is marked as a subscibe or unsubscribe option
    // We may need to check if the unsub option does not have a subscribe option in the same fieldset so we don't 
    // contaminate the fieldset status with other unsub options that are not relevant
    // if (thisInput.attr('data-ccissubscribe') == 'true' || thisInput.attr('data-ccisunsubscribe') == 'true') {
    if (thisInput.attr('data-ccissubscribe') == 'true') {
        // console.log('data-ccissubscribe: true');
        thisInput.closest('fieldset').attr('data-fieldstatus', sThisStatus);
        thisInput.closest('fieldset').attr('data-selectedoption', thisInput.prop('checked') ? 'Yes' : 'No');
        thisInput.closest('fieldset').attr('data-selectedvalue', thisInput.val());
    } else {
		// But only send value updates to the fieldset if the cclocaliseoutput property is present
        if (thisInput.attr('data-cclocaliseoutput') == 'true') {
            if (thisInput.parent().parent().find('input.added').length > 0 && thisInput.parent().parent().find('input.removed').length == 0) {
            	thisInput.closest('fieldset').attr('data-frequencystatus', 'Add');
            } else if (thisInput.parent().parent().find('input.removed').length > 0) {
				thisInput.closest('fieldset').attr('data-frequencystatus', 'Update');
            } else {
				thisInput.closest('fieldset').attr('data-frequencystatus', 'DoNothing');
            }	
        }
    }

	/*

    // Log any selections that require approval so we can create a cookie for the message centre
	if (thisInput.attr('data-ccrequiresapproval') == 'true' && thisInput.prop('checked')) {
		cc_cpprefs_approval.push(thisInput.val().replace('2i', ''));
    } else {
        var nIndexOfThisVal = cc_cpprefs_approval.indexOf(thisInput.val().replace('2i', ''));
        if (nIndexOfThisVal > -1) {
			cc_cpprefs_approval.splice(nIndexOfThisVal, 1);
		}
    }

    */

}

// React to input and set the form element up to report its update status to the submission function
function setInputRadioButton(thisInput) {
    // Log the update status of the fieldset
    var sThisStatus = '';
    // Hold a reference to the original state of the radios so we know of this is a first time addition
    var bOriginalsHadValue = false;
    // Loop over all the radios in the current fieldset
    thisInput.parent().parent().find('input.input_radio').each( function() {
		// Check if the value of the input has changed
        if ($(this).data('original') != $(this).prop('checked')) {
            if ($(this).prop('checked')) {
                $(this).removeClass('removed unchanged').addClass('added');
            } else {
                $(this).removeClass('added unchanged').addClass('removed');
            }
            sThisStatus = 'Update';
        } else {
            $(this).removeClass('added removed').addClass('unchanged');
        }
        // Update the log of original values to see if they were all unselected at the start so we know this field has to be an addition rather than an update
        bOriginalsHadValue = thisInput.data('original');
    });
	// Modify the sThisStatus based on finding that a value has changed but all radios were blank to begin with
    if (sThisStatus == 'Update' && !bOriginalsHadValue) {
		sThisStatus = 'Add';
    }

    // But only send value updates to the fieldset if the cclocaliseoutput property is not present
    if (thisInput.attr('data-cclocaliseoutput') != 'true') {
        thisInput.closest('fieldset').attr('data-fieldstatus', sThisStatus);
        thisInput.closest('fieldset').attr('data-selectedoption', thisInput.next().text());
        thisInput.closest('fieldset').attr('data-selectedvalue', thisInput.val());
    } else {
        thisInput.closest('fieldset').attr('data-frequencystatus', sThisStatus);
		thisInput.closest('fieldset').attr('data-frequencyoption', thisInput.next().text());
        thisInput.closest('fieldset').attr('data-frequencyvalue', thisInput.val());
    }

    // Log any selections that require approval so we can create a cookie for the message centre
	if (thisInput.attr('data-ccrequiresapproval') == 'true' && thisInput.prop('checked')) {
		cc_cpprefs_approval.push(thisInput.val().replace('2i', ''));
    } else {
        var nIndexOfThisVal = cc_cpprefs_approval.indexOf(thisInput.val().replace('2i', ''));
        if (nIndexOfThisVal > -1) {
			cc_cpprefs_approval.splice(nIndexOfThisVal, 1);
		}
    }
}

// React to input and set the form element up to report its update status to the submission function
function setInputText(thisInput) {
    // Store the input values in vars
    var input_original = thisInput.data('original');
    // Log the update status of the fieldset
    var sThisStatus = 'DoNothing';

    console.log('setInputText: ' + input_original + ' | ' + thisInput.val());

	// Check if the value of the input has changed
    if (input_original != thisInput.val()) {
        thisInput.removeClass('unchanged').addClass('changed');
    } else {
		thisInput.removeClass('changed').addClass('unchanged');
    }
    // Loop over all siblings to see if they all started out blank so we know if this is an "add" as opposed to "update"
    var bIsNew = true;
	thisInput.parent().parent().find('.input_text').each( function() {
        if ($(this).attr('data-original') != '' && $(this).attr('data-original') != '0') {
			bIsNew = false;
            return false;
        }
    });
    // Loop over the fields and check if any have changed
    thisInput.parent().parent().find('.input_text').each( function() {
        if ($(this).hasClass('changed')) {
            sThisStatus = (bIsNew) ? 'Add' : 'Update';
            return false;
        }
    });

    // Set del;etion to true so we can override it
    var bBeenDeleted = true;
	// Do we have a uid for a stored address
    if ($('input#input_hidden_businessAddress').val() == '') {
        // If not, deletion can never be an option
		bBeenDeleted = false;
    } else {
        thisInput.parent().parent().find('.input_text').each( function() {
            if ($(this).val() != '' && $(this).val() != 0 && !$(this).find('option').first().prop('disabled')) {
                bBeenDeleted = false;
            }
        });
    }
	if (bBeenDeleted) {
		sThisStatus = 'Delete';
    }

    console.log('ADDRESS STATUS: ' + sThisStatus);
    // Finally send the status to the fieldset
	thisInput.closest('fieldset').attr('data-fieldstatus', sThisStatus);
}

// ============================= START: CONNECT FORM OPTIONS TO EACH OTHER =============================== //

function updateRelated(thisElement) {
    // Call function to tell targetted elements to show/hide their mandatory warning
    setMandatoryWarnings(thisElement);
    // Check if the input has been checked...
    if (thisElement.prop('checked')) {
        // Check if the element has the cciaidcheck property
        if (thisElement.attr('data-cciaidcheck') != '0') {
            // Split the string into an array
            var aCheck = thisElement.attr('data-cciaidcheck').split(',');
            // Loop over the array
            for (i = 0; i < aCheck.length; i++) {
                console.log('Target field: ' + aCheck[i]);
                // Find the associated form element
                var thisInput = $('#field_2i' + aCheck[i]);
                // Check the element exists before trying to do anything with it
                if (thisInput.length > 0) {
                    console.log('Found :' + thisInput.attr('id'));
                    // Check the input
                    thisInput.prop('checked', true);
                    console.log(thisInput.attr('id') + ' checked: ' + thisInput.prop('checked'));
                    // Manually call the functions we need to fire after an input has been updated
                    // updateChildrenDynamic(thisInput);
                    updateChildrenStatic(thisInput);
                    setInputCheckBox(thisInput);
                }

            }
        }
        // Check if the element has the cciaiduncheck property
        if (thisElement.attr('data-cciaiduncheck') != '0') {
            // Split the string into an array
            var aUncheck = thisElement.attr('data-cciaiduncheck').split(',');
            // Loop over the array
            for (i = 0; i < aUncheck.length; i++) {
                // Find the associated form element
                var thisInput = $('#field_2i' + aUncheck[i]);
                // Check the element exists before trying to do anything with it
                if (thisInput.length > 0) {
                    // Check the input
                    thisInput.prop('checked', false);
                    // Manually call the functions we need to fire after an input has been updated
                    // updateChildrenDynamic(thisInput);
                    updateChildrenStatic(thisInput);
                    setInputCheckBox(thisInput);
                }
            }
        }


    // ... or unchecked
    } else {
		// Check if the element has the cciaiduncheckonuncheck property (the property to uncheck other inputs when it is unchecked)
        if (thisElement.attr('data-cciaiduncheckonuncheck') != '0') {
            // Split the string into an array
            var aUncheck = (thisElement[0].hasAttribute('data-cciaiduncheckonuncheck')) ? thisElement.attr('data-cciaiduncheckonuncheck').split(',') : [];
            // Loop over the array
            for (i = 0; i < aUncheck.length; i++) {
                // Find the associated form element
                var thisInput = $('#field_2i' + aUncheck[i]);
                // Check the element exists before trying to do anything with it
                if (thisInput.length > 0) {
                    // Check the input
                    thisInput.prop('checked', false);
                    // Manually call the functions we need to fire after an input has been updated
                    // updateChildrenDynamic(thisInput);
                    updateChildrenStatic(thisInput);
                    setInputCheckBox(thisInput);
                }
            }
        }
        // Check if the element has the cciaiduncheckonuncheck property (the property to uncheck other inputs when it is unchecked)
        if (thisElement.attr('data-cciaidcheckonuncheck') != '0') {
            // Split the string into an array
            var aUncheck = (thisElement[0].hasAttribute('data-cciaidcheckonuncheck')) ? thisElement.attr('data-cciaidcheckonuncheck').split(',') : [];
            // Loop over the array
            for (i = 0; i < aUncheck.length; i++) {
                // Split the string into an array
                var aCheck = thisElement.attr('data-cciaidcheckonuncheck').split(',');
                // Loop over the array
                for (i = 0; i < aCheck.length; i++) {
                    // Find the associated form element
                    var thisInput = $('#field_2i' + aCheck[i]);
                    // Check the element exists before trying to do anything with it
                    if (thisInput.length > 0) {
                        // Check the input
                        thisInput.prop('checked', true);
                        // Manually call the functions we need to fire after an input has been updated
                        // updateChildrenDynamic(thisInput);
                        updateChildrenStatic(thisInput);
                        setInputCheckBox(thisInput);
                    }

                }
            }
        }
    }
}

// This function is used to uncheck and slide up all options following a toggle that has been dynamically changed by clicking another toggle elsewhere
function updateChildrenDynamic(thisInput) {
    if (thisInput.attr('data-ccissubscribe') == 'true') {
		thisInput.parent().nextAll().find('input').prop('checked', false);
        thisInput.parent().nextAll().slideUp();
	}
}

// This function is called directly by anelement being clicked and toggles the visibility of the elemnts following the clicked input
function updateChildrenStatic(thisInput) {
    if (thisInput.attr('data-ccissubscribe') == 'true') {
        console.log('updateChildrenStatic 2: ' + thisInput.attr('id'));
		if (thisInput.prop('checked') == true) {
            // Slide down all the following elements
            thisInput.parent().nextAll().slideDown();
            // Reset all following inputs to original values or uncheck them if no original value exists
            $(thisInput.parent().nextAll().find('li input').not('li.li_ccisfrequency input')).each( function() {
                console.log('Resetting to original state via updateChildrenStatic()');
                $(this).prop('checked', $(this).attr('data-original') == 'true' ? true : false);
            });
        } else {
            // Untick everything following and slide it up
            thisInput.parent().nextAll().find('li input').not('li.li_ccisfrequency input').each( function() {
				$(this).prop('checked', false);
                setInputCheckBox($(this));
            });
			thisInput.parent().nextAll().slideUp();
        }
	}
}

// This function is called on doc ready and whenever an input is clicked to activate any iputs that are suppressed as a result of it
function checkDependencies() {
    // Loop over all fieldset uls with a dependency class
    $('fieldset.fieldset_hasdependency').each( function() {
        // Check if the input this UL relies upon has been checked
        if ($('input#field_2i' + $(this).attr('data-ccdependency')).prop('checked')) {
            // Then show and enable it
			$(this).children().animate({'opacity': '1.0'});
            $(this).find('li input').not('li.li_ccisfrequency input').prop('disabled', false);
            $(this).find('li input').not('li.li_ccisfrequency input').each( function() {
				setInputCheckBox($(this));
            });
        } else {
            // Or suppress, disable and uncheck it
			$(this).children().animate({'opacity': '0.3'});
            $(this).find('li input').not('li.li_ccisfrequency input').prop('disabled', true);
            $(this).find('li input').not('li.li_ccisfrequency input').prop('checked', false);
            $(this).find('li input').not('li.li_ccisfrequency input').each( function() {
				setInputCheckBox($(this));
            });
            $(this).find('li.cc_issubscribe').nextAll('li').slideUp();
        }

    });
}

// Function to get the states of all elements right at the start
function initialiseForm() {
	// Loop over all fieldsets to check/set initial states/visibility
    $('fieldset').find('input').each( function() {
		// Hide any fields following a subscribe option that isn't activated
        if ($(this).attr('data-ccissubscribe') == 'true' && !$(this).prop('checked')) {
			$(this).parent().nextAll().slideUp();
        }

    });
}

// ==================================== START: FORM FILLER FUNCTIONS =================================== //

// Send the returned data to the form
function populateForm(data) {

    if ($('form.form_subscribe').length > 0) {

		// Immediately reset all originals to false
        $('input:checkbox').attr('data-original', 'false');

        loadInputText($('input#input_text_firstName'), data['personalDetails']['firstName']);
        loadInputText($('input#input_text_lastName'), data['personalDetails']['lastName']);
        loadInputText($('input#input_text_jobTitle'), data['personalDetails']['jobTitle']);
        loadInputText($('input#input_text_companyName'), data['personalDetails']['companyName']);

        loadInputText($('input#input_hidden_aemGuid'), data['personalDetails']['aemGuid']);
        loadInputText($('input#input_hidden_sourceFolder'), data['sourceFolder']['id']);
    
        if (data['businessAddress'] !== undefined) {
            loadInputText($('input#input_hidden_businessAddress'), data['businessAddress']['uid']);
        }

        loadInputText($('input#input_hidden_businessEmail'), data['businessEmail']['uid']);
    
        if (data['businessAddress'] !== undefined) {

			var aStreet = [];

            if (data['businessAddress']['street'] !== undefined) {
				aStreet = data['businessAddress']['street'].split('\r\n');
                loadInputText($('input#input_text_street'), aStreet[0]);
            }
			if (aStreet[1] !== undefined) {
				loadInputText($('input#input_text_street_2'), aStreet[1]);
            }
			if (aStreet[2] !== undefined) {
				loadInputText($('input#input_text_street_3'), aStreet[2]);
            }

            loadInputText($('input#input_text_city'), data['businessAddress']['city']);
            loadInputText($('input#input_text_postalCode'), data['businessAddress']['postalCode']);
            loadSelectMenu($('select#input_text_countryName'), data['businessAddress']['countryId']);
			loadStatesFromCountry($('select#input_text_countryName'));
			$('select#input_text_stateName').attr('data-preselect', data['businessAddress']['stateCode']);
        } else {
			loadInputText($('input#input_text_street'), '');
            loadInputText($('input#input_text_street_2'), '');
            loadInputText($('input#input_text_street_3'), '');
            loadInputText($('input#input_text_city'), '');
            loadInputText($('input#input_text_postalCode'), '');
            loadSelectMenu($('select#input_text_countryName'), '0');
        }

        loadInputText($('input#input_text_email'), data['businessEmail']['email']);

        // Opt-out style nodes
        if (data['globalOptOut'] !== undefined) {
            console.log('Found Global Opt Out Data');
            loadGlobalOptOut($('fieldset#fieldset_globalOptOut'), data['globalOptOut']);
        }

        // Opt-in style nodes
        if (data['publications'] !== undefined) {
            loadFieldsetOptIn($('fieldset#fieldset_publications'), data['publications']);
        }
        if (data['events'] !== undefined) {
            loadFieldsetOptIn($('fieldset#fieldset_events'), data['events']);
        }
        if (data['podcasts'] !== undefined) {
            loadFieldsetOptIn($('fieldset#fieldset_podcasts'), data['podcasts']);
        }
        if (data['onlineservices'] !== undefined) {
            loadFieldsetOptIn($('fieldset#fieldset_onlineservices'), data['onlineservices']);
        } else {
			loadFieldsetOptInStatusOnly($('fieldset#fieldset_onlineservices'));
        }

        // Alerter/CA style nodes
        if (data['alerterEnergy'] !== undefined) {
            loadFieldsetAlerters($('fieldset#fieldset_alerterEnergy'), data['alerterEnergy']);
        }
        if (data['alerterFinance'] !== undefined) {
            loadFieldsetAlerters($('fieldset#fieldset_alerterFinance'), data['alerterFinance']);
        }
        if (data['alerterCM'] !== undefined) {
            loadFieldsetAlerters($('fieldset#fieldset_alerterCM'), data['alerterCM']);
        }
        if (data['ca'] !== undefined) {
            loadFieldsetAlerters($('fieldset#fieldset_ca'), data['ca']);
        }
    
        // Standard list nodes
        if (data['nonAlerterCaOS'] !== undefined) {
            loadFieldset($('fieldset#fieldset_nonAlerterCaOS'), data['nonAlerterCaOS']);
        }
        if (data['talkingTech'] !== undefined) {
            loadFieldset($('fieldset#fieldset_talkingTech'), data['talkingTech']);
        }
        if (data['jurisdictions'] !== undefined) {
            loadFieldset($('fieldset#fieldset_jurisdictions'), data['jurisdictions']);
        }
        if (data['legalAreas'] !== undefined) {
            loadFieldset($('fieldset#fieldset_legalAreas'), data['legalAreas']);
        }
        if (data['sectors'] !== undefined) {
            loadFieldset($('fieldset#fieldset_sectors'), data['sectors']);
        }

    }

}

// Collection of functions to map the inbound JSON response to the 

function loadInputText(thisElement, value) {
	thisElement.val(value);
	thisElement.attr('data-original', value);
    errorTrap(thisElement);
    // Reset the input status to unchanged
	thisElement.removeClass('changed').addClass('unchanged');
    thisElement.closest('fieldset').attr('data-fieldstatus', 'DoNothing');
}

function loadSelectMenu(thisElement, value) {
    console.log('loadSelectMenu: ' + thisElement.attr('id') + ' = ' + value);
    thisElement.attr('data-fieldstatus', 'DoNothing');
    if (value != '' && value !== undefined && value !== null) {
		thisElement.attr('data-original', value);
    } else {
		thisElement.attr('data-original', '0');
    }
    thisElement.attr('data-original', value);
	thisElement.find('option').filter( function() {
		return $(this).attr('value') == value;
	}).prop('selected', true);
    // Reset the input status to unchanged
	thisElement.removeClass('changed').addClass('unchanged');
}

function loadFieldset(thisElement, jsonObject) {
    thisElement.attr('data-fieldstatus', 'DoNothing');
    if (jsonObject['optInFolders'] !== undefined) {
        // Loop over the values in the array
        for (var i = 0; i < jsonObject['optInFolders'].length; i++) {
            // Strip the array value into field name to target the correct one and mark it checked
            $(thisElement.find('input#field_' + jsonObject['optInFolders'][i]['id'])).prop('checked', true);
            $(thisElement.find('input#field_' + jsonObject['optInFolders'][i]['id'])).attr('data-original', true);
            // Manually call the fieldset update functions (they won't trigger on their own
            updateChildrenStatic(thisElement.find('input#field_' + jsonObject['optInFolders'][i]['id']));
            setInputCheckBox(thisElement.find('input#field_' + jsonObject['optInFolders'][i]['id']));
            evalMandatoryWarning(thisElement.find('input#field_' + jsonObject['optInFolders'][i]['id']));
        }
    }
    // Reset the input status to unchanged
	thisElement.find('input').removeClass('added removed').addClass('unchanged');
}

function loadFieldsetOptIn(thisElement, jsonObject) {
    // Initially override the field status because it will be null by default. 
    // Setting a value from the feed denotes that null is no longer appropriate.
    thisElement.attr('data-fieldstatus', 'DoNothing');

    // Add the uid to the fieldset so it can be accessed later by the JSON Post builders
	if (jsonObject['optIn'] !== undefined) {
        if (jsonObject['optIn']['uid'] !== undefined) {
            $(thisElement).attr('data-uid', jsonObject['optIn']['uid']);
        } else {
            $(thisElement).attr('data-uid', 'null');
        }
    }
    // Loop over the values in the array
    if (jsonObject['optInFolders'] !== undefined) {
        for (var i = 0; i < jsonObject['optInFolders'].length; i++) {
            // Strip the array value into field name to target the correct one and mark it checked
            $(thisElement.find('input#field_' + jsonObject['optInFolders'][i]['id'])).prop('checked', true);
            $(thisElement.find('input#field_' + jsonObject['optInFolders'][i]['id'])).attr('data-original', true);
            // Manually call the fieldset update functions (they won't trigger on their own
            // ----- C3 Update 11/08/2020 to deal with briefings sub list change ------------ //
            updateChildrenStatic(thisElement.find('input#field_' + jsonObject['optInFolders'][i]['id'])); // Comment/uncomment this line to deactivate/activate the regular newsletters update
            setInputCheckBox(thisElement.find('input#field_' + jsonObject['optInFolders'][i]['id']));
        }
    }
    // Reset the input status to unchanged
	thisElement.find('input').removeClass('added removed').addClass('unchanged');
    // Add the status data if available (normally for onlineservices only)
	if (jsonObject['status'] !== undefined) {
		thisElement.attr('data-statusuid', jsonObject['status']['uid']);
        thisElement.attr('data-statusdisplayvalue', jsonObject['status']['displayValue']);
        thisElement.attr('data-statusid', jsonObject['status']['id']);
    } else {
		thisElement.attr('data-statusuid', 'null');
        thisElement.attr('data-statusdisplayvalue', 'Awaiting Approval');
        thisElement.attr('data-statusid', '2i80629');
    }
}

function loadFieldsetOptInStatusOnly(thisElement) {
	thisElement.attr('data-statusuid', 'null');
	thisElement.attr('data-statusdisplayvalue', 'Awaiting Approval');
	thisElement.attr('data-statusid', '2i80629');
}

function loadFieldsetAlerters(thisElement, jsonObject) {
    thisElement.attr('data-fieldstatus', 'DoNothing');
    // Add the frequency uid to the fieldset
    if (jsonObject['frequency'] !== undefined) {
    	$(thisElement).attr('data-frequencyuid', jsonObject['frequency']['uid']);
    	$(thisElement.find('input#field_' + jsonObject['frequency']['id'])).prop('checked', true);
    	$(thisElement.find('input#field_' + jsonObject['frequency']['id'])).attr('data-original', true);
        setInputCheckBox(thisElement.find('input#field_' + jsonObject['frequency']['id']));
    } else {
		$(thisElement).attr('data-frequencyuid', 'null');
    }
    // Loop over the opt-in values in the array
	if (jsonObject['optInFolders'] !== undefined) {
        for (var i = 0; i < jsonObject['optInFolders'].length; i++) {
            // Strip the array value into field name to target the correct one and mark it checked
            $(thisElement.find('input#field_' + jsonObject['optInFolders'][i]['id'])).prop('checked', true);
            $(thisElement.find('input#field_' + jsonObject['optInFolders'][i]['id'])).attr('data-original', true);
            setInputCheckBox(thisElement.find('input#field_' + jsonObject['optInFolders'][i]['id']));
            updateChildrenStatic(thisElement.find('input#field_' + jsonObject['optInFolders'][i]['id']));
            setMandatoryWarnings(thisElement.find('input#field_' + jsonObject['optInFolders'][i]['id']));
        }
    }
    // Loop over the alerter tags to select them and set their uids
    if (jsonObject['alerterTags'] !== undefined) {
        for (var i = 0; i < jsonObject['alerterTags'].length; i++) {
            // Strip the array value into field name to target the correct one and mark it checked
            $(thisElement.find('input#field_' + jsonObject['alerterTags'][i]['id'])).prop('checked', true);
            $(thisElement.find('input#field_' + jsonObject['alerterTags'][i]['id'])).attr('data-uid', jsonObject['alerterTags'][i]['uid']);
            $(thisElement.find('input#field_' + jsonObject['alerterTags'][i]['id'])).attr('data-original', true);
            setInputCheckBox(thisElement.find('input#field_' + jsonObject['alerterTags'][i]['id']));
        }
    }
    // Loop over the hot topics to select them and set their uids
    if (jsonObject['hotTopics'] !== undefined) {
        for (var i = 0; i < jsonObject['hotTopics'].length; i++) {
            // Strip the array value into field name to target the correct one and mark it checked
            $(thisElement.find('input#field_' + jsonObject['hotTopics'][i]['id'])).prop('checked', true);
            $(thisElement.find('input#field_' + jsonObject['hotTopics'][i]['id'])).attr('data-uid', jsonObject['hotTopics'][i]['uid']);
            $(thisElement.find('input#field_' + jsonObject['hotTopics'][i]['id'])).attr('data-original', true);
            setInputCheckBox(thisElement.find('input#field_' + jsonObject['hotTopics'][i]['id']));
        }
    }
    // Loop over the content types to select them and set their uids
    if (jsonObject['contentType'] !== undefined) {
        for (var i = 0; i < jsonObject['contentType'].length; i++) {
            // Strip the array value into field name to target the correct one and mark it checked
            $(thisElement.find('input#field_' + jsonObject['contentType'][i]['id'])).prop('checked', true);
            $(thisElement.find('input#field_' + jsonObject['contentType'][i]['id'])).attr('data-uid', jsonObject['contentType'][i]['uid']);
            $(thisElement.find('input#field_' + jsonObject['contentType'][i]['id'])).attr('data-original', true);
            setInputCheckBox(thisElement.find('input#field_' + jsonObject['contentType'][i]['id']));
        }
    }
    // Loop over the languages to select them and set their uids
    if (jsonObject['language'] !== undefined) {
        for (var i = 0; i < jsonObject['language'].length; i++) {
            // Strip the array value into field name to target the correct one and mark it checked
            $(thisElement.find('input#field_' + jsonObject['language'][i]['id'])).prop('checked', true);
            $(thisElement.find('input#field_' + jsonObject['language'][i]['id'])).attr('data-uid', jsonObject['language'][i]['uid']);
            $(thisElement.find('input#field_' + jsonObject['language'][i]['id'])).attr('data-original', true);
            setInputCheckBox(thisElement.find('input#field_' + jsonObject['language'][i]['id']));
        }
    }
    // Reset the input status to unchanged
	thisElement.find('input').removeClass('added removed').addClass('unchanged');
}

function loadInitialFrequency(thisElement) {
	// Find the localised daily option
    // thisElement.find('li.li_ccisfrequency input:first').prop('checked', true);
    // Override the frequency status
	// thisElement.attr('data-frequencystatus', 'Add');
}

function loadGlobalOptOut(thisElement, jsonObject) {

    // Initially override the field status because it will be null by default. 
    // Setting a value from the feed denotes that null is no longer appropriate.
    thisElement.attr('data-fieldstatus', 'DoNothing');
    if (jsonObject['optOut'] !== undefined) {
		thisElement.attr('data-selectedoption', jsonObject['optOut']);
    }
    // Loop over the values in the array
    if (jsonObject['optInFolders'] !== undefined) {
        for (var i = 0; i < jsonObject['optInFolders'].length; i++) {
            // Strip the array value into field name to target the correct one and mark it checked
            $(thisElement.find('input#field_' + jsonObject['optInFolders'][i]['id'])).prop('checked', true);
            $(thisElement.find('input#field_' + jsonObject['optInFolders'][i]['id'])).attr('data-original', true);
            // Manually call the fieldset update functions (they won't trigger on their own
            setInputCheckBox(thisElement.find('input#field_' + jsonObject['optInFolders'][i]['id']));
        }
    }
}

// =============================== Form menu and animation controls =============================== //

function openSubMenus(thisElement) {
    thisElement.closest('ul').find('label.selected').trigger('click');
    if (thisElement.parent().parent().children('ul').length > 0) {
		if (thisElement.hasClass('selected')) {
			thisElement.parent().next('ul').slideUp().css('z-index', '2');
			thisElement.removeClass('selected');
			thisElement.parent().removeClass('open');
		} else {
			$('form#prefs_form fieldset ul li.cc_isnotsubscribe ul').hide().css('z-index', '2');
			thisElement.removeClass('selected');
			thisElement.addClass('selected');
			thisElement.parent().next().slideDown().css('z-index', '3');
			thisElement.parent().addClass('open');
		}
	}
}

function updateSelectionCount() {
	$('form#prefs_form fieldset ul li.cc_isnotsubscribe').each( function() {
		var countChildren = $(this).children('ul').children().length;
		var countChecked = $(this).children('ul').children().find('input:checked').length;
		if (countChildren > 0) {
			$(this).children('div').children('label').children('span').remove();
			$(this).children('div').children('label').append('<span> (' + countChecked + '/' + countChildren + ')</span>');
		} else {
			$(this).addClass('nochildren');
		}
		if (countChecked > 0) {
			$(this).addClass('checked');
		} else {
			$(this).removeClass('checked');
		}
	});
}



function loadStatesFromCountry(thisElement) {
	$('select#input_text_stateName option:first-child').text('Loading...');
    $('select#input_text_stateName').attr('data-original', '0');
	var sToCompare = thisElement.find('option:selected').data('thispath');
	$('select#input_text_stateName').load('/content/cliffordchance/client-portal/feeds/ajax-state-list-for-prefs-form.html?tag=' + sToCompare, function() {
		var sValToFind = $(this).attr('data-preselect');
		$(this).find('option').filter( function() {
            $('select#input_text_stateName').attr('data-original', sValToFind);
			return $(this).val() == sValToFind; // changed text() to val for statename fix
		}).prop('selected', true);
        setInputText($('select#input_text_stateName'));
        if ($('select#input_text_stateName').children().length > 1) {
			$('select#input_text_stateName option:first-child').text(sOriginalText).prop('disabled', false);
		} else {
			$('select#input_text_stateName option:first-child').text('No options available').prop('disabled', true);
		}
	});
}

function switchFormPages(thisElement) {
    var sDirection = 'Down';
    if (nSaveAndContinue > thisElement.data('formsection')) {
		sDirection = 'Up';
    }
	nSaveAndContinue = thisElement.data('formsection');
    breadcrumbsAndFormPageSwitch(sDirection);
}

function breadcrumbsAndFormPageSwitch(sDirection) {

	$('section.cp_prefs_' + nSaveAndContinue).slideDown( function() {
		$('html, body').animate({scrollTop: 180});
	});

    if (nSaveAndContinue == 0) {

		$('#prefs_form > fieldset, div.div_prefs_form > h2, div.div_prefs_form > h3, div.div_prefs_form > h5, div#div_error_before_submit').slideDown();
        $('section.cp_prefs_tab').slideUp();
        $('input#prefs_form_submit').val('Save and continue');

    } else if (nSaveAndContinue == 1) {

		$('section.cp_prefs_tab, #prefs_form > fieldset, div.div_prefs_form > h2, div.div_prefs_form > h3, div.div_prefs_form > h5, div#div_error_before_submit').not($('section.cp_prefs_' + nSaveAndContinue)).slideUp();
        $('input#prefs_form_submit').val('Save and continue');

    } else if (nSaveAndContinue == 2) {

        $('section.cp_prefs_tab, #prefs_form > fieldset, div.div_prefs_form > h2, div.div_prefs_form > h3, div.div_prefs_form > h5, div#div_error_before_submit').not($('section.cp_prefs_' + nSaveAndContinue)).slideUp();
        $('input#prefs_form_submit').val('Save and finish');

    } else if (nSaveAndContinue == 3) {

        $('section.cp_prefs_tab, #prefs_form > fieldset, div.div_prefs_form > h2, div.div_prefs_form > h3, div.div_prefs_form > h5, div#div_error_before_submit').not($('section.cp_prefs_' + nSaveAndContinue)).slideUp();
		$('section.cp_prefs_signoff').slideDown( function() {
			$('html, body').animate({scrollTop: 180});
		});
		$('input#prefs_form_submit').val('Go to Client Portal');

	} else if (nSaveAndContinue == 4) {

		window.location.href = '/content/cliffordchance/client-portal.html';

	}

    nSaveAndContinue += 1;

    $('li.li_crumb_' + nSaveAndContinue).prevAll('li.li_crumb').addClass('complete').removeClass('active');
    $('li.li_crumb_' + nSaveAndContinue).removeClass('complete').addClass('active');
    $('li.li_crumb_' + nSaveAndContinue).nextAll('li.li_crumb').removeClass('complete').removeClass('active');

}

// ========================================= Error trapping ====================================== //

function errorTrap(thisInput) {

    var sThisError = thisInput.attr('data-error');
    var sInputVal = thisInput.val().trim();

	if (thisInput.hasClass('input_cleanup')) {

        sThisError = 'Sorry, please use only alpha-numeric characters and basic punctuation';

        if (thisInput.next('span.span_error').length == 0) {
			thisInput.after('<span class="span_error">' + sThisError + '</span>');
        } else {
			thisInput.next().text(sThisError);
        }
        if (sInputVal.indexOf('"') == -1) {
            thisInput.addClass('input_ok').removeClass('input_error');
        } else {
            console.log('FOUND SPECIAL CHAR PROBLEM');
            thisInput.addClass('input_error').removeClass('input_ok');
        }

    }

    if (thisInput.hasClass('input_email') && !thisInput.hasClass('input_error')) {

		sThisError = 'Sorry, that doesn\'t appear to be a valid email address';
        if (thisInput.next('span').length == 0) {
			thisInput.after('<span class="span_error">' + sThisError + '</span>');
        } else {
			thisInput.next().text(sThisError);
        }

        if (sInputVal.length > 6 && sInputVal.indexOf('@') > 0 && sInputVal.lastIndexOf('.') > sInputVal.indexOf('@') && sInputVal.lastIndexOf('.') < sInputVal.length - 2) {
            thisInput.addClass('input_ok').removeClass('input_error');
        } else {
            console.log('FOUND EMAIL PROBLEM');
			thisInput.addClass('input_error').removeClass('input_ok');
        }

    }

    if (thisInput.hasClass('input_required') && !thisInput.hasClass('input_error')) {

        sThisError = thisInput.attr('data-error');
        if (thisInput.next('span').length == 0) {
			thisInput.after('<span class="span_error">' + sThisError + '</span>');
		} else {
			thisInput.next().text(sThisError);
        }
        if (sInputVal == '') {
            console.log('FOUND BLANK PROBLEM');
            thisInput.addClass('input_error').removeClass('input_ok');
        } else {
            thisInput.addClass('input_ok').removeClass('input_error');
        }
    }

    if (thisInput.hasClass('input_error')) {
		thisInput.next('span.span_error').css({'height': '40px', 'opacity': '1'});
	} else {
		thisInput.next('span.span_error').css({'height': '0px', 'opacity': '0'});
	}

    evalSubmit();
}

function cleanUp(s) {
	// s = s.replace(/[^a-zA-Z0-9 &@.,'_-\/()]/g, '');
    s = s.replace('"', '');
	return(s);
}

// Function to call once data has loaded and after each form element ineteraction to tell other form eleemnts to show mandatory warnings
function setMandatoryWarnings(thisInput) {
    // Split the forced selection values onto an array
    var aForcedSelections = (thisInput.attr('data-ccforceselection') != undefined ? thisInput.attr('data-ccforceselection').split(',') : ['0']);
    // Iterate over the forced selection IDs
    for (var i1a = 0; i1a < aForcedSelections.length; i1a++) {

        console.log('setMandatoryWarnings: ' + aForcedSelections[i1a]);

        // Count to decide if we must proceed with the call to the target element
        var nMandatoryCount = 0;
        // First we must evaluate ALL inputs that have the same mandatory target so they don't interfere with one another
        $('input.input_checkbox').each( function() {

            // Check if the looped element has a matching target so we can make a judgment based on whether any of them are active
            if ($(this).attr('data-ccforceselection') != undefined  && aForcedSelections[i1a] != '0') {
                console.log('setMandatoryWarnings: ' + $(this).attr('data-ccforceselection') + ' v ' + aForcedSelections[i1a]);
                if ($(this).attr('data-ccforceselection').indexOf(aForcedSelections[i1a]) > -1 && $(this).prop('checked') && thisInput.prop('checked')) {
                    console.log('setMandatoryWarnings: ' + $(this).attr('data-ccforceselection') + ' v ' + aForcedSelections[i1a]);
                    nMandatoryCount = nMandatoryCount + 1;
                }
            }
        });
        if (nMandatoryCount == 0) {
            // Convenience vars
            var sFieldset = 'fieldset#fieldset_' + aForcedSelections[i1a];
            // find the fieldset
            if ($(sFieldset).find('div.div_error_block').length == 1) {
                $(sFieldset).find('div.div_error_block').remove();
            }
        } else {
            // Check if the element needs to flag another form element as being mandatory
            if (aForcedSelections[i1a] != '0' && thisInput.prop('checked')) {
                // Convenience vars
                var sFieldset = 'fieldset#fieldset_' + aForcedSelections[i1a];
                // find the div error block in the targetted fieldset
                if ($(sFieldset).find('input:checked').length == 0) {
                    if ($(sFieldset).find('div.div_error_block').length == 0) {
                        $(sFieldset).find('p').after('<div class="div_error_block">' + $(sFieldset).data('error') + '</div>');
                    } else {
                        $(sFieldset).find('div.div_error_block').slideDown();
                    }
                } else {
                    console.log('setMandatoryWarnings 7: ' + thisInput.attr('id'));
                    if ($(sFieldset).find('div.div_error_block').length == 0) {
                        $(sFieldset).find('p').after('<div class="div_error_block" style="display: none;">' + $(sFieldset).data('error') + '</div>');
                    } else {
                        $(sFieldset).find('div.div_error_block').slideUp();
                    }
                }
            }
        }
	}
}

/*

// Function to call once data has loaded and after each form element ineteraction to tell other form eleemnts to show mandatory warnings
function setMandatoryWarnings(thisInput) {
    // Count to decide if we must proceed with the call to the target element
    var nMandatoryCount = 0;
    // First we must evaluate ALL inputs that have the same mandatory target so they don't interfere with one another
    $('input.input_checkbox').each( function() {
        // Check if the looped element has a matching target so we can make a judgment based on whether any of them are active
        if ($(this).attr('data-ccforceselection') != undefined  && thisInput.attr('data-ccforceselection') != undefined) {
            if ($(this).attr('data-ccforceselection') == thisInput.attr('data-ccforceselection') && $(this).prop('checked') && thisInput.prop('checked')) {
				nMandatoryCount = nMandatoryCount + 1;
            }
        }
	});
    if (nMandatoryCount == 0) {
		// Convenience vars
		var sFieldset = 'fieldset#fieldset_' + thisInput.attr('data-ccforceselection');
		// find the fieldset
		if ($(sFieldset).find('div.div_error_block').length == 1) {
			$(sFieldset).find('div.div_error_block').remove();
		}
    } else {
        // Check if the element needs to flag another form element as being mandatory
        if (thisInput.attr('data-ccforceselection') != undefined && thisInput.prop('checked')) {
            // Convenience vars
            var sFieldset = 'fieldset#fieldset_' + thisInput.attr('data-ccforceselection');
            // find the div error block in the targetted fieldset
            if ($(sFieldset).find('input:checked').length == 0) {
                if ($(sFieldset).find('div.div_error_block').length == 0) {
                    $(sFieldset).find('p').after('<div class="div_error_block">' + $(sFieldset).data('error') + '</div>');
                } else {
                    $(sFieldset).find('div.div_error_block').slideDown();
                }
            } else {
				console.log('setMandatoryWarnings 7: ' + thisInput.attr('id'));
                if ($(sFieldset).find('div.div_error_block').length == 0) {
                    $(sFieldset).find('p').after('<div class="div_error_block" style="display: none;">' + $(sFieldset).data('error') + '</div>');
                } else {
                    $(sFieldset).find('div.div_error_block').slideUp();
                }
            }
        }
    }
}

*/

// This eval method is only for the local options in the same fiedset as the warning div
function evalMandatoryWarning(thisInput) {

    var thisParentFieldset = thisInput.closest('fieldset');
    var bFoundChecks = false;
    if (thisParentFieldset.find('div.div_error_block').length > 0) {
        thisParentFieldset.find('input:checked').each( function () {
            if (!$(this).closest('.li_checkbox').hasClass('cc_issubscribe') && !$(this).closest('.li_checkbox').hasClass('li_ccisfrequency')) {
                thisInput.closest('fieldset').find('div.div_error_block').slideUp();
				bFoundChecks = true;
            }
        });
        if (!bFoundChecks) {
			thisParentFieldset.find('div.div_error_block').slideDown();
        }
    }
    
}

function evalSubmit() {
	// Look for any fields that have the error class
    var nError = $('form#prefs_form').find('input.input_error').length;

    if (nError > 0) {
        $('input#prefs_form_submit').stop().animate({'opacity': '0.3'}).prop('disabled', true);
    } else {
		$('input#prefs_form_submit').stop().animate({'opacity': '1.0'}).prop('disabled', false);
    }
}

// ================================== START: IA COMMUNICATION FUNCTIONS ================================= //

// Email is hard-coded for testing purposes
function getIAContactViaEmail(sEmail) {
    loadingIcon(true, $('form#prefs_form'), '', '');
    console.log(' ');
    console.log('============================================================================================');
    console.log('-------------------------- Calling getContact() wrapper via EMAIL --------------------------');
    console.log('============================================================================================');
	$.ajax({
        url:'/cc/clp/preferences/contact',
        data:{email: sEmail},
		type:'POST', //
		success: function(data) {
            loadingIcon(false, $('form#prefs_form'), 'One moment please', 'We are configuring your account. Please stay on this page. <br /><strong>Do refresh the page or use your browser\'s back button.</strong>');
            console.log(' ');
            console.log('/////////////////////////// SUCCESS CALLBACK getContact() via EMAIL ///////////////////////////');
            console.log('Email address: ' + sEmail);
            console.log(data);
            console.log('///////////////////////////////////////////////////////////////////////////////////////////////');
            $('div#div_ia_output').text('Data loaded, check console');
            // populateForm(data);
            // checkDependencies();
            // initialiseForm();
		},
        error: function (err) {
            console.log('========================== ERROR CALLBACK getContact() via EMAIL ==========================');
        	console.log(err);
            console.log('===========================================================================================');
        }
    });
}

// GUID is hard-coded for testing purposes
function getIAContactViaGUID(sGuid) {
    loadingIcon(false, $('form#prefs_form'), '', '');
    loadingIcon(true, $('form#prefs_form'), 'One moment please', 'We are retrieving your details from our database.');
    console.log(' ');
    console.log('============================================================================================');
    console.log('-------------------------- Calling getContact() wrapper via GUID ---------------------------');
    console.log('============================================================================================');
	$.ajax({
        url:'/cc/clp/preferences/contact',
        data:{guid: sGuid},
		type:'POST', //
		success: function(data) {

            if (data['srvErrors'] !== undefined) {
            	console.log('SRVR RES: ' + data['srvErrors']['0']['errorDescription']);
                loadingIcon(false, $('form#prefs_form'), '', '');
                loadingIcon(true, $('form#prefs_form'), 'Something went wrong', 'Our database responded with the error: <br /><strong>' + data['srvErrors']['0']['errorDescription'] + '</strong><br/>Please <a href="mailto:online.services@cliffordchance.com?subject=Client%20Portal%20Error%20-%20' + data['srvErrors']['0']['errorCode'] + '" style="color: #45a5da;">email us</a> for further assistance');
            } else {
				loadingIcon(false, $('form#prefs_form'), '', '');
                console.log(' ');
                console.log('/////////////////////////// SUCCESS CALLBACK getContact() via GUID ///////////////////////////');
                console.log('GUID: ' + sGuid);
                console.log(data);
                console.log('//////////////////////////////////////////////////////////////////////////////////////////////');
                populateForm(data);
                checkDependencies();
                initialiseForm();
                updateSelectionCount();
            }

		},
        error: function (err) {
            console.log('========================== ERROR CALLBACK getContact() via GUID ==========================');
        	console.log(err);
            console.log('==========================================================================================');
        }
    });
}

// Final call to unsubscribe wrapper
function unsubscribeContact(sJSON) {
    loadingIcon(true, $('form#prefs_form'), '', '');
    console.log(' ');
    console.log('============================================================================================');
    console.log('-------------------------- Calling unsubscribeContact() wrapper ----------------------------');
    console.log('============================================================================================');
	$.ajax({
        url:'/cc/clp/preferences/unsubscribe',
        data:{req: sJSON},
		type:'POST', //
		success: function(data) {
            loadingIcon(false, $('form#prefs_form'), '', '');
            console.log(' ');
            console.log('/////////////////////////// SUCCESS CALLBACK unsubscribeContact() ////////////////////////////');
            console.log(data);
            console.log('//////////////////////////////////////////////////////////////////////////////////////////////');
            $('section.cp_prefs_signoff').slideDown().prev().slideUp().parent().prevAll().slideUp();
            $('input#unsubscribe_form_submit').fadeOut();
		},
        error: function (err) {
            console.log('========================== ERROR CALLBACK unsubscribeContact() ===========================');
        	console.log(err);
            console.log('==========================================================================================');
        }
    });
}

function updateContact(sJSON) {
    $('section.cp_prefs_signoff').children('h3, h4').css('opacity', '0');
    loadingIcon(true, $('form#prefs_form'), 'One moment please', 'We are saving your changes.');
    console.log(' ');
    console.log('============================================================================================');
    console.log('----------------------------- Calling updateContact() wrapper ------------------------------');
    console.log('============================================================================================');
	$.ajax({
        url:'/cc/clp/preferences/alter/contact',
        data: {req: sJSON},
		type:'POST',
		success: function(data) {
            if (data['srvErrors'] !== undefined) {
            	console.log('SRVR RES: ' + data['srvErrors']['0']['errorDescription']);
                if (data['srvErrors']['0']['errorCode'] == 1000) {
                	loadingIcon(false, $('form#prefs_form'), '', '');
                	loadingIcon(true, $('form#prefs_form'), 'Something went wrong', '<strong>' + data['srvErrors']['0']['errorDescription'] + '</strong><br/>Please <a href="mailto:online.services@cliffordchance.com?subject=Client%20Portal%20Error%20-%20' + data['srvErrors']['0']['errorCode'] + '" style="color: #45a5da;">email us</a> for further assistance');
                } else {
					loadingIcon(false, $('form#prefs_form'), '', '');
                    console.log(' ');
                    console.log('///////////////////////// SUCCESS CALLBACK updateContact() //////////////////////////');
                    console.log(data);
                    console.log('/////////////////////////////////////////////////////////////////////////////////////');
                    console.log('');
                    console.log('/////////////////////// RESETTING FORM VALUES ON CALL BACK //////////////////////////');
                    getIAContactViaGUID(cc_cpuser_guid);
                    $('section.cp_prefs_signoff').children('h3, h4').animate({'opacity': '1'});
                }
            } else {
                loadingIcon(false, $('form#prefs_form'), '', '');
                console.log(' ');
                console.log('///////////////////////// SUCCESS CALLBACK updateContact() //////////////////////////');
                console.log(data);
                console.log('/////////////////////////////////////////////////////////////////////////////////////');
                console.log('');
                console.log('/////////////////////// RESETTING FORM VALUES ON CALL BACK //////////////////////////');
                getIAContactViaGUID(cc_cpuser_guid);
                $('section.cp_prefs_signoff').children('h3, h4').animate({'opacity': '1'});
            }
		},
        error: function (err) {
            console.log('====================== ERROR CALLBACK updateContact() =========================');
        	console.log(err);
            console.log('===============================================================================');
        }
    });
}