﻿function MicrosoftJSONSerializationFix(key, value) {
	if (typeof value === 'string') {
		var isDate = /Date\(([-+]?\d+[-+]?\d+)\)/.exec(value);
		if (isDate) {
			value = new Date(eval(isDate[1]));
		}
	} 
	return value;
}
function extend(origArr, arr) {
	origArr.push.apply(origArr, arr);
};

function searchArray(arrayToSearch, itemToLookFor) {
	arrayToSearch.sort();
	var length = arrayToSearch.length;
	for (var i = 0; i < length; i++) {
		if (arrayToSearch[i] === itemToLookFor)
			return true;
		else if (itemToLookFor < arrayToSearch[i])
			return false;
	}
	return false;
}
function DetectSmartPhoneBrowser() {
	var deviceIphone = "iphone";
	var deviceIpod = "ipod";
	var deviceAndroid = "android";
	var uagent = navigator.userAgent.toLowerCase();
	   
	if (uagent.search(deviceIphone) > -1 || uagent.search(deviceIpod) > -1 || uagent.search(deviceAndroid) > -1) {
		return true;
	}
	else return false;
}
function ReturnEmptyIfNull(stringToCheck) {
	if (stringToCheck === null) return "";
	if (stringToCheck === "null") return "";
	return stringToCheck;
}
function getUrlVars() {
	var vars = [], hash;
	var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
	for (var i = 0; i < hashes.length; i++) {
		hash = hashes[i].split('=');
		vars.push(hash[0]);
		vars[hash[0]] = hash[1];
	}
	return vars;
}

var isPendingSubscriptionAction = false;
var redirectToSubModifyOnComplete = false;


///////////////////////////////////////////////////////////////////////////////////////////
// START: LOGIN 
///////////////////////////////////////////////////////////////////////////////////////////
var LoginPage = function() {
	function ToggleElements(elementID1, elementID2) {
		$("[id$=" + elementID1 + "]").show();
		$("[id$=" + elementID2 + "]").hide();
	}
	function setLoginHtml() {
		var application = getUrlVars()["app"];

		if (!application) {
			application = "default";
		}

		$("#login-text-container").load("/Shared/Includes/LoginText_" + application + ".html");
	}
	return {
		wireup: function() {
			var jitterBugRadio = $("[id$=radJitterbug]");
			var smartPhoneRadio = $("[id$=radSmartPhone]");
			var forgotLoginLink = $("#login-forgot a");
			//Set inital display state base on whats checked
			if (jitterBugRadio.is(":checked")) {
				ToggleElements("divMDN", "divEmail");
				forgotLoginLink.attr("href", "Password.aspx");
			}
			else if (smartPhoneRadio.is(":checked")) {
				ToggleElements("divEmail", "divMDN");
				forgotLoginLink.attr("href", "MobileAppPassword.aspx");
			}
			else {
				jitterBugRadio.attr("checked", true);
				forgotLoginLink.attr("href", "Password.aspx");
			}

			//Set click events for radio buttons
			jitterBugRadio.click(function() {
				ToggleElements("divMDN", "divEmail");
				forgotLoginLink.attr("href", "Password.aspx");
			});
			smartPhoneRadio.click(function() {
				ToggleElements("divEmail", "divMDN");
				forgotLoginLink.attr("href", "MobileAppPassword.aspx");
			});
			setLoginHtml();
		}
	};
} ();
///////////////////////////////////////////////////////////////////////////////////////////
// END: LOGIN 
///////////////////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////////////////
// START: INPUT MASK 
///////////////////////////////////////////////////////////////////////////////////////////
//Common Input Masking definitions
var InputMask = function() {
	function maskDefinitions() {
		//this definition includes all numbers
		$.mask.definitions["#"] = "[0123456789]";
		//this definition excludes 0 and 1
		$.mask.definitions["9"] = "[23456789]";
	}
	function unmaskAll() {
		$(".mask_zip").unmask();
		$(".mask_phone").unmask();
		$(".mask_ccExp").unmask();
		$(".mask_ccAmex").unmask();
		$(".mask_ccOther").unmask();
		$(".mask_cvvOther").unmask();
		$(".mask_cvvAmex").unmask();
	}
	function setMasks() {
		$(".mask_zip").mask("#####?-####", { placeholder: "_" });
		$(".mask_phone").mask("?(9##) ###-####", { placeholder: "_" });
		$(".mask_ccExp").mask("##/####", { placeholder: "_" });
		$(".mask_ccAmex").mask("####-######-#####", { placeholder: "_" });
		$(".mask_ccOther").mask("####-####-####-####", { placeholder: "_" });
		$(".mask_cvvOther").mask("###", { placholder: "_" });
		$(".mask_cvvAmex").mask("####", { placholder: "_" });
	}
	return {
		wireup: function() {
			maskDefinitions();
			//Unbinding masks just in case
			unmaskAll();
			//Binding masks
			setMasks();
		}
	};
} ();
///////////////////////////////////////////////////////////////////////////////////////////
// END: INPUT MASK page
///////////////////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////////////////
// START: ACCOUNT SETTINGS page
///////////////////////////////////////////////////////////////////////////////////////////
var AccountSettingsPage = function () {
	var errorClass = "errorMessage";
	var successClass = "successMessage";
	function toggleDisplay(outgoingSelector, outgoingSlideDir, incommingSelector, incommingSlideDir) {
		var outgoingElement = $(outgoingSelector);
		var incommingElement = $(incommingSelector);
		outgoingElement.toggle('slide', { direction: outgoingSlideDir });
		incommingElement.toggle('slide', { direction: incommingSlideDir });
		$(".page_wrapper").css("min-height", incommingElement.height());
	}

	function getContactInformationObject() {
		var firstName = $("[id$=txtFirstName]").val();
		var lastName = $("[id$=txtLastName]").val();
		var middleName = $("[id$=txtMiddleName]").val();
		var email = $("[id$=txtEmail]").val();
		var phone = $("[id$=txtPhoneNumber]").val();
		var address = $("[id$=txtAddress]").val();
		var city = $("[id$=txtCity]").val();
		var state = $("[id$=ddlState]").val();
		var zip = $("[id$=txtZip]").val();

		var addressObj = new Address(address, city, state, zip);
		var userContactInfo = new UserContactInfo(firstName, lastName, middleName, email, phone, addressObj);
		return userContactInfo;
	}
	function getBillingInformationObject() {
		var cardType = $("[id$=ddlCreditCardType]").val();
		var firstName = $("[id$=txtBillFirstName]").val();
		var lastName = $("[id$=txtBillLastName]").val();
		var creditCardNumber = $("[id$=txtCreditCard]").val();
		var lastFour = creditCardNumber.substr(creditCardNumber.length - 4);
		var cvv = $("[id$=txtCVV2Code]").val();

		var ccMonth = $("[id$=ddlExpirationMonth]").val() - 1; //js months run from 0 - 11
		var ccYear = $("[id$=ddlExpirationYear]").val();
		var creditCardExp = new Date(ccYear, ccMonth, 1);

		var address1 = $("[id$=txtBillAddress]").val();
		var city = $("[id$=txtBillCity]").val();
		var state = $("[id$=ddlBillState]").val();
		var zip = $("[id$=txtBillZip]").val();

		var addressObj = new Address(address1, city, state, zip);
		var creditCardObj = new CreditCard(firstName, lastName, creditCardNumber, cvv, lastFour, creditCardExp, cardType);
		return new UserBillingInfo(creditCardObj, addressObj);
	}
	function getAppSubscriptionObject() {
		var appSubscription = $("#submodify_form").data("sub");
		var subTypes = $("#submodify_form").data("subTypes");
		var isForSelf = $("#radAssignment_1").attr("checked") === "checked";

		if (!isForSelf) {
			appSubscription.UsingAccountEmail = $("#txtUsingAcctEmail").val();
		}

		var sTypeId = parseInt($("#subscription_type").val());

		var sType;
		var length = subTypes.length;
		for (var i = 0; i < length; i++) {
			if (subTypes[i].SubscriptionTypeId === sTypeId) {
				sType = subTypes[i];
				break;
			}
		}
		appSubscription.SubscriptionType = sType;
		return appSubscription;
	}
	function bindContactInformation(userContactInfo) {
		var accountInfo = getOrigUserAccountInfo();
		if (accountInfo !== null) {
			accountInfo.ContactInformation = userContactInfo;
			setOrigUserAccountInfo(accountInfo)

			//Bind field values
			$("[id$=txtFirstName]").val(ReturnEmptyIfNull(userContactInfo.FirstName));
			$("[id$=txtLastName]").val(ReturnEmptyIfNull(userContactInfo.LastName));
			$("[id$=txtMiddleName]").val(ReturnEmptyIfNull(userContactInfo.MiddleName));
			$("[id$=txtEmail]").val(ReturnEmptyIfNull(userContactInfo.Email));
			$("[id$=txtPhoneNumber]").val(ReturnEmptyIfNull(userContactInfo.PhoneNumber));
			$("[id$=txtAddress]").val(ReturnEmptyIfNull(userContactInfo.ContactAddress.StreetAddress1));
			$("[id$=txtCity]").val(ReturnEmptyIfNull(userContactInfo.ContactAddress.City));
			$("[id$=ddlState]").val(userContactInfo.ContactAddress.State);
			$("[id$=txtZip]").val(ReturnEmptyIfNull(userContactInfo.ContactAddress.Zipcode));
			InputMask.wireup();
		}
	}
	function bindAllInformation(allUserInfo) {
		//$("#billing_form .info_box h3").html("");		// TODO_MKT: May need this, looks to be clearing out all the fields before rebind
		var accountInfo = getOrigUserAccountInfo();
		if (accountInfo !== null) {
			accountInfo.ContactInformation = allUserInfo.UserContactInfo;
			accountInfo.BillingInformation = allUserInfo.UserBillingInfo;
			setOrigUserAccountInfo(accountInfo)

			$("[id$=txtFirstName]").val(ReturnEmptyIfNull(allUserInfo.UserContactInfo.FirstName));
			$("[id$=txtLastName]").val(ReturnEmptyIfNull(allUserInfo.UserContactInfo.LastName));
			$("[id$=txtMiddleName]").val(ReturnEmptyIfNull(allUserInfo.UserContactInfo.MiddleName));
			$("[id$=txtEmail]").val(ReturnEmptyIfNull(allUserInfo.UserContactInfo.Email));
			$("[id$=txtPhoneNumber]").val(ReturnEmptyIfNull(allUserInfo.UserContactInfo.PhoneNumber));
			$("[id$=txtAddress]").val(ReturnEmptyIfNull(allUserInfo.UserContactInfo.ContactAddress.StreetAddress1));
			$("[id$=txtCity]").val(ReturnEmptyIfNull(allUserInfo.UserContactInfo.ContactAddress.City));
			$("[id$=ddlState]").val(allUserInfo.UserContactInfo.ContactAddress.State);
			$("[id$=txtZip]").val(ReturnEmptyIfNull(allUserInfo.UserContactInfo.ContactAddress.Zipcode));

			$("[id$=ddlCreditCardType]").attr('selectedIndex', allUserInfo.UserBillingInfo.UserCreditCard.CardType);
			$("[id$=txtBillFirstName]").val(ReturnEmptyIfNull(allUserInfo.UserBillingInfo.UserCreditCard.FirstName));
			$("[id$=txtBillLastName]").val(ReturnEmptyIfNull(allUserInfo.UserBillingInfo.UserCreditCard.LastName));
			$("[id$=txtCreditCard]").val(ReturnEmptyIfNull(allUserInfo.UserBillingInfo.UserCreditCard.FormattedLastFourOfCc));
			$("[id$=txtCVV2Code]").val("");
			$("[id$=txtBillAddress]").val(ReturnEmptyIfNull(allUserInfo.UserBillingInfo.BillingAddress.StreetAddress1));
			$("[id$=txtBillCity]").val(ReturnEmptyIfNull(allUserInfo.UserBillingInfo.BillingAddress.City));
			$("[id$=ddlBillState]").val(allUserInfo.UserBillingInfo.BillingAddress.State);
			$("[id$=txtBillZip]").val(allUserInfo.UserBillingInfo.BillingAddress.Zipcode);

			var expDate = new Date(allUserInfo.UserBillingInfo.UserCreditCard.CardExpirationDate);
			$("[id$=ddlExpirationMonth]").val(expDate.getMonth() + 1);
			$("[id$=ddlExpirationYear]").val(expDate.getFullYear());
			InputMask.wireup();

		}
	}
	function bindAccountBalance(currentBalance) {
		var accountInfo = getOrigUserAccountInfo();
		if (accountInfo !== null) {
			accountInfo.AccountBalance = currentBalance;
			setOrigUserAccountInfo(accountInfo)

			$("[id$=txtAccountBalance]").val(currentBalance);
			$("#payForm_AccountBalance").html(currentBalance);
			$(".account_balance span").html("$" + currentBalance);
			AccountSettingsPage.checkForPageConditions();
		}
	}
	function bindSubscription(subscriptions) {
		var accountInfo = getOrigUserAccountInfo();
		if (accountInfo !== null) {
			accountInfo.Subscriptions = subscriptions;
			setOrigUserAccountInfo(accountInfo);
			bindSubscriptionDisplay(subscriptions);
			AccountSettingsPage.buildSubsManageArea();
		}
	}
	function bindSubscriptionDisplay(subscriptions) {
		var subscriptionList = $("#account_display .right_column .row .content ul");
		subscriptionList.html("");
		var length = subscriptions.length;
		var htmlArr = new Array();
		var nextBillAmount = 0;
		for (var i = 0; i < length; i++) {
			nextBillAmount += isNaN(subscriptions[i].SubscriptionType.Price) ? 0 : subscriptions[i].SubscriptionType.Price;
			htmlArr.push("<li>", subscriptions[i].ApplicationName, "</li>");
		}
		$(".nextBillAmount").html("$" + nextBillAmount.toString());
		subscriptionList.html(htmlArr.join(""));
	}
	function clearPasswordFields() {
		$("[id^=txtOPassword]").val("");
		$("[id^=txtNPassword]").val("");
		$("[id^=txtCPassword]").val("");
	}
	function setBrowserHash(hashToSet, delay) {
		setTimeout("window.location.hash = '" + hashToSet + "';", delay);
	}

	function getOrigUserAccountInfo() {
		var accountInformation = $("[id$=hideOrigAcctValues]").val();
		if (accountInformation !== "" && accountInformation !== null) {
			accountInformation = JSON.parse(accountInformation, MicrosoftJSONSerializationFix);
			return accountInformation;
		}
		else return null;
	}
	function setOrigUserAccountInfo(accountInfo) {
		var json = JSON.stringify(accountInfo);
		$("[id$=hideOrigAcctValues]").val(json);
	}
	function getNotification(statusCode, complexType) {
		switch (statusCode) {
			case "403":
			case "12030":
			case "401":
				return new Notification("Your login has expired please <a href=\"/Login.aspx\">Click Here</a> to login.", "Login Expired", errorClass);
			case "500":
				return new Notification("An unknown error has occured.  Please try again.", "Error: Internal Server Error", errorClass);
			case "409":
				switch (complexType) {
					case "UserContactInfo":
						return new Notification("It appears that the specified email has already been registered with us.", "We're sorry, that email can not be used", errorClass);
					case "Subscription":
						return new Notification("Our records show that you are already subscribed to this application.  Please unsubscribe from the current subscription before trying again.", "It looks like you have already registered with us", errorClass);
					case "UserBillingInfo":
						return new Notification("Please double check the address you entered and try again.", "We're sorry, we can't find this address", errorClass);
				}
				break;
			case "412":
				switch (complexType) {
					case "Subscription":
						handleBillingInfoRequired(true)
						return null;
					case "Password":
						return new Notification("The password you entered into the \"Current Password\" field does not match the password for your account.  Please check your entry and try again.", "We're sorry, that password seems to be incorrect", errorClass);
				}
				break;
			case "Payment":
				return new Notification("We have successfully received your payment.", "Great! Your payment has been processed", successClass);
			case "Payment-Error":
				return new Notification("Please try entering your payment information again.", "We're sorry, we seem to be having a problem processing your payment", errorClass);
			case "Password":
				return new Notification("You can start using your new password immediately.", "Great! Your password has been updated", successClass);
			case "SavedData":
				return new Notification("Your account information has been saved", "Great! Your account has been updated", successClass);
			case "DuplicateSubscription":
				return new Notification("You can not have more than one subscription for the same application for the same user.", "We're sorry, this appears to be a duplicate subscription", errorClass);
		}
	}
	function handleBillingInfoRequired(isPending) {
		isPendingSubscriptionAction = isPending;
		redirectToSubModifyOnComplete = !isPending;
		$("#billing_form .info_box h3").html("Please add your billing information before trying to add a paid subscription.");
		setBrowserHash("billing", 0);
	}
	function doesUserHaveBillingInfo() {
		var account = getOrigUserAccountInfo();
		var billInfo = account.BillingInformation;
		if (billInfo === null) return false;
		if (billInfo.UserCreditCard === null) return false;
		if (billInfo.BillingAddress === null) return false;

		return billInfo.UserCreditCard.LastName !== null && billInfo.UserCreditCard.LastName !== "";
	}
	function doAllSubTypesRequireBillInfo(sTypes) {
		var length = sTypes.lenghth;
		for (var i = 0; i < length; i++) {
			if (!sTypes[i].RequiresBillingInfo) {
				return false;
			}
		}
		return true;
	}
	function showNotification(notification, referrerHash) {
		// clear other notifications out
		$("#errorNotificationSpan").html("");
		$("#notification_form h2 span").html("");
		$("#notification_form p").html("");

		// if its successClass hide the panel showing that they owe a balance, and turn off the paynow button, turn on the save button
		if (notification.CssClass === successClass) {
			$("[id$=pnlNotificationArea]").hide();
			$("[id$=pnlReactivateBtn]").hide();
			$("[id$=pnlSaveBtn]").show();
		}


		$("#notification_form").removeClass(successClass).removeClass(errorClass).addClass(notification.CssClass);
		$("#notification_form h2 span").html(notification.Title);
		$("#notification_form p").html(notification.Message);
		if ($("#notification_form").css('visibility') == 'hidden') {
			$("#notification_form").css('visibility', 'visible');
		}

		setBrowserHash("notification", 0);
		WaitPanel.Hide();
	}
	function getFormSelectorByCType(complexType) {
		switch (complexType) {
			case "UserContactInfo":
				return "#contact_form";
			case "UserBillingInfo":
				return "#billing_form";
			// toggle the notification form here for all other cases
			// this will put a box at the bottom of the page under the submit buttons
			default:
				if ($("#notification_form").css('visibility') == 'hidden') {
					$("#errorNotificationSpan").html("");
					$("#notification_form").css('visibility', 'visible');
				}
				return "#errorNotificationSpan";
		}
	}
	function showServerSideValError(complexType, errorMessages) {
		var html = new Array();
		var length = errorMessages.length;

		html.push("<div class=\"error\"><ul>");
		for (var i = 0; i < length; i++) {
			html.push("<li>", errorMessages[i], "</li>");
		}
		html.push("</div></ul>");
		var selector = getFormSelectorByCType(complexType);
		$(selector + " div.error").remove();
		$(selector).append(html.join(""));
		$(".page_wrapper").css("min-height", $(selector).height());
	}
	function setMaskClassForCcField() {
		var selectedValue = $("[id$=ddlCardType]").val();
		var creditCardField = $("[id$=txtCreditCard]");
		var cvvField = $("[id$=txtCVV]");

		if (selectedValue !== "3") {
			creditCardField.removeClass("mask_ccAmex").removeClass("mask_ccOther").addClass("mask_ccOther");
			cvvField.removeClass("mask_cvvAmex").removeClass("mask_cvvOther").addClass("mask_cvvOther");
		}
		else {
			creditCardField.removeClass("mask_ccOther").removeClass("mask_ccAmex").addClass("mask_ccAmex");
			cvvField.removeClass("mask_cvvAmex").removeClass("mask_cvvOther").addClass("mask_cvvAmex");
		}
		creditCardField.removeClass("valCc").removeClass("valCc3").removeClass("valCc4").removeClass("valCc5").removeClass("valCc6").addClass("valCc" + selectedValue);
		InputMask.wireup();
	}
	function buildAvailSubsArea(subscriptions) {
		var length = subscriptions.length;
		var htmlArr = new Array();
		htmlArr.push("<h3><span>Available Apps</span></h3>");
		for (var i = 0; i < length; i++) {
			extend(htmlArr, buildSubscriptionRow(subscriptions[i], "sub_inactive", "Subscribe", true));
		}
		return htmlArr.join("");
	}
	function buildMySubsArea(subscriptions, accountId) {
		var htmlArr = new Array();
		var otherEmailArr = new Array();
		var otherUserHtmlArr = new Array();
		var length = subscriptions.length;
		htmlArr.push("<h3><span>My Subscriptions</span></h3>");

		//Build base html arrays
		for (var i = 0; i < length; i++) {
			if (accountId === subscriptions[i].UsingAccountId) {
				extend(htmlArr, buildSubscriptionRow(subscriptions[i], "sub_active", "Manage", false));
			}
			else {
				if (!searchArray(otherEmailArr, subscriptions[i].UsingAccountEmail.toUpperCase())) {
					otherEmailArr.push(subscriptions[i].UsingAccountEmail.toUpperCase());
				}
				otherUserHtmlArr.push({
					Email: subscriptions[i].UsingAccountEmail.toUpperCase(),
					HtmlArr: buildSubscriptionRow(subscriptions[i], "sub_active", "Manage", false)
				});
			}
		}
		extend(htmlArr, buildOtherUserSubsArea(otherEmailArr, otherUserHtmlArr));
		return htmlArr.join("");
	}
	function buildOtherUserSubsArea(otherEmails, otherHtmlArray) {
		var eLength = otherEmails.length;
		var hLength = otherHtmlArray.length;
		var htmlArr = new Array();
		for (var i = 0; i < eLength; i++) {
			htmlArr.push("<h3><span>For ", otherEmails[i].toUpperCase(), "</span></h3>");
			for (var j = 0; j < hLength; j++) {
				if (otherHtmlArray[j].Email.toUpperCase() === otherEmails[i].toUpperCase()) {
					extend(htmlArr, otherHtmlArray[j].HtmlArr);
				}
			}
		}
		return htmlArr;
	}
	function buildSubscriptionRow(subscription, rowClass, btnText, isNew) {
		var subId = subscription.SubscriptionId;
		var pAcctId = subscription.PayingAccountId;
		var uAcctId = subscription.UsingAccountId;
		var uAcctEmail = subscription.UsingAccountEmail;
		var sku;
		var appName = subscription.ApplicationName;
		var appId = subscription.ApplicationId;
		var startDate = subscription.StartDate;
		var trialPeriod = subscription.TrialPeriod === null ? 0 : subscription.TrialPeriod;

		var sTypeId;
		var subTypeName;
		var buttonClass = "btnManage";

		if (btnText === "Subscribe") buttonClass = "btnSubscribe";

		if (subscription.SubscriptionType) {
			sku = subscription.SubscriptionType.Sku;
			sTypeId = subscription.SubscriptionType.SubscriptionTypeId;
			subTypeName = subscription.SubscriptionType.SubscriptionTypeName;
		}

		var htmlArr = new Array();
		htmlArr.push("<div class=\"row ", rowClass, "\">");
		htmlArr.push("<div class=\"description\">");
		htmlArr.push(appName);
		if (subTypeName !== null && subTypeName !== undefined && subTypeName !== "") {
			htmlArr.push(" - ", subTypeName);
		}
		if (subscription.TrialPeriod !== null) {
			var today = new Date();
			var trialTicks = trialPeriod * 24 * 60 * 60 * 1000;
			var daysRemaining = Math.round((subscription.StartDate.getTime() - today.getTime() + trialTicks) / (24 * 60 * 60 * 1000));
			daysRemaining = daysRemaining < 0 ? 0 : daysRemaining;
			htmlArr.push("<br />", daysRemaining, " days remaining");
		}
		htmlArr.push("</div>");
		htmlArr.push("<div class=\"content\">");
		htmlArr.push("<a href=\"#submodify\" class=\"", buttonClass, "\" onclick=\"AccountSettingsPage.modifySubscription('", subId, "', '", pAcctId, "', '", uAcctId, "', '", uAcctEmail, "', '", sku, "', '", appName, "', '", appId, "', '", sTypeId, "', ", isNew, ", ", "'", startDate, "', ", trialPeriod, "); return false;\"><label>", btnText, "</label><img src=\"/images/spacer.gif\" alt=\"\" /></a></div>");
		htmlArr.push("</div>");
		return htmlArr;
	}
	function populateSubTypes(sTypes) {
		var htmlArr = new Array();
		var length = sTypes.length;
		htmlArr.push("<option value=\"\">Select Subscription Type</option>");
		for (var i = 0; i < length; i++) {
			htmlArr.push("<option value=\"", sTypes[i].SubscriptionTypeId, "\">", sTypes[i].SubscriptionTypeName, "</option>");
		}
		$("#subscription_type").html(htmlArr.join(""));
	}
	function validateSubscription(appSubscription) {
		var account = getOrigUserAccountInfo();
		if (account !== null) {
			//If subscription id is not null or empty then return true as this is an existing subscription
			//so we don't need to check for duplicates.
			if (appSubscription !== null && appSubscription.SubscriptionId !== null && appSubscription.SubscriptionId !== "") {
				return true;
			}
			else {
				var currSubs = account.Subscriptions;
				var length = currSubs.length;
				for (var i = 0; i < length; i++) {
					if (currSubs[i].UsingAccountEmail.toUpperCase() === appSubscription.UsingAccountEmail.toUpperCase()
								&& currSubs[i].ApplicationName.toUpperCase() === appSubscription.ApplicationName.toUpperCase()) {
						return false;
					}
					if (appSubscription.UsingAccountEmail === ""
								&& currSubs[i].UsingAccountEmail.toUpperCase() === account.ContactInformation.Email.toUpperCase()
								&& currSubs[i].ApplicationName.toUpperCase() === appSubscription.ApplicationName.toUpperCase()) {
						return false;
					}
				}
				return true;
			}
		}
	}
	function checkForDoAction() {
		var doActionField = $("[id$=hideDoAction]").val();

		// so if there is an action then send them to the appropriate page
		switch (doActionField) {
			case "subscribe":
				var appID = $("[id$=hideAppID]").val();
				var subscriptionID = $("[id$=hideSubscriptionID]").val();
				window.location.replace("MyApps.aspx?doAction=subscribe&appID=" + appID + "&subscriptionID=" + subscriptionID);
				break;
			case "gift":
				window.location.replace("SubscriptionGift.aspx");
				break;
		}
	}

	return {
		wireupEvents: function () {
			AccountSettingsPage.buildSubsManageArea();
			$(".btnHash").click(function () {
				if (DetectSmartPhoneBrowser()) {
					scroll(0, 0);
					WaitPanel.Show();
				}
				setBrowserHash(this.hash, 0);
				return false;
			});
			$(".btnCancel").click(function () {
				if (DetectSmartPhoneBrowser()) {
					WaitPanel.Show();
				}
				AccountSettingsPage.resetForm();
				setBrowserHash(this.hash, 0);
				return false;
			});
			$("[id$=ddlCardType]").change(function () {
				setMaskClassForCcField();
			});
			$("[id^=radAssignment]").click(function () {
				$("#txtUsingAcctEmail").removeClass("required").removeClass("email");
				if (this.checked && $(this).val() === "other") {
					$("#txtUsingAcctEmail").addClass("required").addClass("email");
					$(".altUserEmail").show();
				}
				else $(".altUserEmail").hide();
			});

			setMaskClassForCcField();
			InputMask.wireup();
		},
		//        checkUrlHash: function() {
		//            var hash = window.location.hash;
		//            if (hash && hash !== "#") {
		//                var incommingSelector = hash + "_form";
		//                var visibleFormId = $(".form:visible").attr("id");
		//                var outgoingSelector = "";
		//                if (visibleFormId && "#" + visibleFormId !== incommingSelector) outgoingSelector = "#" + visibleFormId;
		//                else outgoingSelector = ".display";
		//                toggleDisplay(outgoingSelector, "left", incommingSelector, "right");
		//            }
		//            else {
		//                var incommingSelector = ".display";
		//                var outgoingId = $(".form:visible").attr("id");
		//                if (outgoingId) toggleDisplay("#" + outgoingId, "right", incommingSelector, "left");
		//            }
		//            WaitPanel.Hide();
		//        },
		checkForPageConditions: function () {
			var accountBalanceHidInput = $("[id$=txtAccountBalance]");
			var accountBalanceDiv = accountBalanceHidInput.parents(".account_balance");
			var currentBalance = parseInt(accountBalanceHidInput.val());
			if (currentBalance > 0) {
				accountBalanceDiv.siblings(".btnPayNow").show();
				accountBalanceDiv.addClass("account_pastdue");
			}
			else {
				accountBalanceDiv.siblings(".btnPayNow").hide();
				accountBalanceDiv.removeClass("account_pastdue");
			}
		},
		//		changeSubscriptionStatus: function () {
		//			WaitPanel.Show();
		//			if (FormValidation.validateForm("#submodify_form")) {
		//				var appSubscription = getAppSubscriptionObject();
		//				if (validateSubscription(appSubscription)) {
		//					DataAccess.changeSubscription("Subscription", appSubscription, AccountSettingsPage.rebindInformation, AccountSettingsPage.errorSavingInformation);
		//				}
		//				else {
		//					var notification = getNotification("DuplicateSubscription");
		//					showNotification(notification);
		//				}
		//			}
		//			else {
		//				WaitPanel.Hide();
		//			}
		//		},
		changeSubscriptionStatus: function () {
			// steps to subscribe
			// 1. this is coming from the my apps page, but i need to validate that we have account info for this user
			//		a. if yes then let them subscribe
			//		b. if no, store that they want to subscribe and what app and send them to account info page
			WaitPanel.Show();
			if (doesUserHaveBillingInfo) {
				var appSubscription = getAppSubscriptionObject();
				if (validateSubscription(appSubscription)) {
					DataAccess.changeSubscription("Subscription", appSubscription, AccountSettingsPage.rebindInformation, AccountSettingsPage.errorSavingInformation);
				}
				else {
					var notification = getNotification("DuplicateSubscription");
					showNotification(notification);
				}
			}
			// if they don't have billing info send them to account settings page with action to subscribe to app
			else {
				WaitPanel.Hide();
				// TODO_MKT: need to put some stuff in here storing the action they were doing when redirected, like the app they are
				// subscribing to, and the price. maybe you can add the app price to their current balance and show that at the top
				// of the new page and the app they are subscribing to
				window.location.replace("AccountSettings.aspx");
			}
		},
		// needed a function to save all data so that any errors in anything can get shown
		saveAllInformation: function () {
			WaitPanel.Show();

			if (FormValidation.validateForm("#divCustomerInfo") && FormValidation.validateForm("#divBillingInfo")) {
				var userContactInfo = getContactInformationObject();
				var userBillingInfo = getBillingInformationObject();
				var allInformation = { UserContactInfo: userContactInfo, UserBillingInfo: userBillingInfo };
				var callback = AccountSettingsPage.rebindInformation;
				var errorCallback = AccountSettingsPage.errorSavingInformation;
				DataAccess.saveSettingsData("AllUserInfo", allInformation, callback, errorCallback);
			}
			else {
				WaitPanel.Hide();
			}
		},
		saveContactInformation: function () {
			WaitPanel.Show();
			if (FormValidation.validateForm("#divCustomerInfo")) {
				var userContactInfo = getContactInformationObject();
				var callback = AccountSettingsPage.rebindInformation;
				var errorCallback = AccountSettingsPage.errorSavingInformation;
				DataAccess.saveSettingsData("UserContactInfo", userContactInfo, callback, errorCallback);
			}
			else {
				WaitPanel.Hide();
			}
			$(".page_wrapper").css("min-height", $("#contact_form").height());
		},
		saveBillingInformation: function () {
			WaitPanel.Show();
			if (FormValidation.validateForm("#divBillingInfo")) {
				var userBillingInfo = getBillingInformationObject();
				DataAccess.saveSettingsData("UserBillingInfo", userBillingInfo, AccountSettingsPage.rebindInformation, AccountSettingsPage.errorSavingInformation);
			}
			else {
				WaitPanel.Hide();
			}
			$(".page_wrapper").css("min-height", $("#billing_form").height());
		},
		submitPayment: function () {
			WaitPanel.Show();
			// check to see if they changes the payment info if not, just save the contact info
			var acctInfo = getOrigUserAccountInfo();
			// check to see if they have old acct info first
			var oldLastFour = "";
			if (acctInfo.BillingInformation !== null) {
				oldLastFour = acctInfo.BillingInformation.UserCreditCard.LastFourOfCreditCard;
			}
			var newCreditCardNumber = $("[id$=txtCreditCard]").val();
			var newlastFour = newCreditCardNumber.substr(newCreditCardNumber.length - 4);
			// if they are the same just save the contact info
			if (oldLastFour === newlastFour) {
				// so just charge them because we cant validate the whole form again since CVV and Credit Card # won't have info
				// set up the allinfo object to say used old account/billing info since the credit card didn't change
				var allInformation = { UserContactInfo: null, UserBillingInfo: null, UseSavedInfo: true };

				DataAccess.saveSettingsData("Payment", allInformation, AccountSettingsPage.rebindInformation, AccountSettingsPage.errorSavingInformation);
			}
			// they must have entered new billing info so revalidate everything and charge them
			else {
				if (FormValidation.validateForm("#divCustomerInfo") && FormValidation.validateForm("#divBillingInfo")) {
					var userContactInfo = getContactInformationObject();
					var userBillingInfo = getBillingInformationObject();
					var allInformation = { UserContactInfo: userContactInfo, UserBillingInfo: userBillingInfo, UseSavedInfo: false };
					var callback = AccountSettingsPage.rebindInformation;
					var errorCallback = AccountSettingsPage.errorSavingInformation;

					DataAccess.saveSettingsData("Payment", allInformation, AccountSettingsPage.rebindInformation, AccountSettingsPage.errorSavingInformation);
				}
			}
		},
		verifyUserByEmail: function () {
			WaitPanel.Show();
			var email = $("[id$=txtInviteEmail]").val();
			DataAccess.verifyUserByEmail(email, AccountSettingsPage.verifiedEmail, AccountSettingsPage.verifiedEmail)
		},
		verifiedEmail: function (verified) {
			$("[id$=divVerficationMessage]").removeClass("notificationAreaFail").removeClass("notificationAreaSuccess");
			if (verified) {
				var notification = "The email has been verified. Click 'Subscribe' to complete your gift purchase.";
				$("[id$=divVerficationMessage]").addClass("notificationAreaSuccess");
				$("[id$=divCheckBtn]").toggle();
				$("[id$=divPayBtn]").toggle();
			}
			else {
				var notification = "An account tied to this email does not exist.";
				$("[id$=divVerficationMessage]").addClass("notificationAreaFail");
			}
			$("[id$=pMessage]").html(notification);
			$("[id$=divVerficationMessage]").toggle();
			WaitPanel.Hide();
		},
		savePassword: function () {
			WaitPanel.Show();
			if (FormValidation.validateForm("#password_form")) {
				var oldPassword = $("[id$=txtOPassword]").val();
				var password = $("[id$=txtNPassword]").val();
				var passArray = new Array();
				passArray[0] = oldPassword;
				passArray[1] = password;
				DataAccess.saveSettingsData("Password", passArray, AccountSettingsPage.rebindInformation, AccountSettingsPage.errorSavingInformation);
			}
			else {
				WaitPanel.Hide();
			}
			$(".page_wrapper").css("min-height", $("#password_form").height());
		},
		rebindInformation: function (dataToRebind, complexType) {
			var type;
			if (dataToRebind[0]) {
				type = typeof (dataToRebind[0]);
			}

			if (type !== "string") {
				switch (complexType) {
					case "AllUserInfo":
						bindAllInformation(dataToRebind);
						var notification = getNotification("SavedData");
						showNotification(notification);
						WaitPanel.Hide();
						checkForDoAction();
						break;
					case "UserContactInfo":
						bindContactInformation(dataToRebind);
						var notification = getNotification("SavedData");
						showNotification(notification);
						WaitPanel.Hide();
						break;
					case "Payment":
						bindAccountBalance(dataToRebind);
						var notification = getNotification("Payment");
						showNotification(notification);
						WaitPanel.Hide();
						checkForDoAction();
						break;
					case "Password":
						clearPasswordFields();
						var notification = getNotification("Password");
						showNotification(notification);
						WaitPanel.Hide();
						break;
					case "Subscription":
						isPendingSubscriptionAction = false;
						redirectToSubModifyOnComplete = false;
						bindSubscription(dataToRebind);
						var notification = getNotification("SavedData");
						showNotification(notification);
						WaitPanel.Hide();
						break;
					case "Refresh":
						setOrigUserAccountInfo(dataToRebind);
						AccountSettingsPage.resetForm();
						WaitPanel.Hide();
						break;
				}
			}
			else {
				showServerSideValError(complexType, dataToRebind);
				WaitPanel.Hide();
			}
		},
		errorSavingInformation: function (xhr, complexType) {
			var notification = getNotification(xhr.status.toString(), complexType);
			if (notification) {
				showNotification(notification, window.location.hash);
			}
			WaitPanel.Hide();
		},
		resetForm: function () {
			var accountInfo = getOrigUserAccountInfo();
			isPendingSubscriptionAction = false;
			redirectToSubModifyOnComplete = false;
			if (accountInfo !== null) {
				bindContactInformation(accountInfo.ContactInformation);
				bindAccountBalance(accountInfo.AccountBalance);
				//bindBillingInformation(accountInfo.BillingInformation);
				$("label.error").remove();
				$("div.error").remove();
				$("input.error").removeClass("error");
				AccountSettingsPage.checkForPageConditions();
			}
		},
		buildSubsManageArea: function () {
			var accountInfo = getOrigUserAccountInfo();
			if (accountInfo !== null) {
				var mySubsHtml = buildMySubsArea(accountInfo.Subscriptions, accountInfo.AccountId);
				var availSubsHtml = buildAvailSubsArea(accountInfo.AvailableSubscriptions);

				$("#account_form .left_column").html(mySubsHtml);
				$("#account_form .right_column").html(availSubsHtml);
			}
		},
		modifySubscription: function (subId, pAcctId, uAcctId, uEmail, sku, appName, appId, sTypeId, isNew, startDate, trialPeriod) {
			WaitPanel.Show();
			if (isNew) startDate = new Date();
			var subToModify = new AppSubscription(subId, pAcctId, uAcctId, uEmail, sku, appId, appName, null, sTypeId, startDate, trialPeriod);
			$("#submodify_form").data("sub", subToModify);
			$("#submodify_form").data("isNew", isNew);
			DataAccess.getSubscriptionTypes(appId, AccountSettingsPage.bindSubModifyForm, AccountSettingsPage.errorSavingInformation);
		},
		deleteSubscription: function (subId) {
			WaitPanel.Show();
			DataAccess.deleteSubscription("Subscription", subId, AccountSettingsPage.rebindInformation, AccountSettingsPage.errorSavingInformation);
		},
		refreshCachedValues: function () {
			WaitPanel.Show();
			DataAccess.refreshCache("Refresh", AccountSettingsPage.rebindInformation, AccountSettingsPage.errorSavingInformation);
		},
		bindSubModifyForm: function (sTypes) {
			var subToModify = $("#submodify_form").data("sub");
			var isForSelf = subToModify.PayingAccountId === subToModify.UsingAccountId;
			var isNew = $("#submodify_form").data("isNew");
			var headerText = isNew ? "Subscribe To " : "Manage ";
			var ddlSubscriptionType = $("#subscription_type");

			if (sTypes) {
				$("#submodify_form").data("subTypes", sTypes);
				populateSubTypes(sTypes);
			}
			$(".subscription_message").html("");
			ddlSubscriptionType.val(subToModify.SubscriptionType.SubscriptionTypeId);
			if (sTypes.length === 1) {
				//If there is only subscription type set the drop down to that subscription type id and hide it
				ddlSubscriptionType.val(sTypes[0].SubscriptionTypeId);
				ddlSubscriptionType.closest(".row").hide();

				if (sTypes[0].SubscriptionTypeId.toString() !== subToModify.SubscriptionType.SubscriptionTypeId) {
					var trialPeriod = subToModify.TrialPeriod === null ? 0 : subToModify.TrialPeriod;
					var billingStartDate = new Date();
					if (Object.prototype.toString.call(subToModify.StartDate) === "[object Date]" && !isNaN(subToModify.StartDate.getTime()) && !isNew) {
						var newDateTicks = subToModify.StartDate.getTime() + (trialPeriod * 24 * 60 * 60 * 1000);
						billingStartDate = new Date(newDateTicks);
					}
					//Display message describing that if they save they are activating a paid subscription.
					var subMessage = new Array();
					subMessage.push("Click save to subscribe to the paid ",
									 subToModify.ApplicationName,
									 " application.  Your credit card will be billed $",
									 sTypes[0].Price,
									 " per month starting on ",
									 billingStartDate.getMonth() + 1,
									 "/",
									 billingStartDate.getDate(),
									 "/",
									 billingStartDate.getFullYear(), ".");
					$(".subscription_message").html(subMessage.join(""));
				}
			}

			$("#submodify_form h2 span").html(headerText + subToModify.ApplicationName);
			$("#txtUsingAcctEmail").removeClass("email").removeClass("required");

			if (isForSelf) {
				$("#radAssignment_1").attr("checked", "checked");
				$("#txtUsingAcctEmail").val("");
				$(".altUserEmail").hide();
			}
			else {
				$("#radAssignment_2").attr("checked", "checked");
				$("#txtUsingAcctEmail").val(subToModify.UsingAccountEmail);
				$("#txtUsingAcctEmail").addClass("email").addClass("required");
				$(".altUserEmail").show();
			}

			var btnUnsubscribe = $("#submodify_form h2 a");
			btnUnsubscribe.unbind("click");
			if (isNew) {
				btnUnsubscribe.hide();
			}
			else {
				btnUnsubscribe.click(function () {
					AccountSettingsPage.deleteSubscription(subToModify.SubscriptionId);
					return false;
				});
				btnUnsubscribe.show();
			}
			var canContinue = true;
			if (isNew && doAllSubTypesRequireBillInfo(sTypes)) {
				canContinue = doesUserHaveBillingInfo();
			}

			if (canContinue) {
				WaitPanel.Hide();
				setBrowserHash("submodify", 0);
			}
			else {
				handleBillingInfoRequired(false);
			}
		}
	};
} ();
///////////////////////////////////////////////////////////////////////////////////////////
// END: ACCOUNT SETTINGS page
///////////////////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////////////////
// START: DATA ACCESS 
///////////////////////////////////////////////////////////////////////////////////////////
var DataAccess = function () {
	function getUrlForSaveData(complexType) {
		switch (complexType) {
			case "AllUserInfo":
				return "/Member/MobileAppMember/AccountSettings.aspx/SaveAllInfo";
			case "UserContactInfo":
				return "/Member/MobileAppMember/AccountSettings.aspx/SaveContactInfo";
			case "UserBillingInfo":
				return "/Member/MobileAppMember/AccountSettings.aspx/SaveBillingInfo";
			case "Payment":
				return "/Member/MobileAppMember/AccountSettings.aspx/SubmitPayment";
			case "Password":
				return "/Member/MobileAppHome.aspx/ChangePassword";
			case "Subscription":
				return "/Member/AppAccountSettings.aspx/SaveSubscription";
			case "Refresh":
				return "/Member/MobileAppHome.aspx/RefreshCachedValues";
		}
	}
	var currentSuccessCallback;
	var currentErrorCallback;
	return {
		saveSettingsData: function (complexType, dataToSave, onSuccess, onError) {
			var url = getUrlForSaveData(complexType);
			var DTO = JSON.stringify({ dataToSave: dataToSave });
			currentSuccessCallback = onSuccess;
			currentErrorCallback = onError;
			DataAccess.genericDataCall(url, DTO, complexType);
		},
		deleteSubscription: function (complexType, subId, onSuccess, onError) {
			var url = "/Member/AppAccountSettings.aspx/DeleteSubscription";
			var DTO = JSON.stringify({ subId: subId });
			currentSuccessCallback = onSuccess;
			currentErrorCallback = onError;
			DataAccess.genericDataCall(url, DTO, complexType);
		},
		getSubscriptionTypes: function (appId, onSuccess, onError) {
			var url = "/Member/AppAccountSettings.aspx/GetSubscriptionTypes";
			var DTO = JSON.stringify({ applicationId: appId });
			currentSuccessCallback = onSuccess;
			currentErrorCallback = onError;
			DataAccess.genericDataCall(url, DTO);
		},
		changeSubscription: function (complexType, appSubscription, onSuccess, onError) {
			var url = getUrlForSaveData(complexType);
			var DTO = JSON.stringify({ subscription: appSubscription });
			currentSuccessCallback = onSuccess;
			currentErrorCallback = onError;
			DataAccess.genericDataCall(url, DTO, complexType);
		},
		refreshCache: function (complexType, onSuccess, onError) {
			var url = "/Member/AppAccountSettings.aspx/RefreshCachedValues";
			var DTO = "{}";
			currentSuccessCallback = onSuccess;
			currentErrorCallback = onError;
			DataAccess.genericDataCall(url, DTO, complexType);
		},
		verifyUserByEmail: function (email, onSuccess, onError) {
			var url = "/Member/MobileAppMember/SubscriptionGift.aspx/VerifyAccountByEmail"
			var DTO = JSON.stringify({ email: email });
			currentSuccessCallback = onSuccess;
			currentErrorCallback = onError;
			DataAccess.genericDataCall(url, DTO);
		},
		genericDataCall: function (url, DTO, complexType) {
			$.ajax({
				type: "POST",
				data: DTO,
				dataType: "JSON",
				contentType: "application/json",
				cache: false,
				timeout: 120000,
				url: url,
				success: function (result, status) {
					//                    result = JSON.parse(result);
					if (result.d) {
						result = JSON.parse(result.d, MicrosoftJSONSerializationFix);
					}
					currentSuccessCallback(result, complexType);
				},
				error: function (xhr, status, error) {
					currentErrorCallback(xhr, complexType);
				}
			});
		}
	};
} ();
///////////////////////////////////////////////////////////////////////////////////////////
// END: DATA ACCESS 
///////////////////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////////////////
// START: FORM VALIDATION 
///////////////////////////////////////////////////////////////////////////////////////////
var FormValidation = function () {
	return {
		wireUpValidationRules: function () {
			//Adding validation methods+
			$.validator.addMethod("phonenum_us", function (phone_number, element) {
				phone_number = phone_number.replace(/\s+/g, "");
				return this.optional(element) || phone_number.length > 9 &&
					phone_number.match(/^(1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/);
			}, "Please specify a valid phone number");
			$.validator.addMethod("zipcode", function (postalcode, element) {
				postalcode = postalcode.split("_").join("");
				if (postalcode.length === 6) {
					postalcode = postalcode.replace("-", "");
				}
				return this.optional(element) || postalcode.match(/^\d{5}$|^\d{5}\-\d{4}$/);
			}, "Please specify a valid zip code");
			$.validator.addMethod("creditCardExp", function (expDate, element) {
				if (expDate) {
					var dateArr = expDate.split("/");
					var dLength = dateArr.length;
					if (dLength === 2) {
						dateArr[0] = dateArr[0].replace(/[^0-9]/g, "");
						dateArr[1] = dateArr[1].replace(/[^0-9]/g, "");
						return dateArr[0].length === 2 && dateArr[1].length === 4;
					}
					else return false;
				}
				else return false;
			}, "Please specify a valid expiration date. (MM/YYYY)");
			$.validator.addMethod("confirm_password", function (password, element) {
				return $(".password").val() === $(".confirm_password").val();
			}, "The passwords you entered do not match.");
			$.validator.addMethod("confirm_email", function (email, element) {
				return $(".email").val() === $(".confirm_email").val();
			}, "The email addresses you entered do not match.");
			$.validator.addMethod("valCc3", function (creditCard, element) {
				if (creditCard.length > 0) {
					return creditCard.charAt(0) === "3";
				}
			}, "This credit card number is not a valid American Express number.");
			$.validator.addMethod("valCc4", function (creditCard, element) {
				if (creditCard.length > 0) {
					return creditCard.charAt(0) === "4";
				}
			}, "This credit card number not a valid Visa card number.");
			$.validator.addMethod("valCc5", function (creditCard, element) {
				if (creditCard.length > 0) {
					return creditCard.charAt(0) === "5";
				}
			}, "This credit card number is not a valid Master Card card number.");
			$.validator.addMethod("valCc6", function (creditCard, element) {
				if (creditCard.length > 0) {
					return creditCard.charAt(0) === "6";
				}
			}, "This credit card number is not a valid Dicover card number.");

			// don't need to test email since they can't change it
			//			$.validator.addMethod("email", function (email, element) {
			//				var emailReg = "^[-\w'+*$^&%=~!?{}#|/`]{1}([-\w'+*$^&%=~!?{}#|`.]?[-\w'+*$^&%=~!?{}#|`]{1}){0,31}[-\w'+*$^&%=~!?{}#|`]?@(([a-zA-Z0-9]{1}([-a-zA-Z0-9]?[a-zA-Z0-9]{1}){0,31})\.{1})+([a-zA-Z]{2}|[a-zA-Z]{3}|[a-zA-Z]{4}|[a-zA-Z]{6}){1}$";
			//				var emailaddressVal = $("input.email").val();

			//				if (!emailReg.test(emailaddressVal)) {
			//					return false;
			//				}
			//				else {
			//					return true;
			//				}
			//			}, "Please specify a valid email address");

			$.validator.classRuleSettings.confirm_password = { confirm_password: true, minlength: 6 };
			$.validator.classRuleSettings.phonenum_us = { phonenum_us: true };
			$.validator.classRuleSettings.zipcode = { zipcode: true };
			$.validator.classRuleSettings.creditCardExp = { creditCardExp: true };
			$.validator.classRuleSettings.confirm_email = { confirm_email: true };
			$.validator.classRuleSettings.valCc3 = { valCc3: true };
			$.validator.classRuleSettings.valCc4 = { valCc4: true };
			$.validator.classRuleSettings.valCc5 = { valCc5: true };
			$.validator.classRuleSettings.valCc6 = { valCc6: true };
			$.validator.classRuleSettings.email = { email: true };

			//TODO: Remove this after full validation has been implemented(patch for registration page)
			if ($(".reqfield-text").length > 0) {
				$("form").validate({
					errorElement: "span",
					errorPlacement: function (error, element) {
						$(".reqfield-text", element.parent().parent()).append(error.attr("style", "color:Red;"));
					}
				});
			}
			else {
				$("form").validate();
			}
		},
		validateForm: function (formSelector) {
			var elementsToValidate = $(formSelector).find(".required, .email, .phonenum_us, .zipcode, .creditcard, .creditCardExp, .password, .confirm_password, .confirm_email, .valCc3, .valCc4, .valCc5, .valCc6");
			var errorCount = 0;
			elementsToValidate.each(function () {
				var elementToValidate = $(this);
				if (!elementsToValidate.valid()) {
					elementToValidate.validate();
					errorCount += 1;
				}
			});
			return errorCount == 0;
		}
	};
} ();
///////////////////////////////////////////////////////////////////////////////////////////
// END: FORM VALIDATION 
///////////////////////////////////////////////////////////////////////////////////////////


function UserContactInfo(firstName, lastName, middleName, email, phoneNumber, contactAddress) {
	this.FirstName = firstName;
	this.LastName = lastName;
	this.MiddleName = middleName;
	this.Email = email;
	this.PhoneNumber = phoneNumber.replace(/[^0-9]/g, "");
	this.ContactAddress = contactAddress;
}
function Address(street1, city, state, zip) {
	this.StreetAddress1 = street1;
	this.City = city;
	this.State = state;
	this.Zipcode = zip.replace(/[^0-9]/g, "");
}

function CreditCard(firstName, lastName, creditCardNumber, cvv, lastFourOfCreditCard, cardExpirationDate, cardType) {
	this.FirstName = firstName;
	this.LastName = lastName;
	this.CreditCardNumber = creditCardNumber;
	this.Cvv = cvv;
	this.LastFourOfCreditCard = lastFourOfCreditCard;
	this.CardExpirationDate = cardExpirationDate;
	this.CardType = cardType;
}
function UserBillingInfo(creditCard, address) {
	this.UserCreditCard = creditCard;
	this.BillingAddress = address;
}
function Notification(message, title, classToAssign) {
	this.Message = message;
	this.Title = title;
	this.CssClass = classToAssign;
}
function AppSubscription(subId, pAcctId, uAcctId, uEmail, sku, appId, appName, appPrice, sTypeId, startDate, trialPeriod) {
	this.SubscriptionId = subId;
	this.PayingAccountId = pAcctId;
	this.UsingAccountId = uAcctId;
	this.UsingAccountEmail = uEmail;
	this.ApplicationId = appId;
	this.ApplicationName = appName;
	this.StartDate = new Date(startDate);
	this.TrialPeriod = trialPeriod;
	this.SubscriptionType = new SubscriptionType(sTypeId, '', appPrice, sku, true);
}
function SubscriptionType(sTypeId, sTypeName, price, sku, reqBillInfo) {
	this.SubscriptionTypeId = sTypeId;
	this.SubscriptionTypeName = sTypeName;
	this.Price = price;
	this.Sku = sku;
	this.RequiresBillingInfo = reqBillInfo;
}


/**  * this below is the function you need from: * http://stackoverflow.com/questions/1865563/ * set-cursor-at-a-length-of-14-onfocus-of-a-textbox */
function setCursor(node, pos) {
	var node = (typeof node == "string" || node instanceof String) ? document.getElementById(node) : node;
	if (!node) { return false; }
	else if (node.createTextRange) {
		var textRange = node.createTextRange();
		textRange.collapse(true);
		textRange.moveEnd(pos);
		textRange.moveStart(pos);
		textRange.select();
		return true;
	}
	else if (node.setSelectionRange) {
		node.setSelectionRange(pos, pos);
		return true;
	}
	return false;
}

function checkRegErrors() {
	if ( $('.error').is(":visible") === true || $('.error').css('display') === 'block' ) {
		return false;
	}
	else {
		return true; 
	}
}
