var divRecsContainer;
var divRecResultsContainer;
var redir = "";
var classic_ass_id = "101225";
var main_test_id = "";
var module_health_id = "";
var module_feelings_id = "";
var module_diet_id = "";
var module_fitness_id = "";

var omni_pgid = "";
var omni_ass_id = readCookie("omni_ass_id");
var omni_ass_name = readCookie("omni_ass_name");
var omni_module_id = readCookie("omni_module_id");
var omni_module_name = readCookie("omni_module_name");
var omni_events = new Array();
var cookieDomain = ".realage.com"; // So far only used in appendEvent, but nice to have for any cookie-setting

if (window.location.href.indexOf("betapreview.")>=0 || window.location.href.indexOf("alphapreview.")>=0 || window.location.href.indexOf("stage.")>=0) {
	main_test_id = "24";
	module_health_id = "29";
	module_feelings_id = "31";
	module_diet_id = "33";
	module_fitness_id = "35";
} else {
	main_test_id = "108267";
	module_health_id = "108272";
	module_feelings_id = "108274";
	module_diet_id = "108276";
	module_fitness_id = "108278";
}

function setCookie(name, value, days){
	if (days) {
		var date = new Date();
		date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
		var expires = "; expires=" + date.toGMTString();
	}
	else var expires = "";
	document.cookie = name + "=" + value + expires + "; path=/; domain=realage.com";
}

function HideNavigationElements() {
	$("#logo").css("background","transparent");
	$("#header_bar").css("display","none");
	$("#header_bar_bot").css("display","none");
	$("#breadcrumb").css("display","none");
	$(document).ready(function() {
		$("#footer").css("display","none");
	});
}

// These functions don't need to exist distinctly, so they just call their replacement.
function setFirstTime(ass_id) { checkAssessmentCompletion(ass_id); }
function HideNavigation(ass_id) { checkAssessmentCompletion(ass_id); }
function HideResultsLink(ass_id) { checkAssessmentCompletion(ass_id); }

function checkAssessmentCompletion(ass_id,make_the_call) {
	var hideresults = readCookie("hideresults_" + ass_id);
	var hidenav = readCookie("first_time");
	var child_id = readCookie("raap_child_id");
	if (!child_id) {
		setChildId(mag_user.realage_member_id,"checkAssessmentCompletion",ass_id,make_the_call);
		return false;
	}
	// These might get reordered, if there's any reason to trust the omni one more than the cookie.
	if (!ass_id) { ass_id = readCookie("current_ass_id"); }
	if (!ass_id) { ass_id = omni_ass_id; }
	if (!ass_id) { return false; } // If there's still no assessment ID, give up.
	switch (hideresults) {
		case "0":
			$("#results_link").css("display","block");
			break;
		case "1":
			//Nothing special for now, as results start out hidden.
			break;
		default:
			//The cookie wasn't set, so I should check.
			make_the_call = true;
			break;
	}
	if (mainRaTest) {
		switch (hidenav) {
			case "1":
				HideNavigationElements();
				break;
			case "0":
				//Nothing special for now, as the nav starts out visible.
				break;
			default:
				//The cookie wasn't set, so I should check.
				make_the_call = true;
				break;
		}
	}
	var ass_loop = function(json){
		var results = json.result;
		var first_time = 1;
		for(looper=0; looper<results.length; looper++) {
			if ((!mainRaTest && (results[looper].assessment_id == ass_id)) || (mainRaTest && (results[looper].assessment_id == classic_ass_id))) {
				first_time = 0;
				break;
			}
		}
		if (mainRaTest && first_time == 1) {
			//raap_raws.call('{"jsonrpc": "2.0", "method": "getCompletedChildModules", "params": ["' + child_id + '"], "id": 1}',module_loop,errproc);
			raTest.setCompletionUX(ass_id);
		} else {
			if (mainRaTest) {
				setCookie("first_time",first_time);
				if (first_time == 1) { HideNavigationElements(); }
			}
			setCookie("hideresults_" + ass_id,first_time);
			if (first_time == 0) { $("#results_link").css("display","block"); }
		}
	}
	var errproc = function(json){
		console.error("checkAssessmentCompletion(" + ass_id + ") error (with child_id " + child_id + ") : " + json.error.valueOf());
	}
	if (make_the_call) {
		raap_raws.call('{"jsonrpc": "2.0", "method": "getCompletedAssessments", "params": ["' + child_id + '"], "id": 1}',ass_loop,errproc);
	}
}

function setChildId(member_id, next_function, next_function_arg, next_function_arg2) {
	var newproc = function(json) {
		var next_function_eval = "";
		if (json.result.child_id) {
			setCookie("raap_child_id", json.result.child_id);
			if (next_function) {
				if (next_function_arg2) { eval(next_function + '("' + next_function_arg + '","' + next_function_arg2 + '")'); }
				else { eval(next_function + '("' + next_function_arg + '")'); }
			}
		}
	}
	var errproc = function(json){
		console.error("setChildId(" + member_id + ") error : " + json.error.valueOf());
	}
	raap_raws.call('{"jsonrpc": "2.0", "method": "getSelf", "params": ["' + member_id + '","56"], "id": 1}',newproc,errproc);
}

function raap_trigger_event(eventArray) {
	// Obviously, we'll have better handling someday.
	var i;
	var pageArray;
	var arrUrl = document.location.href.split("/");
	omni_ass_name = arrUrl[arrUrl.length-1].split("?")[0];
	if (eventArray instanceof Array) {
		eventLoop:
		for (i=0; i<eventArray.length; i++) {
			debugEvent(eventArray[i]);
			eventSwitch:
			switch (eventArray[i][0].toLowerCase()) {
				case "log_event":
					logSwitch:
					switch (eventArray[i][1].toLowerCase().substring(0,5)) {
						case "page_":
							pageArray = eventArray[i][1].toLowerCase().split("_");
							ShowProgressBar(pageArray[1],pageArray[3]);
							omni_pgid = pageArray[1];
							continue eventLoop;
						case "opt_h":
							if (mag_user.email != "" && mag_user.general_optin != "Y" && readCookie("first_time") == "1" && readCookie("opt_in_health") != "1") { redir = "opt-in-health"; }
							continue eventLoop;
						case "opt_d":
							if (mag_user.email != "" && mag_user.general_optin != "Y" && readCookie("first_time") == "1" && readCookie("opt_in_diet") != "1") { redir = "opt-in-diet"; }
							continue eventLoop;
					}
					debugEvent(eventArray[i], "Unhandled log_event");
					continue eventLoop;
				case "assessment_complete":
				case "assessment_completed":
					omni_ass_id = eventArray[i][1].toLowerCase();
					if (mainRaTest) {
						omni_events.push("event48");
						console.debug("event48");
					}
					else {
						omni_events.push("event76");
						console.debug("event76");
					}
					setCookie("current_ass_id","",-1);
					setCookie("hideresults_" + omni_ass_id, "0");
					continue eventLoop;
				case "assessment_started":
					omni_ass_id = eventArray[i][1].toLowerCase();
					if (mainRaTest) {
						checkAssessmentCompletion(eventArray[i][1].toLowerCase(),true);
						omni_events.push("event47");
						console.debug("event47");
					}
					else {
						omni_events.push("event75");
						console.debug("event75");
					}
					setCookie("current_ass_id",eventArray[i][1].toLowerCase());
					continue eventLoop;
				case "module_started":
					omni_module_id = eventArray[i][1].toLowerCase();
					omni_events.push("event49");
					console.debug("event49");
					continue eventLoop;
				case "module_complete":
				case "module_completed":
					omni_module_id = eventArray[i][1].toLowerCase();
					omni_events.push("event74");
					console.debug("event74");
					// Create message for first time user per ticket 40692
					//if (readCookie("first_time") == "1" && !readCookie("yesmail_trans_id")) {
						//postal_article.updateMessage("unsent");
					//}
					continue eventLoop;
				case "module_not_completed":
					continue eventLoop;
				default:
					debugEvent(eventArray[i], "Unhandled raap_trigger_event");
					continue eventLoop;
			}
		}
	} else { debugEvent(eventArray); }
	switch (omni_module_id) {
		case "108272":
		case module_health_id:
			omni_module_name = "Health";
			break;
		case "108274":
		case module_feelings_id:
			omni_module_name = "Feelings";
			break;
		case "108276":
		case module_diet_id:
			omni_module_name = "Diet";
			break;
		case "108278":
		case module_fitness_id:
			omni_module_name = "Fitness";
			break;
		default:
			omni_module_name = omni_module_id + "";
			break;
	}
	if (omni_ass_name) { setCookie("omni_ass_name",omni_ass_name); }
	if (omni_ass_id) { setCookie("omni_ass_id",omni_ass_id); }
	if (omni_module_name) { setCookie("omni_module_name",omni_module_name); }
	if (omni_module_id) { setCookie("omni_module_id",omni_module_id); }
	console.debug("omni_ass_name: " + omni_ass_name + ", omni_ass_id: " + omni_ass_id + ", omni_module_name: " + omni_module_name + ", omni_module_id: " + omni_module_id + ", omni_pgid: " + omni_pgid + ", redir: " + redir);

}

function specTracking() {
	var i;
	var pageid;
	if (document.location.href.indexOf("/raap/") > 0 && document.location.href.indexOf("recs") < 1 && document.location.href.indexOf("login") < 1 && document.location.href.indexOf("overview") < 1) {
		pageid = getQueryValue("page_id");
		if (!pageid) { pageid = "index"; }
		s.pageName = "RealAge: RAAP: " + omni_ass_name + ": " + omni_module_name + ": " + pageid;
		s.channel = "RAAP: " + omni_ass_name;
		s.prop1 = "RAAP";
		s.prop2 = omni_ass_name;
		s.prop4 = "RealAge: RAAP: " + omni_ass_name;
		s.prop10 = omni_ass_name;
		s.prop12 = pageid;
		s.prop16 = omni_ass_id;
		s.prop20 = omni_ass_name;
		s.prop48 = "RAAP: " + omni_ass_name + ": " + omni_module_name + ": " + pageid;
		s.eVar2 = s.pageName;
		s.eVar4 = "RAAP: " + omni_ass_name;
		s.eVar11 = "RA";
		s.eVar13 = "realage";
		s.eVar24 = omni_module_name;
		for (i=0; i<omni_events.length; i++) {
			s.events=s.apl(s.events,omni_events[i],',',1);
		}
	}
}

function debugEvent(eventArgs, lead) {
	var i;
	var eventList = "";
	if (!lead) { lead = "RAAP event"; }
	if (eventArgs instanceof Array) {
		for (i=0; i<eventArgs.length; i++) {
			if (i>0) { eventList = eventList + ", "; }
			eventList = eventList + eventArgs[i]
		}
	} else {
		eventList = eventArgs + " (non-array)";
	}
	console.debug(lead + ": " + eventList);
	document.write("<div style='display:none'>" + lead + ": " + eventList + "</div>");
	return true;
}

function InjectJavaScript()
{
	var toggles = '<div class="plan-main-container plan-selector-container"><div class="plan-selector-title-container">What\'s making your RealAge:</div><div id="plan-selector-younger-main-container"><div class="plan-selector-younger-image-container" onclick="javascript:ShowRecommendations(true,false); return false;"><span class="plan-selector-image"><img src="/cm/realage/site_images/raap/check-icon.jpg" /></span></div><div class="plan-selector-younger-text-container" onclick="javascript:ShowRecommendations(true,false); return false;"><div class="plan-selector-younger-text">YOUNGER</div><div class="plan-selector-younger-link" id="showMeYounger">See All&nbsp;<img src="/cm/realage/site_images/raap/arrow_right-small.gif"/></div></div></div><div id="plan-selector-older-main-container"><div class="plan-selector-older-image-container" onclick="javascript:ShowRecommendations(false,true); return false;"><span class="plan-selector-image"><img src="/cm/realage/site_images/raap/X-icon.jpg" /></span></div><div class="plan-selector-older-text-container" onclick="javascript:ShowRecommendations(false,true); return false;"><div class="plan-selector-older-text">OLDER</div><div class="plan-selector-older-link" id="showMeOlder">See All&nbsp;<img src="/cm/realage/site_images/raap/arrow_right-small.gif" /></div></div></div><div class="plan-selector-combined-container" id="combinedList"><span class="plan-selector-combined-link" onclick="javascript:ShowRecommendations(true,true); return false;">Combined List&nbsp;</span><img alt="Combined List" src="/cm/realage/site_images/raap/arrow_right-small.gif" /></div></div><div class="rec-results-container">';
	divRecsContainer = $(".recs-container")[0];
	divRecResultsContainer = $(".rec-results-container")[0];
	var recReplace = new RegExp('<(div|DIV) class=\"?rec-results-container\"?>');
	if (divRecsContainer) {divRecsContainer.innerHTML = divRecsContainer.innerHTML.replace(recReplace,toggles);}
	var divParent;
	var recId;

	var divs = $(".rec-results-body");
	for (var i=0;i<divs.length;i++)
	{
		divParent = divs[i].parentNode;
		recId = divParent.className.match(/\d+/);
		setBegEndDivTags(divs[i], recId);
		divParent.id = "recAccordionContainer_" + recId;
	}

	var pageListHtml = $(".rec-page-list").html();
	pageListHtml = '<li class="rec-page-list-item overview"><a class="rec-page-link" href="realage-overview?recs">Overview</a></li>' + pageListHtml;
	$(".rec-page-list").html(pageListHtml);
	$(".next-recpage-link").text(nextPageButtonWords).addClass("ra_largebutton");

	var nextPageHtml = $(".next-recpage-container").html();
	nextPageHtml = nextPageHtml + "<a href='" + $(".next-recpage-link").attr("href") + "' class='link_arrow'>" + nextPageLinkWords + "</a>";
	$(".next-recpage-container").html(nextPageHtml);
}

function ShowProgressBar(pageNumber, pageTotal) {
	pageNumber = pageNumber - 1;
	if ((pageTotal-0) < 1) { pageTotal = 16; }
	var percentComplete = Math.floor((pageNumber/pageTotal)*100);
	var middleWidth = ((300/pageTotal) * pageNumber) - 12;

	var process = '<div id="process_bar">';
	if (pageNumber > 0) { process = process + '<img src="/cm/realage/site_images/raap/process-bar-left.gif" width="6" height="25" /><img src="/cm/realage/site_images/raap/process-bar-middle.gif" height="25" width="' + middleWidth + '" /><img src="/cm/realage/site_images/raap/process-bar-right.gif" width="6" height="25" />'; }
	else { process = process + '<img src="/cm/realage/site_images/spacer.gif" width="6" height="25" />'; }
	process = process + '</div>You are ' + percentComplete + '% complete!';
	$(document).ready(function() { $("#process_box").html(process).css('display','block'); });
}

function more_info(infoId) {
	var show = ($("#more-html-" + infoId).css("display") == "none");
	$(".more-html").hide("fast");
	if (show) {	$("#more-html-" + infoId).show("fast"); }
}

function registerCustomQuestionValidationByFactId(factid, f, error_msg) {
	try {
		var qnum = $("[name $= '" + factid + "']").parent().attr("id").replace("q","");
		registerCustomQuestionValidation(qnum, f, error_msg);
	}
	catch (err) { console.debug("Failed to find parent for " + factid + ". Error: " + err); }
}

// Share invites for Nexus page: FB v2, new Twitter platforn
function shareIntroPage() {
	if ((typeof(twitter) != 'undefined') || (typeof(facebook) != 'undefined')) {
		document.write('<div id="scl_med_links">');
		if (typeof(facebook) != 'undefined') { if (facebook) { document.write('<a class="ra_scl_fb" target="_blank" href="http://www.facebook.com/sharer.php?u=' + escape(facebook) + '&t=RealAge">Share this with my friends on Facebook</a>'); } }
		if (typeof(twitter) != 'undefined') { if (twitter) { document.write('<a class="ra_scl_tw" target="_blank" href="http://twitter.com/intent/tweet?text=' + escape(twitter) + '">Share this with my friends on Twitter</a>'); } }
		document.write('</div>');
	}
}

// Validation email for Nexus page
function isValidEmail(str) {
	var r1 = new RegExp("(@.*@)|(\\.\\.)|(@\\.)|(^\\.)");
	var r2 = new RegExp("^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$");
	return (!r1.test(str) && r2.test(str));
}

function getErrorHtmlContent(messageList) {
	var errDiv = "<div id='err_content' class='msg_err'><ul><span>Errors:</span>";
	$.each(messageList, function(index, value) {
		if (value && value != "") {
			errDiv += value;
		}
	});
	errDiv += "</ul></div>";
	return errDiv;
}

function clearErrControlClass(controlList, className) {
	$.each(controlList, function() {
		if ($(this).hasClass(className)) {
			$(this).removeClass(className);
		}
	});
}

function setErrControlClass(controlList, className) {
	$.each(controlList, function(index, control) {
		if (control) {
			control.addClass(className);
			control.change(function() {
				if ($.trim($(this).val()) != "") {
					$(this).removeClass(className);
				}
			});
			if (index == 0) {
				control.focus();
			}
		}
	});
}

// Get invitee address list - return a string contains addresses that separate by comma
function getInviteeAddresses(addrControlList) {
	var inviteeAddrs = "";
	$.each(addrControlList, function() {
		if ($(this).val() && $.trim($(this).val()) != "") {
			inviteeAddrs += $(this).val() + ",";
		}
	});
	return inviteeAddrs.substring(0, inviteeAddrs.length - 1);
}

// Limit text's length of control
function limitLength(taCtrl, maxLength) {
	var textValue = taCtrl.val();
	if (textValue && textValue.length > maxLength) {
		taCtrl.val(textValue.substring(0, maxLength));
		alert("The message has a limit of " + maxLength + " characters.");
		return false;
	}
	return true;
}

// Validation for Nexus page
function validateInviteesForm() {
	var hasErrors = false;
	var errContentList = new Array();
	var errControlList = new Array();
	var errIndex = 0;
	var errCtrlClsName = "err_ctrl";
	// Sender name
	if (!$("#sender_name").val() || $.trim($("#sender_name").val()) == "") {
		hasErrors = true;
		errContentList[errIndex] = "<li>Sender name should not be empty</li>";
		errControlList[errIndex++] = $("#sender_name");
	}
	// Sender email
	if (!$("#sender_email").val() || $.trim($("#sender_email").val()) == "") {
		hasErrors = true;
		errContentList[errIndex] = "<li>Sender email should not be empty</li>";
		errControlList[errIndex++] = $("#sender_email");
	} else if (!isValidEmail($("#sender_email").val())) {
		hasErrors = true;
		errContentList[errIndex] = "<li>Sender email is not a valid email format</li>";
		errControlList[errIndex++] = $("#sender_email");
	}
	// Invitee email addresses
	var emptyAddrNum = 0;
	var inviteeAddrErr = false;
	var inviteeNameErr = false;
	var indexFound;
	var errInviteeCtrl;
	var cont = true;
	// Loop on all input addresses
	$(".invite_list input").each(function(index) {
		if (!$(this).val() || $.trim($(this).val()) == "") {
			// Increase count number of empty input address
			emptyAddrNum++;
		} else {
			// Valid email address
			if (isValidEmail($(this).val())) {
				// Not select invitee name
				if ($(".invite_list select:eq(" + index + ")").val() == "") {
					indexFound = index;
					errInviteeCtrl = $(".invite_list select:eq(" + index + ")");
					inviteeNameErr = true;
					cont = false;
				}
			// Invalid email address
			} else {
				indexFound = index;
				errInviteeCtrl = $(this);
				inviteeAddrErr = true;
				cont = false;
			}
		}
		if (!cont) {
			return false;
		}
	});
	// Not input at least one email address
	if (emptyAddrNum == $(".invite_list input").size()) {
		hasErrors = true;
		errContentList[errIndex] = "<li>There should be at least one invitee email address</li>";
		errControlList[errIndex++] = $(".invite_list input:first");
	// Invalid one email address
	} else if (inviteeAddrErr) {
		hasErrors = true;
		errContentList[errIndex] = "<li>Invitee email address " + (indexFound + 1) + " is not a valid email format</li>";
		errControlList[errIndex++] = errInviteeCtrl;
	// Not select invitee name for valid email address
	} else if (inviteeNameErr) {
		hasErrors = true;
		errContentList[errIndex] = "<li>Please make a selection</li>";
		errControlList[errIndex++] = errInviteeCtrl;
	}
	if (hasErrors) {
		// Add new error content to before of the form
		$("#email_friend").before(getErrorHtmlContent(errContentList));
		// Slide down new error content for parent DIV of the form
		$("#email_friend_main").slideDown("slow");
		// Set error class for all error input controls
		setErrControlClass(errControlList, errCtrlClsName);
		return false;
	}
	return true;
}

// Is from RA Test
function isFromRATest() {
	var path = getQueryValue("path");
	return (path.indexOf("realage-test") >= 0 || path.indexOf("realage-recs") >= 0);
}

// Is logged in
function isLoggedIn() {
	return (!!RA.utils.getCookie('raap_child_id'));
}

// Go to next page in the flow of Nexus page
function goToNextOfNexus(fromRATest) {
	if (fromRATest) {
		var referrer = "" + readCookie("original_referrer");
		console.debug('referrer: ' + referrer);
		//if (readCookie("first_time")=="1") { redir = "/raap/postal-email-reentry"; }
		//else {
			if ((referrer.indexOf("kevtest") > 0) || (referrer.indexOf("doctoroz") > 0)) {
				console.debug('referred by kevtest or doctoroz');
				redir = "/oz-inter";
			} else {
				redir = "/raap/realage-overview";
			}
			setCookie("first_time","0");
		//}
	} else {
		redir = getQueryValue("path");
		if (redir.length > 0) {
			if (redir.indexOf("-recs") > 0) { redir = redir + "?recs"; }
		} else { redir = "/"; } // They don't have a path set, so we don't know where to send them. -- KL 2010-10-07
	}

	window.location.href = redir;
}

var nexus_article = {
	"errCtrlClsName" : "err_ctrl",
	"isfromRAtest" : false,
	"isLoggedIn" : false,
	"emailthis_object" : {},
	/*"restart" : function() {
		document.forms["email_friend"].reset();
		$("#email_success_msg").fadeOut("fast", function() {$("#email_friend").fadeIn("fast")});
		nexus_article.init();
	},*/
	"init" : function() {
		// Limit text's length for Nexus message
		$("#send_message").keyup(function() {
			return limitLength($(this), 750);
		});
		$("#send_message").change(function() {
			return limitLength($(this), 750);
		});
		// Process submit for Nexus form page
		$("#email_friend").submit(function() {
			nexus_article.email_post();
			return false;
		});
		this.isfromRAtest = isFromRATest();
		// Logged in users don't get the captcha
		if (isLoggedIn()) {
			this.isLoggedIn = true;
			$("#email_friend_main .captcha,#email_friend_main .captcha_te,#email_friend_main .captcha_be").remove();
			if (mag_user.email) { $("#sender_email").val(mag_user.email); }
		} else {
			$("#email_friend_main .captcha,#email_friend_main .captcha_te,#email_friend_main .captcha_be").show();
		}
		$.ajaxSetup({ cache: false });
		// Static url, need update once it changed
		var emailthis_addy = "/email-this/" + $("#intro_article_url").val();
		$.get(emailthis_addy, function(data){
			nexus_article.process_emailthis(data);
		});
	},
	"process_emailthis" : function(data) {
		var emailThisObj = eval('(' + data + ')');
		nexus_article.emailthis_object = emailThisObj;
		// Load captchar math question and key
		$("#invite_email_cap_expr").html(nexus_article.emailthis_object.captcha_exp);
		$("#invite_email_cap_key").val(nexus_article.emailthis_object.captcha_key);
		var errCtrl;
		if (nexus_article.emailthis_object.errorstring == "There was a problem with the email address used.  Please enter a valid email address.\n") {
			nexus_article.emailthis_object.errorstring = "There is an error in one or more of the e-mail addresses you have provided";
			errCtrl = $(".invite_list input:eq(0)");
		}
		if (nexus_article.emailthis_object.errorstring == "Problem with CAPTCHA: Invalid answer for key") {
			nexus_article.emailthis_object.errorstring = "Please make sure your answer is entered correctly";
			errCtrl = $("#invite_email_cap_input");
		}
		if (nexus_article.emailthis_object.errorstring == "Problem with CAPTCHA: ") {
			nexus_article.emailthis_object.errorstring = "Please make sure your answer is entered correctly";
			errCtrl = $("#invite_email_cap_input");
		}
		if (nexus_article.emailthis_object.errorstring == "There was a problem with in sending your email.  Please try again.\n") {
			nexus_article.emailthis_object.errorstring = "There is something wrong with one or more of your friends' email addresses that you typed in.";
		}
		if (nexus_article.emailthis_object.errorstring != "") {
			// Add new error content to before of the form
			$("#email_friend").before(getErrorHtmlContent(["<li>" + nexus_article.emailthis_object.errorstring + "</li>"]));
			// Slide down new error content for parent DIV of the form
			$("#email_friend_main").slideDown("slow");
			// Set error class for all error input controls
			setErrControlClass([errCtrl], this.errCtrlClsName);
			$("#email_friend input, select, textarea").removeAttr("disabled");
		}
		if (nexus_article.emailthis_object.save_success == "1") {
			$("#email_friend_main").prepend("<div id='email_success_msg'><strong>Your message has been successfully sent!</strong></div>");//<a style='margin-left: 10px;' href='javascript:nexus_article.restart();'>Continue to invite</a>
			$("#email_friend").fadeOut("fast", function() {$("#email_success_msg").fadeIn("fast")});
			goToNextOfNexus(this.isfromRAtest);
		}
	},
	"email_post" : function() {
		// Remove old error content
		$("#err_content").remove();
		// Clear error class for all form's elements
		clearErrControlClass($("#email_friend input, select"), this.errCtrlClsName);
		// Go to parent DIV of the form
		window.location.href = "#email_friend_main";
		if (!validateInviteesForm()) {
			return false;
		}
		if ($("#emailthis_name").attr("disabled")) {
			$h.console.warn("EMAIL THIS: post execution disabled");
			return false;
		}
		$("#email_friend input, select, textarea").attr("disabled","disabled");
		nexus_article.emailthis_object.article_id = $("#intro_article_id").val();
		nexus_article.emailthis_object.name = $("#sender_name").val();
		nexus_article.emailthis_object.email = $("#sender_email").val();
		nexus_article.emailthis_object.friend_email = getInviteeAddresses($(".invite_list input"));
		nexus_article.emailthis_object.message = $("#nexus_message").text() + "<br /><br />" + $("#send_message").val();
		nexus_article.emailthis_object.captcha_answer = $("#invite_email_cap_input").val();
		nexus_article.emailthis_object.captcha_key = $("#invite_email_cap_key").val();
		nexus_article.emailthis_object.extra_url_params = $("#email_backlink_cbr").val();
		// Send email, call back to process_emailthis once error happen
		$.post("/email-this/email-this", { "article_id" : nexus_article.emailthis_object.article_id, "captcha_answer" : (this.isLoggedIn ? eval(nexus_article.emailthis_object.captcha_exp) : nexus_article.emailthis_object.captcha_answer), "captcha_key" : nexus_article.emailthis_object.captcha_key, "name" : nexus_article.emailthis_object.name, "email" : nexus_article.emailthis_object.email, "friend_email" : nexus_article.emailthis_object.friend_email, "friend_name" : nexus_article.emailthis_object.friend_name, "message" : nexus_article.emailthis_object.message, "extra_url_params" : nexus_article.emailthis_object.extra_url_params }, function(data) { nexus_article.process_emailthis(data); });
	}
};

// Add some hidden fields for Postal Re-entry form on Mag user
function addProfileHidFields() {
	var comb_profile_fld = "<input type='hidden' name='combined_profile' value='1'>";
	var ur_id_fld = "<input type='hidden' name='ur_id' value='" + mag_user.ur_id + "' />";
	var from_lite_fld = "<input type='hidden' value='y' id='from_lite' name='from_lite' />";
	var logged_in_fld = "<input type='hidden' value='1' name='logged_in' />";
	var ur_email_fld = "<input type='hidden' name='email' value='" + (mag_user.email ? mag_user.email : "") + "' />";
	var ur_name_fld = "<input type='hidden' name='user_name' value='" + (mag_user.user_name ? mag_user.user_name : "") + "' />";
	var contry_code_fld = "<input type='hidden' value='" + mag_user.country_code + "' name='country_code' />";
	$("#postal_email_reentry").prepend(comb_profile_fld + ur_id_fld + from_lite_fld + logged_in_fld + ur_email_fld + ur_name_fld + contry_code_fld);
}

// Clear Postal field values held in cookie
function clearPostalCookies() {
	setCookie("postal_profile_error_string","",-1);
	setCookie("postal_profile_email","",-1);
	setCookie("postal_profile_lastname","",-1);
	setCookie("postal_profile_address","",-1);
	setCookie("postal_profile_address2","",-1);
	setCookie("postal_profile_city","",-1);
	setCookie("postal_profile_state","",-1);
	setCookie("postal_profile_postalcode","",-1);
}

// Load user's properties to Postal form
function loadUserProperties() {
	var postal_error_string = readCookie("postal_profile_error_string");
	if (postal_error_string) {
		$("#first_name").val(readCookie("postal_profile_firstname"));
		$("#last_name").val(readCookie("postal_profile_lastname"));
		$("#address_1").val(readCookie("postal_profile_address"));
		$("#address_2").val(readCookie("postal_profile_address2"));
		$("#city").val(readCookie("postal_profile_city"));
		// Select State
		$("#state option[value='" + readCookie("postal_profile_state") + "']").attr("selected", "selected");
		$("#zip_code").val(readCookie("postal_profile_postalcode"));
		// Add new error content to before of the form
		if (postal_error_string.indexOf("Your email is already in the system.") >= 0) {
			postal_error_string = "Your e-mail is already registered with another site on the Hearst Digital Media Network. RealAge is a part of this network. Please enter the same password as you use on any of the Hearst sites listed to the right.";
		}
		$("#postal_email_reentry").before(getErrorHtmlContent(["<li>" + postal_error_string + "</li>"]));
		clearPostalCookies();
	} else {
		$("#first_name").val(mag_user.first_name ? mag_user.first_name : "");
		$("#last_name").val(mag_user.last_name ? mag_user.last_name : "");
		$("#address_1").val(mag_user.address ? mag_user.address : "");
		$("#address_2").val(mag_user.address2 ? mag_user.address2 : "");
		$("#city").val(mag_user.city ? mag_user.city : "");
		// Select State
		$("#state option[value='" + mag_user.state + "']").attr("selected", "selected");
		$("#zip_code").val(mag_user.postal_code ? mag_user.postal_code : "");
	}
	$("#pre_curr_email").val(mag_user.email ? mag_user.email : "");
	$("#pre_curr_screenname").val(mag_user.user_name ? mag_user.user_name : "");
	$("#gender").val(mag_user.gender ? mag_user.gender : "");
	$("#dob_day").val(mag_user.dob_day ? mag_user.dob_day : "");
	$("#dob_month").val(mag_user.dob_month ? mag_user.dob_month : "");
	$("#dob_year").val(mag_user.dob_year ? mag_user.dob_year : "");
}

// Prepopulate Postal Re-entry form
function prepopulatePostal() {
	if (mag_user) {
		allowUpdateEmailAndScreenname();
		addProfileHidFields();
		loadUserProperties();
	}
}

// Allow update email address and screen for first time only
function allowUpdateEmailAndScreenname() {
	if (readCookie("first_time") == "1") {
		$(".reg_hed_info .reg_pri_inf:eq(1)").after("<div class='reg_pri_inf'><h3 class='fld_title'>New e-mail:</h3><input type='text' class='tf_input' maxlength='75' name='change_email' id='regist_new_email'></div>");
		$(".reg_hed_info").append("<div class='reg_pri_inf'><h3 class='fld_title'>New screen name:</h3><input type='text' class='tf_input' maxlength='32' name='change_user_name' id='regist_screen_name'></div>");
	}
}

// Validate a field of Postal Email Re-entry page
function isValidFieldPostalEmailReentryForm(aFieldObject) {
	return aFieldObject.regex.test(aFieldObject.control.val());
}

// Checking there are any fields filled in, SKIP password
function hasChangesPostal() {
	return ($("#regist_new_email").val() ? ($("#regist_new_email").val() != mag_user.email) : false)
		|| ($("#regist_screen_name").val() ? ($("#regist_screen_name").val() != mag_user.user_name) : false)
		|| $("#first_name").val() != mag_user.first_name || $("#last_name").val() != mag_user.last_name
		|| $("#address_1").val() != mag_user.address || $("#address_2").val() != mag_user.address2
		|| $("#city").val() != mag_user.city || $("#state").val() != mag_user.state
		|| $("#zip_code").val() != mag_user.postal_code;
}

// Go to Results page after Postal page - URL: /raap/noplan
function goToResults() {
	if (readCookie("first_time") == "1" && readCookie("yesmail_trans_id")) {
		postal_article.yesmail_sent();
	}
	else { afterPostal(); }
}

function afterPostal() {
	// We don't care about showing success. We just want to go to the next page. -- KL 2010-09-15
	var referrer = "" + readCookie("original_referrer");
	console.debug('referrer: ' + referrer);
	if ((referrer.indexOf("kevtest") > 0) || (referrer.indexOf("doctoroz") > 0)) {
		console.debug('referred by kevtest or doctoroz');
		redir = "/oz-inter";
	} else {
		if (readCookie("first_time") == "1") { redir = "/raap/noplan"; }
		else { redir = "/raap/realage-overview?recs"; }
	}
	setCookie("first_time","0");
	window.location.href = redir;
}

// Validation email for Postal Email Re-entry page
function validatePostalEmailReentryForm() {
	var pwd_regex_cntrl_msg = {regex: /^.{6,50}$/, control: $("#regist_password"), message: "<li>Please enter a password that is between 6 and 50 characters in length</li>"};// Password
	var email_regex_cntrl_msg = {regex: /^[A-Za-z0-9]+((-[A-Za-z0-9]+)|(\.[A-Za-z0-9]+)|(_[A-Za-z0-9]+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]{2,}$/, control: $("#regist_new_email"), message: "<li>Please enter a valid e-mail address using only alphanumeric characters (A–Z, 0–9). A single period (.), dash (-), underscore(_), or at sign (@) also can be used in the address if it is surrounded by alphanumeric characters</li>"};// New e-mail
	var scrname_regex_cntrl_msg = {regex: /^[a-zA-Z0-9\-_]{4,32}$/, control: $("#regist_screen_name"), message: "<li>Username must be between 4 and 32 characters in length and may contain letters, numbers, dashes, and underscores</li>"};// Screen name
	var psn_regex_cntrl_msg = [ {regex: /^([A-Za-z0-9]|\b\s\S){1,24}$/, control: $("#first_name"), message: "<li>Please enter a valid first name</li>"},// First name
		{regex: /^([A-Za-z0-9]|\b\s\S){1,64}$/, control: $("#last_name"), message: "<li>Please enter a valid last name</li>"},// Last name
		{regex: /^([A-Za-z0-9]|\b\s\S){0,100}$/, control: $("#address_1"), message: "<li>Please enter a valid address 1</li>"},// Address 1
		{regex: /^([A-Za-z0-9]|\b\s\S){0,100}$/, control: $("#address_2"), message: "<li>Please enter a valid address 2</li>"},// Address 2
		{regex: /^([A-Za-z0-9]|\b\s\S){0,100}$/, control: $("#city"), message: "<li>Please enter a valid city</li>"}// City
	];
	var zip_regex_cntrl_msg = {regex: /^(\d{5})(?:-(\d{4}))?$/, control: $("#zip_code"), message: "<li>Please enter a zip code in the format 12345 or 12345-1234</li>"};// Zip code
	var hasErrors = false;
	var errContentList = new Array();
	var errControlList = new Array();
	var errIndex = 0;
	var errCtrlClsName = "err_ctrl";
	// Check password
	if (!isValidFieldPostalEmailReentryForm(pwd_regex_cntrl_msg)) {
		hasErrors = true;
		errContentList[errIndex] = pwd_regex_cntrl_msg.message;
		errControlList[errIndex++] = pwd_regex_cntrl_msg.control;
	}
	// Check new email address only when have value
	if (email_regex_cntrl_msg.control.val() && email_regex_cntrl_msg.control.val() != "" && !isValidFieldPostalEmailReentryForm(email_regex_cntrl_msg)) {
		hasErrors = true;
		errContentList[errIndex] = email_regex_cntrl_msg.message;
		errControlList[errIndex++] = email_regex_cntrl_msg.control;
	}
	// Check new new screen name only when have value
	if (scrname_regex_cntrl_msg.control.val() && scrname_regex_cntrl_msg.control.val() != "" && !isValidFieldPostalEmailReentryForm(scrname_regex_cntrl_msg)) {
		hasErrors = true;
		errContentList[errIndex] = scrname_regex_cntrl_msg.message;
		errControlList[errIndex++] = scrname_regex_cntrl_msg.control;
	}
	// Check personal information
	$.each(psn_regex_cntrl_msg, function(i, checkElement) {
		if (!isValidFieldPostalEmailReentryForm(checkElement)) {
			hasErrors = true;
			errContentList[errIndex] = checkElement.message;
			errControlList[errIndex++] = checkElement.control;
		}
	});
	// Check Postal code for Country is 'US' only
	if ($("#postal_email_re_main input[name='country_code']").val() == "US" && !isValidFieldPostalEmailReentryForm(zip_regex_cntrl_msg)) {
			hasErrors = true;
			errContentList[errIndex] = zip_regex_cntrl_msg.message;
			errControlList[errIndex++] = zip_regex_cntrl_msg.control;
	}
	if (hasErrors) {
		// Add new error content to before of the form
		$("#postal_email_reentry").before(getErrorHtmlContent(errContentList));
		// Slide down new error content for parent DIV of the form
		$("#postal_email_re_main").slideDown("slow");
		// Set error class for all error input controls
		setErrControlClass(errControlList, errCtrlClsName);
		return false;
	}
	return true;
}

postal_article = {
	"errCtrlClsName" : "err_ctrl",
	//"new_postal_email": "",
	"profile_obj": {},
	"init": function() {
		prepopulatePostal();
		// Format Postal code is over 5 chars
		$("#zip_code").keyup(function() {
			var v = $(this).val();
			if ((v.length > 5) && (v.length < 7) && v.charAt(5) != '-') {
				var code1 = v.substr(0,5);
				var code2 = "-" + v.substr(5);
				var code = code1 + code2;
				$("#postal_code").val(code);
			}
		}).keyup();
		$("#postal_email_reentry").submit(function() {
			if (hasChangesPostal()) {
				return postal_article.submit();
			} else {
				goToResults();
				return false;
			}
		});
	},
	// Processing message per ticket 40692
	"updateMessage": function (status) {
		var member_id = mag_user.realage_member_id;
		var site_id = 1; // RealAge = 1 (default), DogAge = 2, CatAge = 3
		var email_address = mag_user.email;
		// Create message procedure
		var createMsgProc = function(json) {
			if (json.result.transaction_id) {
				setCookie("yesmail_trans_id", json.result.transaction_id);
			}
		}
		var errCreateMsgProc = function(json) {
			console.error("addMessage [member_id: " + member_id + ", site_id: " + site_id + ", email: " + email_address + "] error : " + json.error.valueOf());
		}
		// Update message
		var updateMsgProc = function(json) {
			console.debug("updateMessage success");
		}
		var errUpdateMsgProc = function(json) {
			console.error("updateMessage [transaction_id: " + readCookie("yesmail_trans_id") + "] error : " + json.error.valueOf());
		}
		var updateMsgSent = function(json) {
			// Clear holding cookie for message
			setCookie("yesmail_trans_id","",-1);
			afterPostal();
		}
		switch (status) {
			case "unsent":
				raap_raws.call('{"jsonrpc": "2.0", "method": "addMessage", "params": ["' + member_id + '","' + site_id + '","' + email_address + '","' + status + '"], "id": 1}', createMsgProc, errCreateMsgProc);
				break;
			case "ready":
				raap_raws.call('{"jsonrpc": "2.0", "method": "updateMessageSent", "params": ["' + readCookie("yesmail_trans_id") + '","1"], "id": 1}', updateMsgProc, errUpdateMsgProc);
				break;
			case "sent":
				raap_raws.call('{"jsonrpc": "2.0", "method": "updateMessageSent", "params": ["' + readCookie("yesmail_trans_id") + '","2"], "id": 1}', updateMsgSent, errUpdateMsgProc);
				break;
			default:
				console.debug("Unhandled updating message on given status: " + status);
		}
	},
	// Processing message for changing email address per ticket 40692
	"updateMessageEmail": function(trans_id, email_addr) {
		// Procedure
		var updateMsgEmailProc = function(json) {
			console.debug("updated email address");
		}
		var errUpdateMsgEmailProc = function(json) {
			console.error("updateMessageEmail [transaction_id: " + trans_id + ", email_address: " + email_addr + "] error " + json.error.valueOf());
		}
		// Call RAW update message email
		raap_raws.call("{'jsonrpc': '2.0', 'method': 'updateMessageEmail', 'params': ['" + trans_id + "', '" + email_addr + "'], 'id': 1}", updateMsgEmailProc, errUpdateMsgEmailProc);
	},
	// YesMail API call per ticket 40692
	"yesmail_sent": function() {
		this.updateMessage("ready");
		//console.debug("this.new_postal_email: " + this.new_postal_email);
		console.debug("mag_user.email: " + mag_user.email);
		// site_id: RealAge = 1 (default), DogAge = 2, CatAge = 3, RealAge UK???
		$.post("/messaging/realAgeTransMessaging.jsp",
			{ "transaction_id": readCookie("yesmail_trans_id"),
				"site_id": 1,
				"member_id": mag_user.realage_member_id,
				//"email_address": this.new_postal_email ? this.new_postal_email : mag_user.email,
				"email_address": mag_user.email,
				"mail_format": "1",
				"welcome_content": "1",
				"master_id": "1277750",
				"test_record": "0"
			},
			function(data) {
				data = jQuery.trim(data);
				console.debug("data: " + data);
				if (data && (data == "1")) {
					postal_article.updateMessage("sent");
				} else {
					console.error("yesmail_sent [transaction_id: " + readCookie("yesmail_trans_id") + ", site_id: " + mag_user.site_id + ", member_id: " + mag_user.realage_member_id + ", email_address: " + mag_user.email + "] error");
				}
			}
		);
	},
	/*"process_saving": function(request, status) {
		$("#postal_email_re_main div:first").hide();
		// Receive response text mean that error happened on wrong password
		if (request && request.responseText) {
			// Enable input elements after saving error
			$("#postal_email_reentry input[id!='pre_curr_email'][id!='pre_curr_screenname'], select").removeAttr("disabled");
			// Add new error content to before of the form
			$("#postal_email_reentry").before(getErrorHtmlContent(["<li>Your password didn't match or some fields are invalid. Please try again.</li>"]));
			// Slide down new error content for parent DIV of the form
			$("#postal_email_re_main").slideDown("slow");
			// Set error class for having input wrong password
			setErrControlClass([$("#regist_password")], this.errCtrlClsName);
		// Show success message
		} else {
			// Process message per ticket 40692
			goToResults();
		}
	},*/
	"submit": function() {
		// Remove old error content
		$("#err_content").remove();
		// Clear error class for all form's elements
		clearErrControlClass($("#postal_email_reentry input, select"), this.errCtrlClsName);
		// Go to parent DIV of the form
		window.location.href = "#postal_email_re_main";
		if (!validatePostalEmailReentryForm()) {
			return false;
		}
		// Call RAW update message email for change email address per ticket 40692
		//if ($("#regist_new_email").val() && $("#regist_new_email").val() != mag_user.email && $("#regist_new_email").val() != this.new_postal_email) {
		if ($("#regist_new_email").val() && $("#regist_new_email").val() != mag_user.email) {
			$("#postal_email_reentry input[type='hidden'][name='email']").val($("#regist_new_email").val());
			this.updateMessageEmail(readCookie("yesmail_trans_id"), $("#regist_new_email").val());
			//this.new_postal_email = $("#regist_new_email").val();
		}
		if ($("#regist_screen_name").val() && $("#regist_screen_name").val() != mag_user.user_name) {
			$("#postal_email_reentry input[type='hidden'][name='user_name']").val($("#regist_screen_name").val());
		}
		setCookie("fromPostalReg","1");
		return true;
		/*$("#postal_email_reentry input, select").attr("disabled", "disabled");
		$("#postal_email_re_main div:first").show();
		postal_article.profile_obj.combined_profile = $("#postal_email_reentry input[type='hidden'][name='combined_profile']").val();
		postal_article.profile_obj.ur_id = $("#postal_email_reentry input[type='hidden'][name='ur_id']").val();
		postal_article.profile_obj.from_lite = $("#postal_email_reentry input[type='hidden'][name='from_lite']").val();
		postal_article.profile_obj.logged_in = $("#postal_email_reentry input[type='hidden'][name='logged_in']").val();
		postal_article.profile_obj.country_code = $("#postal_email_reentry input[type='hidden'][name='country_code']").val();
		postal_article.profile_obj.gender = $("#gender").val();
		postal_article.profile_obj.dob_month = $("#dob_month").val();
		postal_article.profile_obj.dob_day = $("#dob_day").val();
		postal_article.profile_obj.dob_year = $("#dob_year").val();
		postal_article.profile_obj.old_password = $("#regist_password").val();
		postal_article.profile_obj.email = $("#regist_new_email").val() ? $("#regist_new_email").val() : mag_user.email;
		postal_article.profile_obj.user_name = $("#regist_screen_name").val() ? $("#regist_screen_name").val() : mag_user.user_name;
		postal_article.profile_obj.first_name = $("#first_name").val();
		postal_article.profile_obj.last_name = $("#last_name").val();
		postal_article.profile_obj.address = $("#address_1").val();
		postal_article.profile_obj.address2 = $("#address_2").val();
		postal_article.profile_obj.city = $("#city").val();
		postal_article.profile_obj.state = $("#state").val();
		postal_article.profile_obj.postal_code = $("#zip_code").val();
		// Call RAW update message email for change email address per ticket 40692
		if ($("#regist_new_email").val() && $("#regist_new_email").val() != mag_user.email && $("#regist_new_email").val() != this.new_postal_email) {
			this.updateMessageEmail(readCookie("yesmail_trans_id"), $("#regist_new_email").val());
			this.new_postal_email = $("#regist_new_email").val();
		}
		$.ajax({
			type: "POST",
			url: "/registration/saveProfile",
			data: { "combined_profile" : postal_article.profile_obj.combined_profile,
				"ur_id" : postal_article.profile_obj.ur_id,
				"from_lite" : postal_article.profile_obj.from_lite,
				"logged_in" : postal_article.profile_obj.logged_in,
				"country_code" : postal_article.profile_obj.country_code,
				"gender" : postal_article.profile_obj.gender,
				"dob_month" : postal_article.profile_obj.dob_month,
				"dob_day" : postal_article.profile_obj.dob_day,
				"dob_year" : postal_article.profile_obj.dob_year,
				"old_password" : postal_article.profile_obj.old_password,
				"email" : postal_article.profile_obj.email,
				"user_name" : postal_article.profile_obj.user_name,
				"first_name" : postal_article.profile_obj.first_name,
				"last_name" : postal_article.profile_obj.last_name,
				"address" : postal_article.profile_obj.address,
				"address2" : postal_article.profile_obj.address2,
				"city" : postal_article.profile_obj.city,
				"state" : postal_article.profile_obj.state,
				"postal_code" : postal_article.profile_obj.postal_code
			},
			complete: function(XMLHttpRequest, textStatus) { postal_article.process_saving(XMLHttpRequest, textStatus); }
		});*/
	}
}

function setShowMoreEllipses(tag, recnumber)
{
	var DivShowEllipses = "<span id=\"ellipses_QQQ\" class=\"ellipses show-ellipses\"> . . .<br/><br/><br/><br/><br/></span>"
	var PlaceHolderRecNumber = "QQQ";
	var regularExp = new RegExp(PlaceHolderRecNumber, "g");
	var spanoutput = DivShowEllipses.replace(regularExp, recnumber);
	tag.innerHTML = spanoutput
}

function setBegEndDivTags(recDiv, recnumber)
{
	var showmoreelements = recDiv.getElementsByTagName('span');
	var ellipsesSet = false;
	for (var i=0;i<showmoreelements.length;i++)
	{
		if (showmoreelements[i].className == "div-show-ellipses")
		{
			setShowMoreEllipses(showmoreelements[i], recnumber);
			ellipsesSet = true;
		}
	}

	if (recDiv.offsetHeight > 100 || ellipsesSet) {
		var innerHTMLDiv;
		innerHTMLDiv = recDiv.innerHTML;

		var DivBegStatic = "<div id=\'recContainer_QQQ\' class=\'inner-container-right\'><div style=\'display: block;\' id=\'showMoreContainer_QQQ\' class=\'show-more-container\'><a href=\'javascript:;\' class=\'expandable_readmore\' onclick=\"javascript:ShowMe(\'QQQ\'); return false;\"></a></div><a name=\'ridQQQ\'></a>"
		var DivEndStatic = "<div style=\'display: block;\' id=\'closeContainer_QQQ\' class=\'close-container\'><a href=\'javascript:;\' class=\'expandable_collapse\' onclick=\"javascript:CloseMe(\'QQQ\'); return false;\"></a></div></div>";
		var DivBeg;
		var DivEnd;
		var PlaceHolderRecNumber = "QQQ";
		var regularExp = new RegExp(PlaceHolderRecNumber, "g");

		DivBeg = DivBegStatic.replace(regularExp,recnumber);
		DivEnd = DivEndStatic.replace(regularExp,recnumber);
		recDiv.innerHTML = DivBeg + innerHTMLDiv + DivEnd;
	}
	//alert(DivBeg);
	//alert(DivEnd);
}



// Custom Accordion Control
// Original Author Unknown
// Modified By Joseph DiPierro April 2008
// For RealAge, Inc.  All Rights Reserved

var OnlyOneOpenAtATime = false;  // Only open one 'accordion control' at a time
var OpenStack = [];              // This will hold a list of opened recommendation ids

var timerlen = 10;                // This is how often the timer fires - every 10 miliseconds or 1/100 of a second
var normalSlideSpeed = 15;        // This adjusts the normal speed of the slider, higher is faster - Actually, it's the number of pixels each increment changes
var fastSlideSpeed = 20;         // This adjusts the faster speed of the slider, higher is faster - Actually, it's the number of pixels each increment changes
var offsetBloat = 9;			// The expected difference between the style.height and offsetHeight of our accordian div.

// These are all arrays because each accordion control will have one of these
var timerID = new Array();
var recObj = new Array();
var endHeight = new Array();
var moving = new Array();
var dir = new Array();
var IsVisible = new Array();
var ClosedStateInPx = new Array();
var OpenStateInPx = new Array();

// The variables below will be set when needed to an object on the page - usually a div or span

// Each accordion control will have a unique identifier - the recID will be prepended
var accordionContainerName = "recAccordionContainer_";
var recContainerName       = "recContainer_";
var showMoreContainerName  = "showMoreContainer_";
var closeContainerName     = "closeContainer_";
var ellipsesSpanName       = "ellipses_";

// There are only one of each of these
var showMeYoungerName      = "showMeYounger";
var showMeOlderName        = "showMeOlder";
var combinedListName       = "combinedList";

// slidedown - triggers the accordion control to expand
function slidedown(rec_id, slideSpeed)
{
    if (moving[rec_id])
        return;

    if (IsVisible[rec_id])
        return;

    var accordionContainer = document.getElementById(accordionContainerName + rec_id);
    var recContainer = document.getElementById(recContainerName + rec_id);

    // Only slide down if the height of the recommendation container is greater than the height of the accordion container
   if (recContainer.offsetHeight > accordionContainer.offsetHeight)
   {
        ClosedStateInPx[rec_id] = accordionContainer.offsetHeight;
        OpenStateInPx[rec_id] = recContainer.offsetHeight;

        moving[rec_id] = true;
        dir[rec_id] = "down";

        recObj[rec_id] = accordionContainer;
        startslide(rec_id, slideSpeed);
    }
}

// slideup - triggers the accordion control to collapse from an expanded state
function slideup(rec_id, slideSpeed)
{
    if (moving[rec_id])
        return;

    if (!IsVisible[rec_id])
        return;

    var accordionContainer = document.getElementById(accordionContainerName + rec_id);

    OpenStateInPx[rec_id] = accordionContainer.offsetHeight;

    moving[rec_id] = true;
    dir[rec_id] = "up";

    recObj[rec_id] = accordionContainer;
    startslide(rec_id, slideSpeed);
}

// startslide - triggers the accordion control to start sliding
function startslide(rec_id, slideSpeed)
{

    if (IsVisible[rec_id])
        endHeight[rec_id] = ClosedStateInPx[rec_id];
    else
       endHeight[rec_id] = OpenStateInPx[rec_id];

    recObj[rec_id].style.display = "block";
    IsVisible[rec_id] = true;

    // start the sliding process
    timerID[rec_id] = setInterval('slidetick(\'' + rec_id + '\',' + slideSpeed + ');',timerlen);
}

// slidetick - this is where the accordion control actually moves - It is called continuously
// ad a preset interval 'timerlen' until the control has reached it's opened or closed position.
function slidetick(rec_id, slideSpeed)
{
    var recHeight = recObj[rec_id].offsetHeight;

    // increase or decrease the height of the recommendation accordion container
    if (dir[rec_id] == "up")
        recHeight -= slideSpeed;
    else
        recHeight += slideSpeed;

    // If the new height is greater than or equal-to the fully expanded heght then stop sliding.
    // Same goes if the height is less than or equal-to the default closed height.
    // Otherwise, just set the new height and let the interval run again.

    if ( (recHeight >= OpenStateInPx[rec_id]) || (recHeight <= ClosedStateInPx[rec_id]) )
        endSlide(rec_id);
    else
        recObj[rec_id].style.height = recHeight + "px";

    return;
}

// endSlide - this is called when the control has reached it's opened or closed position.
function endSlide(rec_id)
{
    // stop sliding
    clearInterval(timerID[rec_id]);

    // set the final recommendation accordion control height
    if(dir[rec_id] == "up")
    {
        recObj[rec_id].style.height = (ClosedStateInPx[rec_id] - offsetBloat) + "px";
        IsVisible[rec_id] = false;
    }
    else
    {
        recObj[rec_id].style.height = endHeight[rec_id] + "px";
    }

    delete(moving[rec_id]);
    delete(timerID[rec_id]);
    delete(endHeight[rec_id]);
    delete(recObj[rec_id]);
    delete(dir[rec_id]);

    return;
}

/* --------------------------------------------------------------------------*/

// ShowMe - Show the recommendation (expand the accordion control) and hide the Show Me button and Ellipses
function ShowMe(rec_id)
{
   // if (OnlyOneOpenAtATime)
   //     CloseAll();

    // hide the ellipses for this recommendation if it's there
    var ellipsesSpan = document.getElementById(ellipsesSpanName + rec_id);
    if (ellipsesSpan)
        ellipsesSpan.className  = "ellipses hide-ellipses";

    // hide the Show More div for this recommendation if it's there
    var showMoreDiv = document.getElementById(showMoreContainerName + rec_id);
    if (showMoreDiv)
        showMoreDiv.style.display = "none";

    slidedown(rec_id, normalSlideSpeed );

    // add this rec_id to the opened recommendations stack
    OpenStack.push(rec_id);

    // Finally, if necessary, close all other open recs
     if (OnlyOneOpenAtATime)
         CloseAllButThis(rec_id);
}

// ShowAll - Show all the recommendation, costs, benefits, or both groups
function ShowAll(bens,costs)
{
    var allDivs = document.getElementsByTagName("div");
    var splitDiv;

    // loop through all div tags on the page
    for (var i=0; i < allDivs.length; i++)
    {
        if (allDivs[i].getAttribute("id") != null)
        {
            // if the div has an id attrubute split it on the underscore charactrer
            splitDiv = allDivs[i].getAttribute("id").split("_");

            // the result will be something like this:
            // [0] = recommendation
            // [1] = benefit
            // [2] = 123

            // if the first part of the div is recommendation check to see if benefit or cost follows
            if (splitDiv[0] == "recommendation")
            {
                if(splitDiv[1] == "benefit")
                {
                    if (bens)
                        ShowMe(SplitDiv[2]);
                }
                else if(splitDiv[1] == "cost")
                {
                    if (costs)
                        ShowMe(SplitDiv[2]);
                }
            }
        }
    }
}

// CloseMe - minimize the recommendation (collapse the expanded accordion control) and display the Show Me button and Ellipses
function CloseMe(rec_id)
{
    if (moving[rec_id])
    {
        // wait until this recommendation accordion control stops moving
        setTimeout('CloseMe(\'' + rec_id + '\');',timerlen);
        return;
    }

    slideup(rec_id, fastSlideSpeed);

    // then wait until the control is fully closed before showing the Show more link and ellipses
    ShowShowMoreLink(rec_id);
}

// CloseMeThisSpeed - minimize the recommendation (collapse the expanded accordion control) and display the Show Me button and Ellipses
function CloseMeThisSpeed(rec_id, slideSpeed)
{
    if (moving[rec_id])
    {
        // wait until this recommendation accordion control stops moving
        setTimeout('CloseMeThisSpeed(\'' + rec_id + ',' + slideSpeed + '\');',timerlen);
        return;
    }

    slideup(rec_id, slideSpeed);

    // then wait until the control is fully closed before showing the Show more link and ellipses
    ShowShowMoreLink(rec_id);
}


// CloseAll - minimize any and all expanded recommendations (collapse all expanded accordion controls) and display the Show Me button and Ellipses
function CloseAll()
{
    // If a rec is open it will be on the stack.  Close all open recs
    while (OpenStack.length > 0)
    {
        var open_rec_id = OpenStack.pop();
        CloseMe(open_rec_id);
    }
}


// CloseAllButThis - minimize any and all expanded recommendations (collapse all expanded accordion controls) Except for the one passed in
function CloseAllButThis(rec_id)
{
    if (moving[rec_id])
    {
        // wait until this recommendation accordion control stops moving
       setTimeout('CloseAllButThis(\'' + rec_id + '\');',timerlen);
       return;
    }

    var rec_id_poped = false;

    // If a rec is open it will be on the stack.  Close all open recs
    while (OpenStack.length > 0)
    {
        var open_rec_id = OpenStack.pop();

        if (open_rec_id == rec_id)
            rec_id_poped = true;
        else
            CloseMeThisSpeed(open_rec_id, fastSlideSpeed);
    }
    // push the passed in rec_id back on the stack if it was poped
    if (rec_id_poped)
        OpenStack.push(rec_id);
}


// ShowShowMoreLink - Waits until the control is done sliding before showing the 'Show more' link
function ShowShowMoreLink(rec_id)
{
    if (moving[rec_id])
    {
       // wait until this recommendation accordion control stops moving
       setTimeout('ShowShowMoreLink(\'' + rec_id + '\');',timerlen);
       return;
    }

    var ellipsesSpan = document.getElementById(ellipsesSpanName + rec_id);
    if (ellipsesSpan)
       ellipsesSpan.className  = "ellipses show-ellipses";

    var showMoreDiv = document.getElementById(showMoreContainerName + rec_id);
    if (showMoreDiv)
        showMoreDiv.style.display = "block";
}

// ShowAllRecommendations - Called from the Plan Overview page selector control
// Shows all the recommendation, costs, benefits, or both groups
function ShowAllRecommendations(bens,costs)
{
    var showMeYoungerLink = document.getElementById(showMeYoungerName);
    var showMeOlderLink = document.getElementById(showMeOlderName);
    var combinedListLink = document.getElementById(combinedListName);

    var seeAllYounger = (bens  && ! costs);
    var seeAllOlder   = (costs && ! bens);
    var combined      = (bens  && costs);

    var seeAllYoungerLinkVisible = (showMeYoungerLink.style.display == "" || showMeYoungerLink.style.display == "block");
    var seeAllOlderLinkVisible   = (showMeOlderLink.style.display == ""   || showMeOlderLink.style.display == "block");
    var combinedLinkVisible      = (combinedListLink.style.display == "block");

    // If we are already seeing all Younger or all Older then nothing to do
    if ((seeAllYounger && ! seeAllYoungerLinkVisible) ||
        (seeAllOlder   && ! seeAllOlderLinkVisible))
    {
        return;
    }

    showMeYoungerLink.style.display = (seeAllYounger ? "none" : "block");
    showMeOlderLink.style.display =   (seeAllOlder   ? "none" : "block");
    combinedListLink.style.display =  (combined      ? "none" : "block");

    if (seeAllYounger || seeAllOlder)
    {
        // If the category containers are expanded then close them
        if (combinedLinkVisible)
        {
            CloseAll();
            // We need to give everything some time to settle down before processing the recommendaitons then expanding all
            setTimeout('ProcessRecommendations(' + bens + ',' + costs + ');',1000);
            setTimeout('ExpandAll();',1500);
        }
        else
        {
            ProcessRecommendations(bens,costs);
            // We need to give everything some time to settle down before expanding all
            setTimeout('ExpandAll();',500);
        }
    }
    else  // combined the lists
    {
        CloseAll();
        // We need to give everything some time to settle down before processing the recommendaitons then expanding all
        setTimeout('ProcessRecommendations(' + bens + ',' + costs + ');',1000);
    }
}


// PrintAllRecommendations - Called from the Print Overview page - selector control
// Shows all the recommendation, costs, benefits, or both groups
function PrintAllRecommendations(bens,costs)
{
    // We want to allow all category containers to open
    OnlyOneOpenAtATime = false;

    var showMeYoungerLink = document.getElementById(showMeYoungerName);
    var showMeOlderLink = document.getElementById(showMeOlderName);
    var combinedListLink = document.getElementById(combinedListName);

    var seeAllYounger =  (bens && ! costs);
    var seeAllOlder   =  (costs && ! bens);
    var combined      =  bens && costs;

    var seeAllYoungerLinkVisible = (showMeYoungerLink.style.display == "" || showMeYoungerLink.style.display == "block");
    var seeAllOlderLinkVisible   = (showMeOlderLink.style.display == ""   || showMeOlderLink.style.display == "block");
    var combinedLinkVisible      = (combinedListLink.style.display == "block");

    // If we are already seeing all Younger or all Older then nothing to do
    if ((seeAllYounger && ! seeAllYoungerLinkVisible) ||
         (seeAllOlder   && ! seeAllOlderLinkVisible))
    {
        return;
    }

    showMeYoungerLink.style.display = (seeAllYounger ? "none" : "block");
    showMeOlderLink.style.display =   (seeAllOlder   ? "none" : "block");
    combinedListLink.style.display =  (combined      ? "none" : "block");

    CloseAll();
    // We need to give everything some time to settle down before processing the recommendaitons then expanding all
    setTimeout('ProcessRecommendations(' + bens + ',' + costs + ');',1000);
    setTimeout('ExpandAll();',1500);
}


// ShowRecommendations - This function is called from the Plan Detail page selector control
// Show all the recommendation, costs, benefits, or both groups
function ShowRecommendations(bens,costs)
{
    var showMeYoungerLink = document.getElementById(showMeYoungerName);
    var showMeOlderLink = document.getElementById(showMeOlderName);
    var combinedListLink = document.getElementById(combinedListName);

    var seeAllYoungerLinkVisible = (showMeYoungerLink.style.display == "" || showMeYoungerLink.style.display == "block");
    var seeAllOlderLinkVisible   = (showMeOlderLink.style.display == ""   || showMeOlderLink.style.display == "block");

    var seeAllYounger =  bens && ! costs;
    var seeAllOlder   =  costs && ! bens;
    var combined      =  bens && costs;

    // If we are already seeing all Younger or all Older then nothing to do
    if ((seeAllYounger && ! seeAllYoungerLinkVisible) ||
         (seeAllOlder && ! seeAllOlderLinkVisible))
    {
        return;
    }

    showMeYoungerLink.style.display = (seeAllYounger ? "none" : "block");
    showMeOlderLink.style.display =   (seeAllOlder   ? "none" : "block");
    combinedListLink.style.display =  (combined      ? "none" : "block");

    ProcessRecommendations(bens,costs);
}

// ProcessRecommendations - This function does the actual showing or hiding recommendation costs, benefits, or both groups
function ProcessRecommendations(bens,costs)
{
   // This was allowing the see all Younger and see all Older to be called continuiously

    var allDivs = document.getElementsByTagName("div");
    var splitDiv;
	var count;

    // loop through all div tags on the page
    for (var i=0; i < allDivs.length; i++)
    {
        if (allDivs[i].className != null)
        {
			if (allDivs[i].className != "")
			{
				// if the div has an id attrubute split it on the underscore charactrer
				splitDiv = allDivs[i].className.split(" ");

				// if the first part of the div is recommendation check to see if benefit or cost follows
				for (count=0; count<splitDiv.length; count++)
				{
					if (splitDiv[count] == "is-benefit") { allDivs[i].style.display = (bens)? "block":"none"; }
					if (splitDiv[count] == "is-cost") { allDivs[i].style.display = (costs)? "block":"none"; }
				}
			}
        }
    }
}

// ExpandAll - Expand all recommendation containers - used on print pages
function ExpandAll()
{
    // We want to allow all category containers to open
    OnlyOneOpenAtATime = false;

    var allDivs = document.getElementsByTagName("div");
    var splitDiv;
    var rec_category;

    // loop through all div tags on the page
    for (var i=0; i < allDivs.length; i++)
    {
        if (allDivs[i].getAttribute("id") != null)
        {
            // if the div has an id attrubute split it on the underscore charactrer
            splitDiv = allDivs[i].getAttribute("id").split("_");

            // the result will be something like this:
            // [0] = accordionContainer
            // [1] = health

            // if the first part of the div is accordionContainer expand it
            if (splitDiv[0] == "accordionContainer")
            {
                rec_category = splitDiv[1];
                ShowMe(rec_category);
            }
        }
    }
}

// OpenBookmark - If there is a bookmark in the URL identify the rec_id and open it
// Example URL:  http://www.realage.com/ralong/planner/habits.aspx#rid108
function OpenBookmark()
{
    var bookmarkIndex = window.location.href.indexOf('#');

    if (bookmarkIndex > -1)
    {
        // Add 4 to the bookmark Index to remove the '#rid'
        var bookmark = window.location.href.substring(bookmarkIndex+4);
        ShowMe(bookmark);
    }
}

// HideOpenCloseLinks - If the height of the recomendation is not bigger than the height of the
// accordion container then we do not need the open and close links, so hide them
function HideOpenCloseLinks()
{
    var allDivs = document.getElementsByTagName("div");
    var splitDiv;

    // loop through all div tags on the page
    for (var i=0; i < allDivs.length; i++)
    {
        if (allDivs[i].getAttribute("id") != null)
        {
            // if the div has an id attrubute split it on the underscore charactrer
            splitDiv = allDivs[i].getAttribute("id").split("_");

            // the result will be something like this:
            // [0] = accordionContainer
            // [1] = health

            // if the first part of the div is accordionContainer expand it
            if (splitDiv[0] == "accordionContainer")
            {
                var rec_id = splitDiv[1];
                var accordionContainer = allDivs[i];  // document.getElementById(accordionContainerName + rec_id);
                var recContainer = document.getElementById(recContainerName + rec_id);

                var showMoreLink = document.getElementById(showMoreContainerName + rec_id);
                var closeLink = document.getElementById(closeContainerName + rec_id);

                var showLink = (recContainer.offsetHeight > accordionContainer.offsetHeight + 12);

                if (showMoreLink)
                    showMoreLink.style.display = (showLink ? "block" : "none");

                if (closeLink)
                    closeLink.style.display    = (showLink ? "block" : "none");
            }
        }
    }
}

function appendEvent(eventName) {
	var eventsToAppend;
	eventsToAppend = $h.util.getCookie("eventsToAppend");
	if (eventsToAppend) { eventsToAppend = eventsToAppend.split(','); }
	else { eventsToAppend = new Array(); }
	eventsToAppend.push(eventName);
	$h.util.setCookie("eventsToAppend",eventsToAppend,{"path" : "/", "domain" : cookieDomain});
}

//Opts in the user
function UserOptIn() {
//Will return true if optin is successful or if user is already opted in
	if (mag_user.email != "") {
		if (mag_user.general_optin == "Y"){
			return true;
		} else {
			$.post("/registration/save_email_prefs?json=1",{"ur_id": mag_user.ur_id,"ep_56_default_1" : "Y","ep_56_1_1" : "Y"});
			appendEvent("event11");
			return true;
		}
	}
	return false;
}
function getRAAPAgeInfo(){
	var child_id = readCookie("raap_child_id");
	var newproc = function(json){
		var results = json.result;
		if (results.real_age != null){
			raap_raws.variables.real_age = results.real_age;
			raap_raws.variables.cal_age = results.current_age;
			raap_raws.variables.last_updated = results.last_updated_date;
			// get cal_diff string
			var cal_diff = parseFloat(raap_raws.variables.real_age - raap_raws.variables.cal_age).toFixed(1);
			if (cal_diff > 0){
				cal_diff = "+"+cal_diff;
			}
			raap_raws.variables.cal_diff = cal_diff;
		} else {
			raap_raws.variables.cal_age = results.current_age;
		}
	}
	var errproc = function(json){}
	raap_raws.call('{"jsonrpc": "2.0", "method": "getRealAge", "params": ["'+child_id+'"], "id": 1}',newproc,errproc);
}

function getCalAge(date1) {
	now = new Date()
	born = new Date(date1);
	years = Math.abs((now.getTime() - born.getTime()) / (365.25 * 24 * 60 * 60 * 1000));
	return years;
}

// RAAP datamode json url
function getRaapUrl() {
	var url = "http://raap.realage.com/data/json?callback=?";
	if (window.location.href.indexOf("alphapreview")>=0 || window.location.href.indexOf("betapreview")>=0 || window.location.href.indexOf("stage.")>=0) { 
		url = "http://stageraap.realage.com/data/json?callback=?";
	}
	return url;
}

/*****************************
*	raap_raws namespace
******************************/
var raap_raws = {
	variables : {
		member_id : null,
		cal_age : "?",
		cal_diff : "+/-",
		real_age : "??",
		news : null,
		goals : null,
		isActive : null,
		last_updated : null,
		personalpod_data : null,
		child_id: null,
		MAX_FACT_VALUE_LENGTH: "30"
	},
	call : function(data,proc,err){
		var success = function(json){
			if (json.hasOwnProperty("result")) {
					proc(json);
			} else if (json.hasOwnProperty("error")) {
					console.error("JSON RPI ERROR["+json.error.code+"] "+json.error.message);
					err(json);
			} else {
				console.error("UNKNOWN RESULT");
			}
		}
		var testobj = {
			"url": "/raws2/",
			"dataType": "json",
			"type": "POST",
			"data": data,
			"contentType": "application/json",
			"success": success
		}
		jQuery.ajax(testobj);
	},
	hasValidChildId: function() {
		var childId = this.getChildId();
		if (childId != null && childId.length > 0 && childId != "0") {
			return true;
		}
		return false;
	},
	getChildId: function() {
		this.child_id = RA.utils.getCookie("raap_child_id");
		return this.child_id;
	},
	getFactValue: function(aFactId, aCallback) {
		// can return empty string or null (undefined) as valid value
		this.getChildId();
		var newproc = function(json){
			var results = json.result;
			$.each(results, function(key,value){
				// TODO - if hardcoded "aValue" variable name passed in function a hack, fix it - ker
				aValue = results[key].fact_value;
				if (typeof(aCallback) == 'function') aCallback(aValue);
				return results[key].fact_value;
			});
		}	
		var errproc = function(json){}
		ra_raws.call('{"jsonrpc": "2.0", "method": "getFactValue", "params": ["' + this.child_id + '","' + aFactId +  '"], "id": 1}',newproc,errproc);
	},
	getFactValues: function(aFactList) {
		this.getChildId();
		// TODO - accepts list of fact ids: getFactValues($child_id, $fact_id1, $fact_id2, etc.);
		// Returns an ARRAY of KEY -> VALUE MAPPINGS - see getFactValue
	},
	setFactValue: function(aFactId, aFactValue) {
		//Call will fail RAAP-RAWS validation if fact value length database constraint is exceeded.
		this.getChildId();
		if ((aFactValue != undefined) && (aFactValue.length > 0 && aFactValue.length <= this.variables.MAX_FACT_VALUE_LENGTH) && (aFactId != null)) {
			var newproc = function(json){
			var results = json.result; }
			var errproc = function(json){}
			ra_raws.call('{"jsonrpc": "2.0", "method": "setFactValue", "params": ["' + this.child_id + '","' + aFactId + '","' +  aFactValue + '"], "id": 1}',newproc,errproc);
		} else {
			return false;
		}
	},	
	setFactValues: function(aFactArr) {
		//TODO - accepts array of fact id and fact value key/value pairs; relative risk values optional
	},
	clearFactValue: function(aFactId) {
		//bug in setFactValue call, fix in RAAP v2.006 - RAAP-RAWS validation fails if pass empty string value; using "setFactValues" instead
		this.getChildId();
		var newproc = function(json){
		var results = json.result;
			return true;
		}
		var errproc = function(json){}
		//set to empty fails: ra_raws.call('{"jsonrpc": "2.0", "method": "setFactValue", "params": ["' + this.child_id + '","' + aFactId + '","' + "" + '"], "id": 1}',newproc,errproc);
		ra_raws.call('{"jsonrpc": "2.0", "method": "setFactValues", "params": ["' + this.child_id + '", [{"fact_id": "' + aFactId + '","fact_value": ""}] ], "id": 1}',newproc,errproc);		
	}
}

/*****************************
*	raTest namespace
******************************/
var raTest = {
	complete: false,
	child_id: null,
	mod_ids: null,
	completedModules: null,
	callback: null,
	calculatedRealAge: null,
	last_location_fact_id: "18468",		//TODO pass from article; same staging, prod
	firstPgId: null,
	RESUME_KEY: "raTest_resume",
	COMPLETE_KEY: "raTest_complete",
	REALAGE_KEY: "raTest_realage",
	TAKEN_KEY: "raTest_taken_dt",
	real_age: "??",
	actual_age: "?",
	age_diff: "+/-",
	taken_dt: null,
	setCompletedModules: function(){
		if (this.child_id != null) {
			// RAAP datamode call
			$.ajax({
				url: getRaapUrl(),
				dataType: "jsonp",
				cache: false,
				data: {'method': 'getCompletedChildModules', 'params': '{"child_id":"' + this.child_id + '"}' },
				jsonpCallback: 'raTest.setTestComplete'
			});
		}
	},
	setTestComplete: function (data) {
		completedModules = data.result;

		var health_ids, feelings_ids, diet_ids, fitness_ids;
		$.each(this.mod_ids, function(key, value) {
			switch (key) {
				case "health":
					health_ids = value;
				case "feelings":
					feelings_ids = value;
				case "diet":
					diet_ids = value;
				case "fitness":
					fitness_ids = value;
			}
		});

		var health_comp = false;
		var feelings_comp = false;
		var diet_comp = false;
		var fitness_comp = false;
		var module_id_regex;

		$.each(completedModules, function(i,item) {
			module_id_regex = new RegExp("\\b" + item.module_id + "\\b");		
			if (module_id_regex.test(health_ids)) { health_comp = true; raTest.setLastTakenDt(item.completed_dttm); }
            if (module_id_regex.test(feelings_ids)) { feelings_comp = true; raTest.setLastTakenDt(item.completed_dttm); }
            if (module_id_regex.test(diet_ids)) { diet_comp = true; raTest.setLastTakenDt(item.completed_dttm); }
            if (module_id_regex.test(fitness_ids)) { fitness_comp = true; raTest.setLastTakenDt(item.completed_dttm); }

		});

		if (health_comp && (feelings_comp || diet_comp || fitness_comp)) { this.complete = true; }	
		
		// persist
		RA.utils.storeData(this.COMPLETE_KEY, this.complete);
		if (this.complete == true) {
			RA.utils.storeData(this.TAKEN_KEY, this.formatTakenDt(this.taken_dt) );
		}	
		
		if (typeof(this.callback) == 'function') this.callback();
	},
	getCalculatedRealAge: function(passed_allow_incomplete,passed_callback) {
		// RAAP datamode call
		// allow_incomplete parameter
		// 0: returns null if RAAP criteria not met for RealAge test completion
		// 1: value returned even if RAAP determines child has not completed the RealAge test
		if (this.child_id != null) {
			var calcRAParams = { "method": "calculateRealAge", "params": '{"child_id":"' + this.child_id + '","allow_incomplete":"' + passed_allow_incomplete + '"}' };
			$.getJSON(getRaapUrl(), calcRAParams, function(CalcRA) {
				if (CalcRA.result != null) {
					this.calculatedRealAge = CalcRA.result;
					// persist
					RA.utils.storeData(raTest.REALAGE_KEY, raTest.getRoundedAge(this.calculatedRealAge));
					if (typeof(passed_callback) == 'function') passed_callback(CalcRA.result);
				}
			});
		}
	},
	setLastTakenDt: function(moduleCompleteDt) {
        if (moduleCompleteDt != null) {
            var dateArray = moduleCompleteDt.split(' ');
            var datePart;
            if (dateArray.length >= 1) { datePart = dateArray[0]; }
            if (this.taken_dt == null || this.taken_dt < datePart) {
                this.taken_dt = datePart;
            }
        }
    },
	formatTakenDt: function(dt) {
		var shortDt = null;
		if (dt != null) {
			var dateSplit = dt.split('-');
			if (dateSplit.length > 2) {
				shortDt = dateSplit[1] + "/" + dateSplit[2] + "/" + dateSplit[0] ;
			}
		}
		return shortDt;
	},
	getComplete: function() {
		// read persisted value if available
		var asmtComplete = RA.utils.getData(this.COMPLETE_KEY);
		if (!asmtComplete)  {
			asmtComplete = null;	
		}
		return asmtComplete;
	},
	getRoundedAge: function(age) {
		if (age != null & age > 0) {
			return Math.round(age * 10) / 10;
		}
		return 0
	},
	
	/** start COMPLETION UX **/
	setCompletionUX: function(asmt_id) {
		//set user experience based on RA Test completion
		//refactored from checkAssessmentCompletion function to assure "getCompletedChildModules" call not duplicated on page
		if (this.getComplete() == null) {
			//module completion call not made yet this session, make the call with callback to set items
			raTest.init(mod_ids,function(){raTest.setCompletionUX_Items(asmt_id)});				
		} else {
			//module completion value found, set items
			this.setCompletionUX_Items(asmt_id);
		}
	},
	setCompletionUX_Items: function(asmt_id) {
		var first_time = 1;		
		if (this.getComplete() == "true") { first_time = 0; }
		if (first_time == 1) { HideNavigationElements(); }
		if (first_time == 0) { $("#results_link").css("display","block"); }
		setCookie("first_time",first_time);
		setCookie("hideresults_" + asmt_id,first_time);
	},
	clearCompletionUX: function() {
		var asmt_id = RA.utils.getCookie("current_ass_id");	
		RA.utils.eraseCookie("hideresults_" + asmt_id);
		RA.utils.eraseCookie("first_time");
	},
	/** end COMPLETION UX **/

	/** start MY REALAGE **/
	sessionInitMyRealAge: function() {
		// makes first call of session to calculate realage, if no call has been made yet, and if logged in
		// stored raTest complete value is only found if a call has already been made to setTestComplete
		if (this.getComplete() == null)   {
			raTest.init(mod_ids,function(){raTest.setMyRealAge()});
		} else if (this.getComplete() == "true" && this.getRealAge() == null ) {
			// call to get complete value was made in this session, but still need to make calc RA call
			this.setMyRealAge();
		}		
	},
	setMyRealAge: function() {
		// calculate realage, if criteria met; set the My Realage elements
		// uses values from init; example as callback to init: raTest.init(mod_ids,function(){raTest.setMyRealAge()});
		if (this.getComplete() == "true") {
			raTest.getCalculatedRealAge("1",raTest.setMyRA_Elements);
		} else {
			// set default values
			raTest.setMyRA_Elements(null);
		}
	},
	getMyRealAge: function() {
		// read persisted values if available; set the My Realage elements
		if (raap_raws.hasValidChildId() ) {
			if (this.getComplete() == "true") {
				raTest.setMyRA_Elements(this.getRealAge() );
			} else {
				// set default values
				raTest.setMyRA_Elements(null);
			}		
		} else {
			this.clearMyRA_StoredValues();
		}
	},
	getRealAge: function() {
		// read persisted value if available
		var realage = RA.utils.getData(this.REALAGE_KEY);
		if (!realage)  {
			realage = null;	
		}
		return realage;
	},
	getTakenDt: function() {
		// read persisted value if available
		var taken_dt = RA.utils.getData(this.TAKEN_KEY);
		if (!taken_dt)  {
			taken_dt = null;	
		}
		return taken_dt;
	},
	clearMyRA_StoredValues: function() {
		// clear persisted values
		RA.utils.eraseData(this.TAKEN_KEY);
		RA.utils.eraseData(this.REALAGE_KEY);
		RA.utils.eraseData(this.COMPLETE_KEY);
	},
	setMyRA_Elements: function(calcRA) {
		// elements are shared site-wide	
		if (calcRA != null) {
			this.real_age = raTest.getRoundedAge(calcRA);
			this.actual_age = raTest.getRoundedAge(getCalAge(mag_user.birth_date));
			this.taken_dt = raTest.getTakenDt();
			
			// get age_diff string
			var age_diff = parseFloat(this.real_age - this.actual_age).toFixed(1);
			if (age_diff > 0){
				age_diff = "+"+age_diff;
			}
			this.age_diff = age_diff;

			if (window.location.pathname == "" || window.location.pathname == "/") { //homepage
				$(".hp-logged-out").hide();
				$(".hp-logged-in").show();
				personalize("$('.hp-logged-in-carousel').html(personalHomepageCarousel);$('.hp-logged-in-carousel').jCarouselLite({btnNext: '.hp-logged-in-carousel-next',btnPrev: '.hp-logged-in-carousel-prev',mouseWheel: false,visible: 3});");
			}
			$(".header-logged-out").hide();
			$(".header-logged-in").show();
		}
		
		$(".calage").html(this.actual_age);
		$(".realage").html(this.real_age);
		$(".difference").html(this.age_diff);
		
		if (this.taken_dt == null) {
			$(".taken").hide();
		} else {
			$(".taken").html("Taken " + this.taken_dt);
			$(".taken").show();
		}
	},
	/** end MY REALAGE **/	

	/** start RESULTS PAGE **/
	setPlanTemplateRealAge: function(calcRA) {
		// elements are raap_getplan.tmpl specific
		if (calcRA != null) {
			var real_age = raTest.getRoundedAge(calcRA);
			var actual_age = raTest.getRoundedAge(getCalAge(mag_user.birth_date));

			$(document).ready(function(){
				$("#result_inc").hide();
				if (real_age > actual_age) {
					$("#result_older").show();
				} else if (real_age < actual_age) {
					$("#result_younger").show();
				} else if (real_age == actual_age && real_age != "") {
					$("#result_same").show();
				}
				$("#calrealage").text(real_age);
				$("#planbar").show();
				
				// sync up MyRA with updated values 
				raTest.getMyRealAge();
						
			});
		}
	},
	setPlanRealAge: function() {
		if (this.complete == true) {
			raTest.getCalculatedRealAge("1",raTest.setPlanTemplateRealAge);
		}
	},
	/** end RESULTS PAGE **/
	
	/** start RESUME LOCATION IN TEST **/
	resumeLocation: function() {
		if (raap_raws.hasValidChildId() ) {
			// stored raTest complete value is only found if a "setTestComplete" call has already been made in session
			if (this.getComplete() == null)   {
				console.debug("COMPLETE_KEY not found, call raTest init processResumeLocation");
				// make first call of session to determine if test complete
				raTest.init(mod_ids,function(){raTest.processResumeLocation()});
			} else {
				console.debug("COMPLETE_KEY found, call processResumeLocation");
				this.processResumeLocation();
			}
		} else {
			this.clearResumeLocation_StoredValues();	
		}
	},
	processResumeLocation: function() {
		// at starting page of asmt, determine if test complete - if not, redirect to last location saved, if any
		// save page location in Fact on every page of test viewed until they get to results page	
		if (this.isMainTestVersion() && this.getComplete() == "false") {				
			if (this.resumeLastLocation() ) {
				//if qualified, will redirect from start of asmt to last page of visit if Fact value for page id found
				raap_raws.getFactValue(this.last_location_fact_id, function(){raTest.goToLastLocation(aValue)} );
			} else if (this.isFirstPageOfTest() ) {
				//prevent redirect when link back to start of test from mod tab
				RA.utils.storeData(this.RESUME_KEY, false);
				//no page id value stored for first page of test
				this.clearResumeLocation();
			} else {
				//store current RAAP page id in database Fact to persist for next visit
				var urlParam = RA.utils.getParameter("page_id");
				if (urlParam.length > 0) {
					raap_raws.setFactValue(this.last_location_fact_id, urlParam);
				}
			}
		}	
	},
	resumeLastLocation: function() {
		//return true if test taker meets criteria to redirect to last page visited		
		if (this.isFirstPageOfTest() ) {
			if (this.getComplete() == "false" && this.getResume() == null) {
				return true;
			} else {
				return false;
			}
		}
		return false;
	},
	goToLastLocation: function(locFactValue) {
		//only redirect if stored Fact value found
		//set resume key so won't redirect again at start of test in this session
		if (locFactValue != undefined && locFactValue.length > 0) {
			RA.utils.storeData(this.RESUME_KEY, true);
			var nextUrl = raTest.getLastLocationUrl(locFactValue);
			window.location.href = nextUrl;
		} else {
			RA.utils.storeData(this.RESUME_KEY, false);
		}
	},
	getLastLocationUrl: function(nextPgId) {
		var pageUrl = window.location.href;			
		if ( (nextPgId != undefined) && (nextPgId.length > 0) ) {		
			if (window.location.pathname.indexOf("realage-test")>=0) { 
				var urlParam = RA.utils.getParameter("page_id");
				if (urlParam.length > 0) {
					// querystring contains a "page_id" parameter - replace the value
					pageUrl = pageUrl.replace(urlParam, nextPgId);
				} else if (!urlParam) {
					// no querystring parameters - attach one
					pageUrl = pageUrl + "?page_id=" + nextPgId;
				} else {
					// add querystring name/value to existing parameters
					pageUrl = pageUrl + "&page_id" + nextPgId;
				}
			}			
		}		
		return pageUrl;
	},
	getFirstPgId: function(){
		//TODO - REMOVE THIS - pass value from article instead of hard-coding; won't need at all if page_id removed from RAAP tab for 1st mod
		var pgId = "108280";
		if (window.location.href.indexOf("betapreview.")>=0 || window.location.href.indexOf("alphapreview.")>=0 || window.location.href.indexOf("stage.")>=0) { 
			pgId = "37";
		}
		return pgId;
	},
	isFirstPageOfTest: function() {
		// live page 1 urls - http://www.realage.com/raap/realage-test || http://www.realage.com/raap/realage-test?page_id=108280
		// beta page 1 urls - http://betapreview.realage.com/raap/realage-test || http://betapreview.realage.com/raap/realage-test?page_id=37
		this.firstPgId = this.getFirstPgId();	//TODO - REMOVE - testing only - article/template will set
		if (window.location.pathname.indexOf("realage-test")>=0) { 
			var urlParam = RA.utils.getParameter("page_id");
			if (urlParam.length > 0 && urlParam == this.firstPgId) {
				return true;
			} else if (!urlParam) {
				// no page id - assume start of test
				return true;
			}
		}
		return false;
	},
	isMainTestVersion: function() {
		//exclude all non- "realage-test" urls like "http://www.realage.com/raap/realage-test-e"
		var re = new RegExp("realage-test$");
		return re.test(window.location.pathname);
	},
	getResume: function() {
		//read persisted value if available
		var resume = RA.utils.getData(this.RESUME_KEY);	
		if (!resume)  {
			resume = null;	
		}
		return resume;
	},
	clearResumeLocation: function() {
		//per requirements, stored location is cleared once results page is reached
		raap_raws.clearFactValue(this.last_location_fact_id);
	},
	clearResumeLocation_StoredValues: function() {
		//clear persisted values
		RA.utils.eraseData(this.RESUME_KEY);
	},
	/** end RESUME LOCATION IN TEST **/
	
	init: function(passed_mod_ids,passed_callback) {
		if (raap_raws.hasValidChildId() ) {
			this.child_id = raap_raws.getChildId();
		}
		this.mod_ids = passed_mod_ids;
		this.callback = passed_callback;
		this.setCompletedModules();
		return true;
	}
};
