﻿/// <reference name="MicrosoftAjax.js" />
/// <reference name="Util.js" />
/// <reference path="../../GlobalJSFunctionsDetail.js" />
var subInfo = null;
var phoneFieldDirty = false;
var profileEditor = false;
var ALT_ENABLED_SMS = "Subscribe via text messaging";
var ALT_ENABLED_EMAIL = "Subscribe via email";
var ALT_SUBBED_SMS = "Unsubscribe from text messages";
var ALT_SUBBED_EMAIL = "Unsubscribe email";
var listFilter = '';
var isProfileAvailable = false;
var savedMailListID = 0;
var listID = 0;
// Add handler to fix IE bug.
$addHandler(window, 'load', function () { invalidateNMLists(); });

$(document).ready(function () {
	if ($("#phoneNumber").val() != '')
		ysnSMS.checked = true;
});

function inflateUIHtml(html) {
	if (html == null)
		return '';
	else
		return (html + '')
			.replace(/%T1%/g, "\"You must sign in to subscribe to or unsubscribe from lists.\"")
			.replace(/%T2%/g, "\"Please enter a phone number and click save to be able to receive text messages from this list.\"")
			.replace(/%T3%/g, "\"Subscribe via text messaging\"")
			.replace(/%T4%/g, "\"Subscribe via email\"")
			.replace(/%T5%/g, "\"Unsubscribe from text messages\"")
			.replace(/%T6%/g, "\"Unsubscribe email\"")
			.replace(/%T7%/g, " height=\"16\" width=\"16\" src=\"/Common/images/NotifyMe/")
			.replace(/%T8%/g, " href=\"/List.aspx\" onclick=\"subUnsub(")
			.replace(/%T9%/g, ");return false;\"><img id=\"img");
}

function invalidateNMLists() {
	/// <summary>IE work-around. Invoked when operations that affect image visibility are made through AJAX callbacks.</summary>
	var nmLists = document.getElementById('nmLists');

	// Hack to fix IE vanishing images bug.
	if (nmLists) {
		nmLists.style.display = 'none';
		nmLists.style.display = 'block';
	}
}

function setListFilter(filter) {
	/// <summary>Sets list section visiblity filter, updates UI.</summary>
	/// <param name="filter" type="String">The ID of the section to show. All other sections are hidden.</param>
	listFilter = filter;
	processFilter();
}

function clearListFilter() {
	/// <summary>Clears list section visiblity filter, updates UI.</summary>
	listFilter = '';
	processFilter();
}

function processFilter() {
	/// <summary>Applies list section visiblity filter.</summary>
	var nmLists = document.getElementById('nmLists');
	var section = nmLists.firstChild;

	while (section != null) {
		if (section.nodeType == 1) {
			if (listFilter == '' || section.id == listFilter)
				section.style.display = 'block';
			else
				section.style.display = 'none';
		}

		section = section.nextSibling;
	}
}

function refreshLists() {
	/// <summary>Refreshes Notify Me lists section.</summary>
	NotifyMeAjax.UpdateSubscriberListsUI(document.aspnetForm.EMAIL.value, document.aspnetForm.NID.value, listID, refreshListsSuccess, refreshListsFailure);
}

function hideAvailableListsMenu() {
	/// <summary>Hides available lists menu with a short delay (100ms).</summary>
	setTimeout(hideAvailableListsMenuNow, 300);
}

function hideAvailableListsMenuNow() {
	/// <summary>Hides available lists menu with immediatly.</summary>
	document.getElementById('availableLists').style.display = 'none';
}

function refreshListsSuccess(result, userContext) {
	/// <summary>Callback for refresh list success.</summary>
	/// <param name="result" type="Int32">Result from call to server.</param>
	/// <param name="userContext" type="String">An arbitrary string passed to the server request routine.</param>

	// Update markup, run JavaScript to update client state.
	var contactInfo = document.getElementById('fstContactInfo');
	var nmLists = document.getElementById('nmLists');
	nmLists.innerHTML = inflateUIHtml(result[0]); 	// HTML from server.
	processFilter(); 								// Apply view filter.
	eval(result[1]); 								// JavaScript from server.

	// Hack for Internet Explorer.
	var nmLists = document.getElementById('nmLists');

	if (nmLists)
		nmLists.style.clear = 'left';

	if (savedMailListID > 0) {
		subUnsub(savedMailListID, true);
		savedMailListID = 0;
	}
}

function refreshListsFailure(error, userContext) {
	/// <summary>Callback for refresh list failure.</summary>
	/// <param name="error" type="Sys.Net.WebServiceError">Error object from server.</param>
	/// <param name="userContext" type="String">An arbitrary string passed to the server request routine.</param>

	// Error occurred updating through AJAX, try postback.
	document.aspnetForm.submit();
}

function phoneNumber_Blur(event) {
	/// <summary>Occurs when user leaves phone number field.</summary>
	/// <param name="event" type="Sys.UI.DomEvent">Stores information on event.</param>
	// var target = (event.target ? event.target : event.srcElement);
	phoneFieldDirty = true;
}

function emailAddressSignIn_KeyDown(event) {
	/// <summary>Event handler for emailAddressSignIn element when a key is pressed down.</summary>
	/// <param name="event" type="Sys.UI.DomEvent">Stores information on event.</param>
	var keyCode = (event.which ? event.which : event.keyCode);

	switch (keyCode) {
		case 13:
		case 10:
			signIn();
			break;
	}
}

function phoneNumber_KeyDown(event) {
	/// <summary>Event handler for phoneNumber element when a key is pressed down.</summary>
	/// <param name="event" type="Sys.UI.DomEvent">Stores information on event.</param>
	var keyCode = (event.which ? event.which : event.keyCode);

	switch (keyCode) {
		case 13:
		case 10:
			saveSMSProfile();
			break;
	}
}

function updateEmailPrefSuccess(result, userContext) {
	/// <summary>Callback for email preference update success.</summary>
	/// <param name="result" type="Int32">Result from call to server.</param>
	/// <param name="userContext" type="String">An arbitrary string passed to the server request routine.</param>
	if (!result) {
		var htmlEmailPref = document.getElementById('HTMLEmailPref');
		htmlEmailPref.checked = !htmlEmailPref.checked;
		alert('Your HTML email preference could not be updated.');
	}
	updateEmailPref = this._updateEmailPref;
}

function updateEmailPrefFailure(error, userContext) {
	/// <summary>Callback for email preference update failure.</summary>
	/// <param name="error" type="Sys.Net.WebServiceError">Error object from server.</param>
	/// <param name="userContext" type="String">An arbitrary string passed to the server request routine.</param>
	var htmlEmailPref = document.getElementById('HTMLEmailPref');
	htmlEmailPref.checked = !htmlEmailPref.checked;
	alert('Your HTML email preference could not be updated due to error.');
	updateEmailPref = this._updateEmailPref;
}

function updateEmailPref(event) {
	/// <summary>Event fired when user clicks email format checkbox. Sends preference to server.</summary>
	/// <param name="event" type="Sys.UI.DomEvent">Stores information on event.</param>
	this._updateEmailPref = updateEmailPref;
	updateEmailPref = function () { alert('Your email preference is being updated. Please wait...'); }

	var emailAddress = document.aspnetForm.EMAIL.value;
	var target = (event.srcElement ? event.srcElement : event.target);
	NotifyMeAjax.UpdateEmailPreference(emailAddress, (target.checked ? 'HTML' : 'Text'), updateEmailPrefSuccess, updateEmailPrefFailure);
}

function updateBusinessPrefSuccess(result, userContext) {
	/// <summary>Callback for business account update success.</summary>
	/// <param name="result" type="Int32">Result from call to server.</param>
	/// <param name="userContext" type="String">An arbitrary string passed to the server request routine.</param>
	if (!result) {
		var personalPref = document.getElementById('PersonalPref');
		personalPref.checked = !personalPref.checked;
		alert('Your personal/business account type could not be updated.');
	}
	updateBusinessPref = this._updateBusinessPref;
}

function updateBusinessPrefFailure(error, userContext) {
	/// <summary>Callback for business account update failure.</summary>
	/// <param name="error" type="Sys.Net.WebServiceError">Error object from server.</param>
	/// <param name="userContext" type="String">An arbitrary string passed to the server request routine.</param>
	var personalPref = document.getElementById('PersonalPref');
	personalPref.checked = !personalPref.checked;
	alert('Your personal/business account type could not be updated due to error.');
	updateBusinessPref = this._updateBusinessPref;
}

function updateBusinessPref(event) {
	/// <summary>Event fired when user clicks business account checkbox. Sends SMS mobile number type (personal, business) to server.</summary>
	/// <param name="event" type="Sys.UI.DomEvent">Stores information on event.</param>
	this._updateBusinessPref = updateBusinessPref;
	updateBusinessPref = function () { alert('Your personal/business account type is being updated. Please wait...'); }

	var emailAddress = document.aspnetForm.EMAIL.value;
	var target = (event.srcElement ? event.srcElement : event.target);
	NotifyMeAjax.UpdateBusinessPreference(emailAddress, target.checked, updateBusinessPrefSuccess, updateBusinessPrefFailure);
}

function ToggleSMSDetails(event, checked, dirty) {
	/// <summary>Event fired when user clicks "I would like to be able to receive..." checkbox.  Hides/shows SMS details DIV</summary>
	/// <param name="event" type="Sys.UI.DomEvent">Stores information on event.</param>
	var $SMS = $('.SMS');
	if (checked) {
		//$SMS.slideDown(300);
		divSMSDetails.style.display = "block";
	}
	else {
		//$SMS.slideUp(300);
		divSMSDetails.style.display = "none";
		document.getElementById('phoneNumber').value = '';
		phoneFieldDirty = dirty;
		saveSMSProfile();
	}
}

function getMinInfoSuccess(result, userContext) {
	var OBFUSC_SMS_NUMBER = 0;
	var BUSINESS_PREF = 1;
	var SHOW_PROFILE_EDITOR = 2;
	var HTML_EMAIL_PREFERED = 3;

	if (document.getElementById('phoneNumber') != null) {
		document.getElementById('phoneNumber').value = result[OBFUSC_SMS_NUMBER];
		document.aspnetForm.SMS.value = result[OBFUSC_SMS_NUMBER];
		if (document.getElementById('phoneNumber').value != '') {
			ysnSMS.checked = true;
			ToggleSMSDetails(null, true, false);
		}
		else {
			ysnSMS.checked = false;
			ToggleSMSDetails(null, false, false);
		}
	}

	if (result[SHOW_PROFILE_EDITOR] == 'true') {
		document.getElementById('firstName').value = '';
		document.getElementById('lastName').value = '';
		document.getElementById('addressLine1').value = '';
		document.getElementById('addressLine2').value = '';
		document.getElementById('city').value = '';
		document.getElementById('postalCode').value = '';
		document.getElementById('how').value = '';
		isProfileAvailable = true;
		document.getElementById('fstFullProfile').style.display = '';
		profileEditor = true;
	} else {
		document.getElementById('fstFullProfile').style.display = 'none';
		profileEditor = false;
	}

	var personalPref = document.getElementById('PersonalPref');

	if (personalPref)
		personalPref.checked = (result[BUSINESS_PREF] == 'true');

	if (result[HTML_EMAIL_PREFERED] != "TEXT") { //the result was cast ToUpper()
		document.aspnetForm.HTMLEmailPref.checked = true;
	}
	else { //this will catch HTML prefered and no selection having been made
		document.aspnetForm.HTMLEmailPref.checked = false;
	}
}

function tryConfirmAgainSuccess(result, userContext) {
	/// <summary>Callback for reconfirmation success.</summary>
	/// <param name="result" type="Int32">Result from call to server.</param>
	/// <param name="userContext" type="String">An arbitrary string passed to the server request routine.</param>

	if (result > 0)
		showSubscriptionModal(false, false);
}

function tryConfirmAgainFailure(error, userContext) {
	/// <summary>Callback for reconfirmation failure.</summary>
	/// <param name="error" type="Sys.Net.WebServiceError">Error object from server.</param>
	/// <param name="userContext" type="String">An arbitrary string passed to the server request routine.</param>

	// Error occurred updating through AJAX, try postback.
	document.aspnetForm.submit();
}

function tryConfirmAgain(emailAddress) {
	/// <summary>Gives user a chance to re-confirm their unconfirmed subscriptions.</summary>
	/// <param name="emailAddress" type="String">Email address.</param>

	NotifyMeAjax.ReactivateEmail(emailAddress, tryConfirmAgainSuccess, tryConfirmAgainFailure);
}

function getBounceNoticeSuccess(result, userContext) {
	/// <summary>Callback for GetBounceNotice() success.</summary>
	/// <param name="result" type="Int32">Result from call to server.</param>
	/// <param name="userContext" type="String">An arbitrary string passed to the server request routine.</param>

	var numResults = result.length;

	if (numResults > 0) {
		// Prepare markup for bounced lists display.
		var spnBounce = document.getElementById('spnBounce');
		var listsText = [];

		for (var i = 0; i < numResults; i++)
			listsText.push(result[i].Name);

		var messageWrapperEm = document.createElement('em');
		messageWrapperEm.innerHTML = '<strong>Due to delivery issues for your account, you are no longer subscribed to the lists below:</strong><br>' + listsText.join(', ') + '<br>';

		var lnkReactivate = document.createElement('a');
		lnkReactivate.href = '#';
		lnkReactivate.style.fontStyle = 'normal';
		lnkReactivate.innerHTML = 'Reactivate Your Subscriptions';
		messageWrapperEm.appendChild(lnkReactivate);

		// Show bounced lists.
		spnBounce.appendChild(messageWrapperEm);
		spnBounce.style.display = '';

		// Attach event handler to reactivation link.
		$(lnkReactivate).click(function (event) {
			event.preventDefault();
			tryConfirmAgain(userContext);
		});
	}
}

function signInSuccess(result, userContext) {
	/// <summary>Callback for sign-in success.</summary>
	/// <param name="result" type="Int32">Result from call to server.</param>
	/// <param name="userContext" type="String">An arbitrary string passed to the server request routine.</param>
	if (result > 0) {
		document.aspnetForm.EMAIL.value = userContext;
		document.aspnetForm.ACCTID.value = result;
		document.getElementById('divSignIn').style.display = 'none';
		document.getElementById('divManage').style.display = 'block';
		document.getElementById('emailAddressManage').value = userContext;
		NotifyMeAjax.GetBounceNotice(userContext, getBounceNoticeSuccess, function () { }, userContext);
		NotifyMeAjax.GetMinProfileInfo(userContext, getMinInfoSuccess, function () { });
		refreshLists();
		signIn = this._signIn;
	}
	else {
		alert('Could not sign in to Notify Me.');
		signIn = this._signIn;
	}
}

function signInFailure(error, userContext) {
	/// <summary>Callback for sign-in failure.</summary>
	/// <param name="error" type="Sys.Net.WebServiceError">Error object from server.</param>
	/// <param name="userContext" type="String">An arbitrary string passed to the server request routine.</param>
	signIn = this._signIn;
	handleServiceMethodError(error);
	return;
}

function subUnsubSuccess(result, userContext) {
	/// <summary>Callback for subscription/unsubscription success.</summary>
	/// <param name="result" type="Boolean">Result from call to server.</param>
	/// <param name="userContext" type="String">Contains state information (type of action, mailing list ID). See subUnsub() NotifyMeAjax calls.</param>
	subUnsubWorkDone(userContext, (result == 0 ? 1 : 0), null);
	invalidateNMLists();
}

function subUnsubFailure(error, userContext) {
	/// <summary>Callback for subscription/unsubscription failure.</summary>
	/// <param name="error" type="Sys.Net.WebServiceError">Error object from server.</param>
	/// <param name="userContext" type="String">Contains state information (type of action, mailing list ID). See subUnsub() NotifyMeAjax calls.</param>
	subUnsubWorkDone(userContext, false, error);
	invalidateNMLists();
}

function closeHelpAndSavePref(isUserHidingHelp) {
	closeModalDialog('editItemBehavior');

	if (isUserHidingHelp) {
		document.aspnetForm.SHOWHELP.value = 'false';
		NotifyMeAjax.SetShowSubHelp(false);
	}
}

function closeHelpAndSavePhone(mobilePhone) {
	closeModalDialog('editItemBehavior');
	if (mobilePhone != '') {
		document.getElementById('phoneNumber').value = mobilePhone;
		ysnSMS.checked = true;
		ToggleSMSDetails(null, true, true);
		phoneFieldDirty = true;
		saveSMSProfile();
	}
}

function closeHelp() {
	closeModalDialog('editItemBehavior');
}

function subUnsubWorkDone(userContext, success, error) {
	/// <summary>Called by callbacks when their work is complete. Allows subsequent requests and finishes request processing.</summary>
	/// <param name="userContext" type="String">Contains state information (type of action, mailing list ID). See subUnsub() NotifyMeAjax calls.</param>
	/// <param name="success" type="Boolean">Whether or not the action was successful.</param>
	/// <param name="error" type="Sys.Net.WebServiceError">Error object from server.</param>
	var isSMS = false, isSub = false, mailListID = 0;
	var mailListDesc = null;

	if (userContext) {
		isSMS = (userContext.charAt(1) == 's');
		isSub = (userContext.charAt(0) == '+');
		mailListID = userContext.substr(2);
		mailListDesc = subInfo[mailListID];
	}

	if (success) {
		var clickedImg;

		if (isSMS) {
			clickedImg = document.getElementById('imgSMS' + mailListID);
			clickedImg.src = "/Common/images/NotifyMe/NotifyMeSMS" + (isSub ? "Selected" : "") + ".png";
			clickedImg.alt = (isSub ? ALT_SUBBED_SMS : ALT_ENABLED_SMS);
			clickedImg.title = clickedImg.alt;
			mailListDesc.isSMS = isSub;
		}
		else {
			clickedImg = document.getElementById('imgEmail' + mailListID)
			clickedImg.src = "/Common/images/NotifyMe/NotifyMeEmail" + (isSub ? "Selected" : "") + ".png";
			clickedImg.alt = (isSub ? ALT_SUBBED_EMAIL : ALT_ENABLED_EMAIL);
			clickedImg.title = clickedImg.alt;
			mailListDesc.isEmail = isSub;
		}

		if (isSub)
			showSubscriptionModal(false, isSMS);
	}
	else
		alert('The list could not be ' + (isSub ? 'subscribed to.' : 'unsubscribed from.'));

	if (mailListDesc) {
		if (isSMS)
			mailListDesc.workSMS = false;
		else
			mailListDesc.workEmail = false;
	}
}

function showSubscriptionModal(force, isSMS) {
	/// <summary>Shows modal after a user attempts to sign up for an SMS or email notification.</summary>
	/// <param name="mailListID" type="Int32">The mailing list to modify subscription for.</param>
	if (document.aspnetForm.SHOWHELP.value == 'true' || force) {
		// Alt Icon: /Common/Images/NotifyMeIconSmall.png
		var iconHTML = '<img style=\"padding-right: 4px; vertical-align: top;\" src="/App_Themes/CP/Images/IconNotifyMe.gif" />';
		var titleText = iconHTML + 'Attention';
		var formName;
		var height;

		if (isSMS) {
			formName = "NotifyMeSMSSubHelp.htm";
			height = "190px";
		}
		else {
			formName = "NotifyMeSubHelp.aspx";
			height = "200px";
		}

		openGenericModalDialog(height, 'subHelp', titleText, '/common/modules/NotifyMe/' + formName);
	}
}

function subUnsub(mailListID, isSMS) {
	/// <summary>Invoked when user clicks a subscribe/unsubscribe image button.</summary>
	/// <param name="mailListID" type="Int32">The mailing list to modify subscription for.</param>
	/// <param name="userContext" type="String">Whether or not the subscription is email or SMS.</param>
	var mailListDesc = subInfo[mailListID];
	var emailAddress = document.aspnetForm.EMAIL.value;
	var phoneNumber = document.getElementById('phoneNumber').value;
	var pendingMsg = 'Your subscription is pending. Please wait...';
	var loggedIn = (document.aspnetForm.EMAIL.value + '' != '');
	var iconHTML = '<img style=\"padding-right: 4px; vertical-align: top;\" src="/App_Themes/CP/Images/IconNotifyMe.gif" />';
	var titleText = iconHTML + 'Attention';

	if (loggedIn) {
		if (isSMS) {
			if ((phoneNumber + '').trim() == '') {
				savedMailListID = mailListID;
				openGenericModalDialog("190px", 'subHelp', titleText, '/common/modules/NotifyMe/NotifyMeNumberSubHelp.htm');
			}
			else if (mailListDesc.canSMS && mailListDesc.workSMS)
				alert(pendingMsg);
			else if (mailListDesc.canSMS) {
				mailListDesc.workSMS = true;

				if (mailListDesc.isSMS)
					NotifyMeAjax.RemoveSubscriptionSMS(emailAddress, mailListID, subUnsubSuccess, subUnsubFailure, '-s' + mailListID);
				else
					NotifyMeAjax.AddSubscriptionSMS(emailAddress, mailListID, subUnsubSuccess, subUnsubFailure, '+s' + mailListID);
			}
			else
				subUnsubFailure();
		}
		else {
			if (mailListDesc.canEmail && mailListDesc.workEmail)
				alert(pendingMsg);
			else if (mailListDesc.canEmail) {
				mailListDesc.workEmail = true;

				if (mailListDesc.isEmail)
					NotifyMeAjax.RemoveSubscriptionEmail(emailAddress, mailListID, subUnsubSuccess, subUnsubFailure, '-m' + mailListID);
				else
					NotifyMeAjax.AddSubscriptionEmail(emailAddress, mailListID, subUnsubSuccess, subUnsubFailure, '+m' + mailListID);
			}
			else
				subUnsubFailure();
		}
	}
	else {
		alert('You must sign in to subscribe to or unsubscribe from lists.');
		document.getElementById('emailAddressSignIn').focus();
	}
}

function signIn() {
	/// <summary>Invoked to sign-in to Notify Me.</summary>
	this._signIn = signIn;
	signIn = function () { alert('Your sign-in process is pending. Please wait...') };

	var emailAddressSignIn = document.getElementById('emailAddressSignIn');

	var fnFail = function (message) {
		alert(message);
		signIn = this._signIn;
		emailAddressSignIn.focus();
	};

	if (!emailValidate(emailAddressSignIn.value))
		fnFail('Email address does not appear to be valid. Please check what you have entered.');
	else {
		var email = emailAddressSignIn.value;
		NotifyMeAjax.EnsureProfileExists(email, signInSuccess, signInFailure, emailAddressSignIn.value);
		NotifyMeAjax.CheckUserForSMSAlert(email, function (result) { document.getElementById('ahrefSMS').style.display = result ? 'block' : 'none'; });
	}
}

function signOut() {
	/// <summary>Invoked to sign-out of Notify Me.</summary>
	var emailAddressSignIn = document.getElementById('emailAddressSignIn');

	emailAddressSignIn.value = '';
	document.aspnetForm.EMAIL.value = '';
	document.aspnetForm.ACCTID.value = '';
	document.aspnetForm.SMS.value = '';
	document.getElementById('divSignIn').style.display = 'block';
	document.getElementById('divManage').style.display = 'none';

	spnBounce.innerHTML = '';
	spnBounce.style.display = 'none';

	refreshLists();
}

function saveSMSSuccess(result, userContext) {
	/// <summary>Callback executed when request to update stored SMS number is successfully made.</summary>
	/// <param name="result" type="Int32">Result from call to server.</param>
	/// <param name="userContext" type="String">An arbitrary string passed to the server request routine.</param>
	var phoneField = document.getElementById('phoneNumber');
	var BULLET_CHAR = '\u25CF';

	if (result) {
		var refreshListSection = (document.aspnetForm.SMS.value == ''
			|| phoneField.value == '');

		document.aspnetForm.SMS.value = phoneField.value;

		if (phoneField.value != '') {
			phoneField.value = phoneObfuscate(phoneField.value, BULLET_CHAR);
			ysnSMS.checked = true;
			ToggleSMSDetails(null, true, false);
		}
		else {
			ysnSMS.checked = false;
			ToggleSMSDetails(null, false, false);
		}

		phoneFieldDirty = false;

		alert('Your SMS number has been updated.');

		if (refreshListSection)
			refreshLists();
	}
	else {
		alert('The SMS number could not be updated.');
		phoneField.focus();
	}
}

function saveSMSFailure(error, userContext) {
	/// <summary>Callback executed when request to update stored SMS number fails.</summary>
	/// <param name="error" type="Sys.Net.WebServiceError">Error object from server.</param>
	alert('An error occurred and the SMS number could not be updated!');
}

function saveSMSProfile() {
	/// <summary>Invoked when user clicks Save SMS link after editing their SMS number. Updates number stored for account.</summary>
	var phoneField = document.getElementById('phoneNumber');

	if (profileEditor && document.getElementById('fstFullProfile').style.display != 'none') {
		if (phoneFieldDirty) {
			phoneField.value = '';
			phoneFieldFirstEdit = false;
		}

		var values = new Object();
		values.firstName = document.getElementById('firstName').value;
		values.lastName = document.getElementById('lastName').value;
		values.addressLine1 = document.getElementById('addressLine1').value;
		values.addressLine2 = document.getElementById('addressLine2').value;
		values.city = document.getElementById('city').value;
		values.state = document.getElementById('txtState').value;
		values.postalCode = document.getElementById('postalCode').value;
		values.how = document.getElementById('how').value;

		var profileDirty = !((('' + values.firstName + values.lastName + values.addressLine1 + values.addressLine2 + values.city + values.postalCode + values.how).trim() == '') && (values.state == 'zz' || (values.state + '') == ''));
		var problems = new Array();

		if (!nullWhitespaceOrEmpty(values.postalCode) && !isZipCode(values.postalCode, intCountryCode)) {
			var codeName = (intCountryCode == 840 ? "ZIP" : "postal");
			problems.push('The ' + codeName + ' code you entered is not valid.');
			document.getElementById('postalCode').focus();
		}

		if (!nullWhitespaceOrEmpty(values.city) && nullWhitespaceOrEmpty(values.state)) {
			problems.push('A state must be entered if a city is specified.');
			document.getElementById('txtState').focus();
		}

		if (problems.length > 0) {
			alert('Please correct these profile issues:\r\n\r\n* ' + problems.join('\r\n* '));
			return;
		}
		else if (profileDirty) {
			var emailAddress = document.aspnetForm.EMAIL.value;

			NotifyMeAjax.UpdateProfile(emailAddress, values.firstName, values.lastName,
				values.addressLine1, values.addressLine2, values.city, values.state,
				values.postalCode, values.how, profileSaveSuccess, profileSaveFailure);
		}
		else {
			document.getElementById('fstFullProfile').style.display = 'none';
		}
	}

	if (phoneFieldDirty && document.getElementById('phoneNumber') != null) {
		var onValidNumber = function (newPhoneNumber) {
			var emailAddress = document.aspnetForm.EMAIL.value;
			NotifyMeAjax.UpdateSMSNumber(emailAddress, newPhoneNumber, saveSMSSuccess, saveSMSFailure);
		}

		validatePhoneInput(onValidNumber);
	}
}

function validatePhoneInput(onSuccess) {
	/// <summary>Validates phone number entered in UI. Displays alerts to user if data is missing or invalid.</summary>
	/// <param name="onSuccess">Function to execute if phone number validates successful.</param>
	var newPhoneNumberField = document.getElementById('phoneNumber');
	var newPhoneNumber = (newPhoneNumberField.value + '').trim();

	if (newPhoneNumber != '' && !phoneValidate(newPhoneNumber)) {
		alert('Please enter a valid U.S. or Canadian phone number in the format shown.');
		newPhoneNumberField.focus();
	}
	else if (phoneStripFormatting(newPhoneNumber) == '5555550123') {
		alert('The example number is fictional and cannot not be used.');
		newPhoneNumberField.focus();
	}
	else {
		newPhoneNumberField.value = newPhoneNumber;
		onSuccess(newPhoneNumber);
	}
}

function profileSaveSuccess(result, userContext) {
	/// <summary>Callback executed when request profile update is successfully made.</summary>
	/// <param name="result" type="Int32">Result from call to server.</param>
	/// <param name="userContext" type="String">An arbitrary string passed to the server request routine.</param>
	if (result) {
		fullProfileFieldSet = document.getElementById('fstFullProfile');
		fullProfileFieldSet.style.display = 'none';
		profileEditor = false;
	}
	else
		alert('Your profile could not be updated.');
}

function profileSaveFailure(error, userContext) {
	/// <summary>Callback executed when request to update profile fails.</summary>
	/// <param name="error" type="Sys.Net.WebServiceError">Error object from server.</param>
	alert('Your profile could not be updated due to error.');
}

function nullWhitespaceOrEmpty(value) {
	/// <summary>Returns true if value is null, whitespace, or empty.</summary>
	/// <param name="id" type="String">Value to check.</param>
	return (('' + value).trim() == '');
}

function toggleMessageSection(id) {
	/// <summary>Toggles visibility of sections on message view.</summary>
	/// <param name="id" type="String">Id of element to toggle message section for.</param>
	var messageBody = document.getElementById(id);
	var messageArrow = document.getElementById(id + '_arrow');

	if (messageBody.style.display == 'none') {
		messageBody.style.display = 'block';
		messageArrow.innerHTML = '&#9660;';
	}
	else {
		messageBody.style.display = 'none';
		messageArrow.innerHTML = '&#9658;';
	}
}
