/* mhc-common.js - Sosign Interactive Inc. - project: MyHealthCheckup.com (http://www.myhealthcheckup.com) - 20/03/2007	*/
/*
 * object: MHCCommon
 *
 * -> Core functions used by multiple objects and pages
 */
var MHCCommon = {
	
	/* object properties */
	logOutResource: "php/logout.php",
	PDFResource: "php/htmlToPDF.php",
	graphImageResource: "php/graphImage.php",
	emailResource: "php/sendEmail.php",
	forgotPasswordResource: "php/forgotPassword.php",
	menuDataModelResource: "php/menuDataModel.php",
	menuDataResource: "php/menuData.php?lang="+gMHCLanguage,
	userRolesResource: "php/userRoles.php",
	userDataResource: "php/userData.php",
	graphImageSent: false,
	
	/*
	 * method: getLanguage
	 *
	 * -> get page lang based on html and body attributes
	 */
	getLanguage: function() {
		var lang = document.documentElement.lang;
		lang = lang ? lang : "en";
		return lang;
	},
	
	/*
	 * method: addLangChangeEvent
	 *
	 * -> build allow to change language using the language selector
	 */
	addLangChangeEvent: function() {
	
		/* change value regarding lang set in url */
		var value = $("#langSelector").val();
		var lang = MHCCommon.getLanguage();
		var selectLang = lang ? lang : "en";
		
		$("#langSelector").val(selectLang);
		
		/* add a change event to change language */
		$("#langSelector").change(function(){
			var lang = $(this).val();
			var url = $("link[hreflang='"+lang+"']").attr("href");
			
			if(url) {
				if(window.location.search) {
					url += window.location.search;
				}
				window.location = url;
			}
			return true;
		});
		return true;
	},
	
	/*
	 * method: addCopyrightMessage
	 *
	 * -> add a copyright message at bottom of pages
	 */
	addCopyrightMessage: function() {
		var message = gMHCLangVars.copyrightBoxMessage;
		$("#gMHCCopyrightMessageContainer").html(message);
		return true;
	},
	
	/*
	 * method: addCvAgeBox
	 *
	 * ->  add a box containing cvAge
	 */
	 addPageTitle: function(pageTitleIndex) {
	 	$("<div></div>").insertBefore($("#logo"))
	 		.attr("id", "gMHCPageTitle")
	 		.html(gMHCLangVars.pageTitles[pageTitleIndex]);
	 	
	 	return true;
	 },
	
	/*
	 * method: getUrlVars
	 *
	 * -> parse variables from an URL
	 */
	getUrlVars: function(url) {
		var vars = [], hash;
		var hashes = url.slice(url.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;
	},
	
	/*
	 * method: idealWeight
	 *
	 * -> calculate ideal weight
	 */
	idealWeight: function(height) {
		var bounds = new Object();
		bounds["low"] = Math.round((18.5 * Math.pow((height / 100), 2)));
		bounds["high"] = Math.round((25.0 * Math.pow((height / 100), 2)));
		return bounds;
	},
	
	/*
	 * method: bmi
	 *
	 * -> calculate body mass index
	 */
	bmi: function(profileData) {
		result = Math.round(10 * (profileData["weight"] / Math.pow((profileData["height"]/100), 2))) / 10;
		return result;
	},
	
	/*
	 * method: changeSelectValue
	 *
	 * -> change a select element value
	 */
	changeSelectValue: function(fieldId, value) {
		$("select[id$='"+fieldId+"']").val(value);
		return true;
	},
	
	/*
	 * method: allPressureValues
	 *
	 *	-> return the systolic/dastolic in a same string
	 */
	allPressureValues: function(profileData) {
		return (profileData["systolic"].toString()+"/"+profileData["diastolic"].toString());
	},
	
	/*
	 * method: hdlRatio
	 *
	 * -> calculate total cholesterol / hdl cholesterol ratio
	 */
	hdlRatio: function(profileData){
		return (Math.round(100 * (parseFloat(profileData["totalCholesterol"]) / parseFloat(profileData["hdlCholesterol"]))) / 100);
	},
	
	/*
	 * method: moderateMets
	 *
	 * -> calculate mets for moderate exercise
	 */
	moderateMets: function(profileData){
		return parseInt(profileData["nbMinutesPerWeekModerate"]) * 4;
	},
	
	/*
	 * method: vigorousMets
	 *
	 * -> calculate mets for vigorous exercise
	 */
	vigorousMets: function(profileData){
		return parseInt(profileData["nbMinutesPerWeekVigorous"]) * 8;
	},
	
	/*
	 * method: convertSmokeValue
	 *
	 * -> replace choices numvers by human readable values
	 */
	convertSmokeValue: function(profileData) {
		return gMHCLangVars["smokingStatusValues"][profileData["smoke"]];
	},
	
	/*
	 * method: today
	 *
	 * -> return today's date formatted as YYYY-MM-DD or DD-MM-YYYY 
	 */
	today: function(format) {
		format = format ? format : "en";
		var today = new Date();
		var year = today.getFullYear();
		var month = (today.getMonth() + 1).toString().replace(/^([0-9])$/, "0$1");
		var day = (today.getDate()).toString().replace(/^([0-9])$/, "0$1");
		
		if(format == "en") {
			return year+"-"+month+"-"+day;
		
		} else {
			return day+"-"+month+"-"+year;
		}
	},
	
	/*
	 * method: addlogOutLink
	 *
	 * -> add a link to log out from server
	 */
	addlogOutLink: function(type) {
		if(typeof(gMHCLangVars) != "undefined") {
			var action;
			
			if(type) {
				action = "MHCCommon.logOut(null, '"+type+"');";
				
			} else {
				action = "MHCCommon.logOut();";
			}
			
			$("#topMenu").prepend(
				$("<span></span>").append(
					$("<a></a>")
						.attr("onclick", action)
						.attr("href", "javascript:void(0)")
						.html(gMHCLangVars.logOutLinkLabel)
				)
			);
		}
		return true;
	},
	
	getUserName: function() {
		var userName = "";
		$.ajax({
			url: "php/myaccountData.php?fields=firstName,lastName",
			type: 'get',
			async: false,
			dataType: "json",
			success: function(data) {
				userName = data["firstName"]+" "+data["lastName"];
				userName = userName.replace("undefined", "");
			}
		});
		return userName;
	},
	
	getHealthProfessionalUserName: function() {
		var userName = "";
		$.ajax({
			url: "php/myaccountData.php?type=professional&fields=firstName,lastName",
			type: 'get',
			async: false,
			dataType: "json",
			success: function(data) {
				userName = data["firstName"]+" "+data["lastName"];
				userName = userName.replace("undefined", "");
			}
		});
		return userName;
	},
	
	/*
	 * method: addloggedAsMessage
	 *
	 * -> add a message to display under which name user is logged in
	 */
	addloggedAsMessage: function() {
		
		if(!$("#userMenu").get(0) && !$("#professionalMenu").get(0)) {
			var retry = function(){ MHCCommon.addloggedAsMessage(); };
			window.setTimeout(retry, 100);
			
		} else if($("#professionalMenu").get(0) && $("#userMenu").get(0)) {
				var user = MHCCommon.getUserName();
				var pro = MHCCommon.getHealthProfessionalUserName();
				
				$("#topMenu").prepend(
					$("<span></span>").html(gMHCLangVars.loggedAsLinkLabel+pro)
				);
				
				$("<li class=\"loggedBox\">"+user+"</li>")
					.prependTo("#userMenu");

		} else if($("#professionalMenu").get(0) && !$("#userMenu").get(0)) {
			var pro = MHCCommon.getHealthProfessionalUserName();
			$("#topMenu").prepend(
				$("<span></span>").html(gMHCLangVars.loggedAsLinkLabel+pro)
			);
			
		} else if(!$("#professionalMenu").get(0) && $("#userMenu").get(0)) {
			var user = MHCCommon.getUserName();
			$("#topMenu").prepend(
				$("<span></span>").html(gMHCLangVars.loggedAsLinkLabel+user)
			);
		}
		return true;
	},
	
	/*
	 * method: logout
	 *
	 * -> logout out from server (destroy current session)
	 */
	logOut: function(noRedirect, type) {
		
		var resource = this.logOutResource;
		
		if(type) {
			resource += "?type="+type;
		}
		
		/* get units data */
		$.ajax({
			url: resource,
			type: 'get',
			async: false,
			dataType: "json",
			success: function(response) {
			
				if(response["authenticated"] == "0") {
					
					/* logout on other domain */
					var dataObj = {"type":type};
					var domain = MHCCommon.getOtherDomain();
					
					if(domain) {
						MHCCommon.xRequest(
							"get",	
							"http://"+domain+"/"+resource, 
							dataObj,
							function(){
								if(noRedirect != true) {
									window.location = "index."+gMHCLanguage+".html";
								}
							});
					}
				}
			}
		});
		
		return false;
	},
	
	/*
	 * method: extractFields
	 *
	 * -> parse field names from a data model (used to request data by field name)
	 */
	extractFields: function(dataModel) {
	
		/* extract field list needed by dataModel */
		var fields = new Array();
		
		$.each(dataModel, function(i, value) {
			if(value["value"]) {
				$.each(value["value"], function(y, subValue){
					fields.push(y);
				});
			
			} else {
				fields.push(i);
			}
		});
		
		return fields.join(",");
	},
	
	/*
	 * method: addExplanationsButton
	 *
	 * -> add a addExplanationsButton button to download a pdf document explaining the page content
	 */
	addExplanationsButton: function(container, type) {
		container = "#"+container;
		var label = gMHCLangVars.explanationsButtonLabels[type];
		var fileName;
		
		switch(type) {
			case "profile":
				fileName = "pdf/Explanations_Profile_"+gMHCLanguage+".pdf";
				break;
				
			case "compareprofiles":
				fileName = "pdf/Explanations_Compareprofiles_"+gMHCLanguage+".pdf";
				break;
				
			case "history":
				fileName = "pdf/Explanations_History_"+gMHCLanguage+".pdf";
				break;
				
			case "diabetes":
				fileName = "pdf/Explanations_Diabetes_"+gMHCLanguage+".pdf";
				break;
		}
		
		$("<input type=\"button\" id=\"gMHCExplanationsButton\"/>")
			.appendTo($(container))
			.val(label)
			.click(function(){
				window.open(fileName, "gMHCExplanations");
			});
		return false;
	},
	
	/*
	 * method: addPDFButton
	 *
	 * -> add a "save as pdf" button to return a pdf document based on page content
	 */
	addPDFButton: function(container, fileName) {
		container = "#"+container;
		
		$("<form onsubmit=\"return MHCCommon.beforePDFSubmit(this);\"></form>")
			.appendTo($(container))
			.attr("action", MHCCommon.PDFResource)
			.attr("method", "post")
			.append(
				$("<input type=\"hidden\" name=\"gMHCHtmlMainContent\" id=\"gMHCHtmlMainContent\"/>")
			).append(
				$("<input type=\"hidden\" name=\"gMHCPDFFileName\"/>")
					.val(fileName)
					
			).append(
				$("<input type=\"submit\" id=\"gMHCSaveAsPDF\"/>")
					.val(gMHCLangVars.saveAsPDFButtonLabel)
					.each(function(){this.disabled = true; this.setAttribute("disabled", "disabled");})
					
			);
		return true;
	},
	
	/*
	 * method: addPrintButton
	 *
	 * -> add a "print" button to print page
	 */
	addPrintButton: function(container) {
		container = "#"+container;
		$("<input type=\"button\" id=\"gMHCPrintPage\" onclick=\"return MHCCommon.beforePrintPage();\"/>")
			.appendTo($(container))
			.val(gMHCLangVars.printPageButtonLabel)
			.each(function(){this.disabled = true; this.setAttribute("disabled", "disabled");})
			.before(
				$("<img src=\"img/loader.gif\" alt=\"\" id=\"gMHCPrintIndicator\" />").css({
					height: $("#gMHCPrintPage").height()
				})
			);
		return true;
	},
	
	/*
	 * method: addSendEmailButton
	 *
	 * -> add a "send email" button
	 */
	addSendEmailButton: function(container, fileName, userEmail, langObj) {

		container = "#"+container;
		$("<input type=\"button\" id=\"gMHCSendEmail\"/>")
			.appendTo($(container))
			.val(gMHCLangVars.sendEmailButtonLabel)
			.each(function(){this.disabled = true; this.setAttribute("disabled", "disabled");})
			.click(function(){
			
				$.scrollTo($("div[id$='GraphContainer']"));
				
				/* function to send email */
				var sendFunc = function(value, message){

				};
				
				/* function to check if email has been entered in form */
				var mysubmitfunc = function(v,m){
				      an = m.children('#gMHCEmailRecipient');
				      if(an.val() == ""){
				            an.css("border","solid #FF0000 1px");
				            return false;
				      
				      } else {
				      
						/* image is present */
						if($("#gMHCGraphImage").attr("src") != "" && $("#gMHCGraphImage").get(0) != undefined && $("#gMHCGraphImage").get(0) != null && $("#gMHCGraphImage").attr("src").toString() != "undefined" && $("#gMHCGraphImage").attr("src").toString() != "null") {
							MHCCommon.sendByEmail(v, m, fileName);
						
						/* image is not in DOM yet or its src attribute is undefined, wait until this is the case */
						} else {
							MHCCommon.sendByEmailValue = v;
							MHCCommon.sendByEmailMessage = m;
							MHCCommon.sendByEmailFilename = fileName;
							var timeoutId = window.setTimeout("MHCCommon.sendByEmail(MHCCommon.sendByEmailValue, MHCCommon.sendByEmailMessage);", 250);
						}
				      
				      	
				      	return true;
				      }
				};
				
				/* form to send email */
				var formHTML = '<h1>'+gMHCLangVars.sendEmailButtonLabel+'</h1>'
								+'<div>'
								+'<label for="gMHCEmailRecipient">'+gMHCLangVars.emailInputLabel+'</label> '
								+'<input type="text" id="gMHCEmailRecipient" name="gMHCEmailRecipient" value="'+(userEmail?userEmail:"")+'" />'
								+'</div>'
								+'<div>'
								+'<label for="gMHCEmailMessage">'+gMHCLangVars.commentsInputLabel+'</label>'
								+'<textarea id="gMHCEmailMessage" name="gMHCEmailMessage">'+(langObj?langObj.emailMessage:"")+'</textarea>'
								+'</div>';
				
				var buttonsObj = new Object();
				buttonsObj[gMHCLangVars.sendButtonLabel] = true;
				buttonsObj[gMHCLangVars.cancelButtonLabel] = null;
				
			 	$.prompt(formHTML,{
				      submit: mysubmitfunc,
				      buttons: buttonsObj,
				      prefix: "jqiEmail"
				});
			});
		return true;
	},
	
	/*
	 * method: sendByEmail
	 *
	 * -> send a PDF via email
	 */
	sendByEmail: function(value, message, fileName){
		
		/* email is set */
		if(value == true) {
		
			/* encode email address and text plain message */
			var recipient = encodeURIComponent(message.find('#gMHCEmailRecipient').val());
			var encodedMessage = encodeURIComponent(message.find('#gMHCEmailMessage').val());

			var tableContent = new String();
			
			/* create PDF structure regarding type of data */
			switch(fileName) {
				case "history":
					tableContent = MHCCommon.createPDFHistoryTable();
					break;
					
				case "compareprofiles":
					tableContent = MHCCommon.createPDFCompareProfilesTable();
					break;
					
				default:
					tableContent = MHCCommon.createPDFProfileTable();
					break;
			}
			
			var htmlContent = MHCCommon.buildHtmlContent(tableContent);
			
			/* encode to be JSON compatible */
			htmlContent = encodeURIComponent(htmlContent);
			var lang = MHCCommon.getLanguage() ? MHCCommon.getLanguage() : "en";
				
			$.ajax({
				url: MHCCommon.emailResource,
				type: "POST",
				async: true,
				data: "gMHCEmailRecipient="+recipient
						+"&gMHCEmailMessage="+encodedMessage
						+"&gMHCHtmlMainContent="+htmlContent
						+"&gMHCPDFFileName="+fileName
						+"&lang="+lang,
				dataType: "json",
				success: function(response) {
					
					/* error while sending email */
					if(response["emailSent"] == "false") {
						$.prompt(gMHCLangVars.messages.errorEmailNotSent);
					}
				},
				error: function(response) {
					
					/* the image was not ready, retry */
					if(response.status == 500) {
						MHCCommon.sendByEmailValue = value;
						MHCCommon.sendByEmailMessage = message;
						MHCCommon.sendByEmailFilename = fileName;
						var timeoutId = window.setTimeout("MHCCommon.sendByEmail(MHCCommon.sendByEmailValue, MHCCommon.sendByEmailMessage);", 250);
					
					} else {
						$.prompt(gMHCLangVars.messages.errorEmailNotSent);
					}
				}
			});
		}
		return true;
	},
	
	/*
	 * method: forgotPassword
	 *
	 * -> send an email to a user who have forgottten his password
	 */
	forgotPassword: function(accountType) {
		
		/* function to check if email has been entered in form */
		var mysubmitfunc = function(v,m){
		      an = m.children('#gMHCEmailRecipient');
		      
		      if(an.val() == ""){
		            an.css("border","solid #FF0000 1px");
		            return false;
		      
		      } else {
		      	MHCCommon.resetPassword(v,m);
		      	return true;
		      }
		};
		var formHTML = gMHCLangVars.forgotPasswordTitle+'<p><label for="gMHCEmailRecipient">'+gMHCLangVars.emailInputLabel+'</label> <input type="text" id="gMHCEmailRecipient" name="gMHCEmailRecipient" style="width:200px;margin-bottom:0px;" /></p>';
		formHTML += "<input type=\"hidden\" id=\"gMHCAccountType\" value=\""+accountType+"\"/>";
		
		var buttonsObj = new Object();
		buttonsObj[gMHCLangVars.sendButtonLabel] = true;
		buttonsObj[gMHCLangVars.cancelButtonLabel] = false;
		
		/* prompt user to retrieve his/her password */
	 	$.prompt(formHTML,{
		      submit: mysubmitfunc,
		      buttons: buttonsObj,
		      callBack: MHCCommon.resetPassword
		});
	},
	
	/*
	 * method: resetPassword
	 *
	 * -> reset a password - callback function for forgot password
	 */
	resetPassword: function(value, message) {
	
		if(value == true) {
			var recipient = encodeURIComponent(message.find('#gMHCEmailRecipient').val());
			var accountType = encodeURIComponent(message.find('#gMHCAccountType').val());
			
			var lang = MHCCommon.getLanguage();
			var lang = lang ? lang : "en";
				
			$.ajax({
				url: MHCCommon.forgotPasswordResource,
				type: "POST",
				async: false,
				data: "gMHCEmailRecipient="+recipient+"&gMHCAccountType="+accountType+"&lang="+lang,
				dataType: "json",
				success: function(response) {
					
					if(response["message"]) {
			   			gMHCModalWindow = new MHCModalWindow(gMHCLangVars["messages"][response["message"]], gMHCLangVars.closeButtonLabel);
					
					} else {
			   			gMHCModalWindow = new MHCModalWindow(gMHCLangVars["messages"][response["error"]], gMHCLangVars.closeButtonLabel);
					}
				}
			});
		}
	},
	/*
	 * method: addSignupButton
	 *
	 * -> add a signup button to a page
	 */
	addSignupButton: function(container) {
		container = "#"+container;
	
		$("<input type=\"button\" id=\"gMHCProfileSignupButton\"/>")
			.prependTo($(container))
			.val(gMHCLangVars.signupButtonLabel)
			.click(function(){
				window.location = "./signup."+gMHCLanguage+".html?type=tryit";
			});
		return true;
	},

	/*
	 * method: createPDFProfileTable
	 *
	 * -> create html structure to be interpreted by pdf generator
	 */
	createPDFProfileTable: function(isDiabetes) {
		var imgSrc = $("#gMHCProfileGraphContainer").find("img").attr("src");
		
		if(typeof(imgSrc) == "string") {
		
			/* remove no-cache variables */
			imgSrc = imgSrc.replace(/\?cache=.*/i,"");
			imgSrc = imgSrc.replace(/_[0-9]+/i,"");
			
			/* as the picture is jpeg, dompdf have to work on a local file */
			imgSrc = imgSrc.replace(/.*\/temp\//i,"temp/");
		}
		var logoSrc = (gMHCLanguage == "en") ? "img/my-health-checkup-white.jpg" : "img/my-health-checkup-"+gMHCLanguage+"-white.jpg";
		
		/* create table html structure and content */
		var table = new String();
		table += '<table id="logo">'
   				+'<tr>'
      			+'<td>'
      			+'<img width="360" height="70" src="'+logoSrc+'"/>'
      			+'</td>'
      			+'<td id="gMHCPageTitle">'
      			+$("#gMHCPageTitle").html()
      			+'</td>'
   				+'</tr>'
   				+'</table>'
   				+'<table>'
   				+'<tr id="gMHCProfileAccountContainer">'
  				+'<td id="gMHCProfileAccountLeftContainer">'
  				+$("#gMHCProfileAccountContainer").children(":first").html()
  				+'</td>'
      			+'<td id="gMHCProfileAccountRightContainer">'
      			+$("#gMHCProfileAccountContainer").children(":last").html()
      			+'</td>'
   				+'</tr>'
			  	+'<tr>'
			    +'<td id="gMHCStatusUserDataContainer">'
			    +$("#gMHCStatusUserDataContainer").html()
			    +'<div id="gMHCStatusUserDataCVAgeContainer">'
			    +$("#gMHCStatusUserDataCVAgeContainer").html()
			    +'</div>'
			    +'</td>'
			    +'<td id="gMHCProfileGraphContainer">'
			    +'<img src="'+imgSrc+'" />'
			    +'</td>'
			    +'</tr>'
   				+'<tr>'
     			+'<td colspan="2" id="gMHCProfileDefaultValuesMessageContainer">'
     			+$('#gMHCProfileDefaultValuesMessageContainer').html()
     			+'</td>'
   				+'</tr>'
   				+'<tr>'
     			+'<td colspan="2" id="gMHCProfileMessage1Container">'
     			+$('#gMHCProfileMessage1Container').html()
     			+'</td>'
   				+'</tr>'
			    +'<tr>'
			    +'<td colspan="2" id="gMHCProfileMessage2Container">'
			    +$('#gMHCProfileMessage2Container').html()
			    +'</td>'
			    +'</tr>';
			    
			    if($('#gMHCProfileMessage3Container').html() != "") {
				    table += '<tr>'
					    	+'<td colspan="2" id="gMHCProfileMessage3Container">'
				   	 		+$('#gMHCProfileMessage3Container').html()
					    	+'</td>'
					    	+'</tr>';
			    }	    
			    
			    table += '<tr>'
			    +'<td colspan="2" id="gMHCCopyrightMessageContainer">'
			    +$('#gMHCCopyrightMessageContainer').html()
			    +'<p>'+gMHCLangVars.clinemetricaCopyright+'</p>'
			    +'</td>'
			    +'</tr>'
				+'</table>';
		
		table = table.replace("null", "");
		
		if(gMHCPageName == "diabetes") {
			table = table.replace("gMHCProfileMessage3Container", "gMHCProfileMessage3ContainerDiabetes");
			table = table.replace("gMHCProfileMessage2Container", "gMHCProfileMessage2ContainerDiabetes");
		}

		return table;
	},

	/*
	 * method: createPDFCompareProfilesTable
	 *
	 * -> create html structure to be interpreted by pdf generator
	 */
	createPDFCompareProfilesTable: function() {
		var firstDateIndex = $("#gMHCCompareProfilesFormContainer").find("select:first").val();
		var lastDateIndex = $("#gMHCCompareProfilesFormContainer").find("select:last").val();
		
		var firstDate = $("#gMHCCompareProfilesFormContainer").find("select:first").find("option:selected").html();
		var lastDate = $("#gMHCCompareProfilesFormContainer").find("select:last").find("option:selected").html();
		
		var imgSrc = $("#gMHCCompareProfilesGraphContainer").find("img").attr("src");
		if(typeof(imgSrc) == "string") {
			imgSrc = imgSrc.replace(/\?cache=.*/i,"");
			imgSrc = imgSrc.replace(/_[0-9]+/i,"");
			
			/* as the picture is jpeg, dompdf have to work on a local file */
			imgSrc = imgSrc.replace(/.*\/temp\//i,"temp/");
		}
		
		var logoSrc = (gMHCLanguage == "en") ? "img/my-health-checkup-white.jpg" : "img/my-health-checkup-"+gMHCLanguage+"-white.jpg";
		
		/* create table html structure and content */
		var table = new String();
		table += '<table id="logo">'
   				+'<tr>'
   				+'<td>'
   				+'<img width="360" height="70" src="'+logoSrc+'"/>'
				+'</td>'
      			+'<td id="gMHCPageTitle">'
      			+$("#gMHCPageTitle").html()
      			+'</td>'
   				+'</tr>'
   				+'</table>'
   				+'<table>'
   				+'<tr id="gMHCProfileAccountContainer">'
   				+'<td id="gMHCProfileAccountLeftContainer">'
   				+$("#gMHCProfileAccountContainer").children(":first").html()
   				+'</td>'
   				+'<td id="gMHCProfileAccountRightContainer">'
   				+$("#gMHCProfileAccountContainer").children(":last").html()
   				+'</td>'
   				+'</tr>'
   				+'<tr>'
   				+'<td colspan="2" id="gMHCCompareProfilesFormContainer">'
   				+$("#gMHCCompareProfilesFormContainer").html()
   					.replace(/<select.*gMHCCompareProfilesProfileSelector1[^>]+>.*?<\/select>/i, '<span id="gMHCCompareProfilesProfileSelector1">'+firstDate+'</span>')
   					.replace(/<select.*gMHCCompareProfilesProfileSelector2[^>]+>.*?<\/select>/i, '<span id="gMHCCompareProfilesProfileSelector2">'+lastDate+'</span>')
   				+'</td>'
   				+'</tr>'
   				+'<tr>'
   				+'<td colspan="2" id="gMHCProfileDefaultValuesMessageContainer">'
   				+$("#gMHCCompareProfilesDefaultValuesMessageContainer").html()
   				+'</td>'
   				+'</tr>'
   				+'<tr>'
   				+'<td id="gMHCCompareProfilesChangesContainer">'
   				+$("#gMHCCompareProfilesChangesContainer").html()
   				+'</td>'
   				+'<td id="gMHCCompareProfilesGraphContainer">'
   				+'<img src="'+imgSrc+'"/>'
   				+'</td>'
   				+'</tr>'
   				+'<tr>'
   				+'<td colspan="2" id="gMHCCompareProfilesStatusContainer">'
   				+$("#gMHCCompareProfilesStatusContainer").html()
   				+'</td>'
   				+'</tr>'
			    +'<tr>'
			    +'<td colspan="2" id="gMHCCopyrightMessageContainer">'
			    +$('#gMHCCopyrightMessageContainer').html()
			    +'<p>'+gMHCLangVars.clinemetricaCopyright+'</p>'
			    +'</td>'
			    +'</tr>'
				+'</table>';
		
		return table;
	},
	
	/*
	 * method: createPDFHistoryTable
	 *
	 * -> create html structure to be interpreted by pdf generator
	 */
	createPDFHistoryTable: function() {
		var table = new String();
		
		var logoSrc = (gMHCLanguage == "en") ? "img/my-health-checkup-white.jpg" : "img/my-health-checkup-"+gMHCLanguage+"-white.jpg";
		
		var imgSrc = $("#gMHCHistoryGraphContainer").find("img").attr("src");
		
		if(typeof(imgSrc) == "string") {
			imgSrc = imgSrc.replace(/\?cache=.*/i,"");
			imgSrc = imgSrc.replace(/_[0-9]+/i,"");
			
			/* as the picture is jpeg, dompdf have to work on a local file */
			imgSrc = imgSrc.replace(/.*\/temp\//i,"temp/");
		}
		
		/* create table html structure and content */
		table += '<table id="logo">'
				+'<tr>'
		      	+'<td>'
		      	+'<img width="360" height="70" src="'+logoSrc+'"/>'
		      	+'</td>'
      			+'<td id="gMHCPageTitle">'
      			+$("#gMHCPageTitle").html()
      			+'</td>'
   				+'</tr>'
   				+'</table>'
   				+'<table>'
		   		+'<tr id="gMHCProfileAccountContainer">'
		      	+'<td id="gMHCProfileAccountLeftContainer">'
		      	+$("#gMHCProfileAccountContainer").children(":first").html()
		      	+'</td>'
		      	+'<td id="gMHCProfileAccountRightContainer">'
		      	+$("#gMHCProfileAccountContainer").children(":last").html()
		      	+'</td>'
		  		+'</tr>'
   				+'<tr>'
		      	+'<td colspan="2" id="gMHCHistoryFormContainer">'
		      	+$("#gMHCHistoryFormContainer").html()
		      	+'</td>'
	   			+'</tr>'
				+'<tr>'
				+'<td colspan="2" id="gMHCProfileDefaultValuesMessageContainer">'
   				+$("#gMHCHistoryDefaultValuesMessageContainer").html()
   				+'</td>'
   				+'</tr>'
		   		+'<tr>'
		      	+'<td colspan="2" id="gMHCHistoryGraphContainer">'
		      	+'<img src="'+imgSrc+'"/>'
		      	+'</td>'
		   		+'</tr>'
		   		+'<tr>'
		      	+'<td colspan="2" id="gMHCHistoryStatusContainer">'
		      	+$("#gMHCHistoryStatusContainer").html()
		      	+'</td>'
		   		+'</tr>'
			    +'<tr>'
			    +'<td colspan="2" id="gMHCCopyrightMessageContainer">'
			    +$('#gMHCCopyrightMessageContainer').html()
			    +'<p>'+gMHCLangVars.clinemetricaCopyright+'</p>'
			    +'</td>'
			    +'</tr>'
				+'</table>';
		return table;
	},
	
	/*
	 * method: updateHtmlContent
	 *
	 * -> update html content used by PDF generator
	 */
	updateHtmlContent: function(fileName) {
		var htmlContent; 
		var tableContent = new String();
		
		switch(fileName) {
			case "history":
				tableContent = MHCCommon.createPDFHistoryTable();
				break;
				
			case "compareprofiles":
				tableContent = MHCCommon.createPDFCompareProfilesTable();
				break;
				
			case "diabetes":
				tableContent = MHCCommon.createPDFProfileTable(true);
				
			default:
				tableContent = MHCCommon.createPDFProfileTable(false);
				break;
		}
		
		htmlContent = MHCCommon.buildHtmlContent(tableContent);
		$("#gMHCHtmlMainContent").val(htmlContent);
		return true;
	},
	
	/*
	 * method: buildHtmlContent
	 *
	 * -> put an html fragment in a valid html page
	 */
	buildHtmlContent: function(htmlFragment) {

		var htmlContent = '<html><head><style type="text/css">@import url("css/stylesheet-pdf.css");</style></head>'
						+'<body>'+htmlFragment+'</body></html>';
		
		/* clean HTML for MSIE browsers */
		if($.browser.msie) {
		
			/* remove JQuery attribute for IE */
			var patternJquery = / jquery[0-9]+="[0-9]+"/gi;
			htmlContent = htmlContent.replace(patternJquery, "");
			
			/* remove attributes used by form.prototype.js */
			var patternAttr = / (calculate|haveDefault|dataType|nodeIndex|compare)=\s*".*?"/gi;
			htmlContent = htmlContent.replace(patternAttr, "");
			
			/* add quotes to attributes (*/		
			var addQuotesPattern = /([a-zA-Z0-9_]+)=([a-zA-Z0-9_]+)/gi;
	
			var replacer = function(str, p1, p2, offset, s) {
				return p1+"=\""+p2.replace(/"/gi, "")+"\"";
			};
			htmlContent = htmlContent.replace(addQuotesPattern, replacer);
			
			/* remove new lines */
			htmlContent = htmlContent.replace(/[\r\n]+/gi, "");
		}
		return htmlContent;
	},
	
	/*
	 * method: beforePDFSubmit
	 *
	 * -> function executed just before html data for PDF generation is sent
	 */
	beforePDFSubmit: function(formObj) {
	
		/* scroll to graph to avoid FF bug (flash which are not visible are not loaded) */
		$.scrollTo($("div[id$='GraphContainer']"));
		
		if(!formObj) {
			formObj = MHCCommon.formObj;
		}
		
		/* start working indicator */
		gMHCWorkingIndicator.show();
		
		/* image is present, submit the data */
		if($("#gMHCGraphImage").get(0) != undefined && $("#gMHCGraphImage").get(0) != null) {
			MHCCommon.updateHtmlContent(gMHCPageName);
			gMHCWorkingIndicator.hide();
			$(formObj).submit();
			return true;
		
		/* image is not in DOM yet, wait until this is the case */
		} else {
			MHCCommon.formObj = formObj;
			var timeoutId = window.setTimeout("MHCCommon.beforePDFSubmit(MHCCommon.formObj)", 250);
			return false;
		}
	},
	
	/*
	 * method: beforePrintPage
	 *
	 * -> function executed just before the user can print the page
	 */
	beforePrintPage: function() {
	
		/* scroll to graph to avoid FF bug (flash which are not visible are not loaded) */
		$.scrollTo($("div[id$='GraphContainer']"));
		
		/* start working indicator */
		gMHCWorkingIndicator.show();
		
		/* image is present, print the page */
		if($("#gMHCGraphImage").get(0) != undefined && $("#gMHCGraphImage").get(0) != null && MHCCommon.graphImageSent == true) {
			gMHCWorkingIndicator.hide();
			window.print();
			return true;
		
		/* image is not in DOM yet, wait until this is the case */
		} else {
			var timeoutId = window.setTimeout("MHCCommon.beforePrintPage()", 250);
			return false;
		}
	},
	
	/*
	 * method: beforePagePrint
	 *
	 * -> wrapper for beforePrintPage - delayed the execution (IE only - no print event in firefox)
	 */
	beforePagePrint: function(e) {
		
		/* image is present */
		if($("#gMHCGraphImage").get(0) != undefined && $("#gMHCGraphImage").get(0) != null) {
			return true;
		
		/* image is not in DOM yet, wait until this is the case */
		} else {
			var timeoutId = window.setTimeout("MHCCommon.beforePagePrint()", 250);
			return false;
		}
	},
	
	/*
	 * method: setGraphImage
	 *
	 * -> Insert an image representation of a flash chart
	 */
	setGraphImage: function(bitmapData) {
		MHCCommon.graphImageSent = false;
		
		/* send image data to resource */
		$.ajax({
			url: MHCCommon.graphImageResource,
			type: "POST",
			global: false,
			cache: false,
			data: bitmapData+"&pageName="+gMHCPageName,
			
			/* resource sent a response */
			success: function(imageLink) {
				var imagePart = imageLink.toString().split(".");
				cachePrevent = new Date().getTime();
				imageLink = $.trim(imagePart[0]+"_"+cachePrevent+"."+imagePart[1])+"?cache="+cachePrevent;
				
				/* image already exists, replace it */
				if($("#gMHCGraphImage").get(0) != undefined && $("#gMHCGraphImage").get(0) != null) {
					var cloneEl = $("#gMHCGraphImage").clone(true);
					cloneEl.attr("src", $.trim(imageLink));
					$("#gMHCGraphImage").replaceWith(cloneEl);
					
				/* image doesn't exist, insert it */
				} else {
					$("<img src=\""+imageLink+"\" alt=\"\" />")
						.insertAfter($("#ie_chart"))
						.attr("id", "gMHCGraphImage");
				}
				
				/* image has been sent */
				MHCCommon.graphImageSent = true;
				
				/* re-enable buttons at top of page */
				$("#gMHCPrintPage, #gMHCSaveAsPDF, #gMHCSendEmail").removeAttr("disabled")
					.each(function(){
						this.disabled = false;
						$("#gMHCPrintIndicator").css("display", "none");
					});
			},
			
			/* unknown error */
			error: function(){}
		});
	},
	
	/*
	 * method: addMyAccountLink
	 *
	 * -> Add a link pointing to account informations
	 */
	addMyAccountLink: function() {
		if(typeof(gMHCLangVars) != "undefined") {
			if(!$("#userMenu").get(0) && !$("#professionalMenu").get(0)) {
				var retry = function(){ MHCCommon.addMyAccountLink(); };
				window.setTimeout(retry, 100);
				
			} else if(!$("#professionalMenu").get(0)) {
				$("#textSize").before(
					$("<a></a>").append(gMHCLangVars.myAccountLinkLabel)
						.attr("href", "myaccount."+gMHCLanguage+".html")
				);
			}
		}
	},
	
	/*
	 * method: addFontSizeSwitcher
	 *
	 * -> Add a control to allow font-size switching
	 */
	addFontSizeSwitcher: function() {
	
		if(typeof(gMHCLangVars) != "undefined") {
			$("#topMenu").append(
				$("<span></span>").append(gMHCLangVars.fontSizeLinkLabel)
					.append(
						$("<a></a>").attr("href", "javascript:MHCCommon.setActiveStyleSheet('smallfont')")
							.html("-")
					
					).append(
						"/"
						
					).append(
						$("<a></a>").attr("href", "javascript:MHCCommon.setActiveStyleSheet('bigfont')")
							.html("+")
					)
			);
		}
		return true;
	},

	/*
	 * method: setActiveStyleSheet
	 *
	 * -> switch between stylesheet present in page (used to increase/decrease font size)
	 */
	setActiveStyleSheet: function(title) {
		var i, a, main;
		for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
			if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")) {
				a.disabled = true;
				
				if(a.getAttribute("title") == title) {
					a.disabled = false;
				}
			}
		}
	},

	/*
	 * method: getActiveStyleSheet
	 *
	 * -> get current active stylesheet
	 */
	getActiveStyleSheet: function() {
		var i, a;
		for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
			if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title") && !a.disabled) {
				return a.getAttribute("title");
			}
		}
		return null;
	},
	
	/*
	 * method: getPreferredStyleSheet
	 *
	 * -> get the default stylesheet to use
	 */
	getPreferredStyleSheet: function() {
	  var i, a;
	  for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
	  
	    if(a.getAttribute("rel").indexOf("style") != -1
	       && a.getAttribute("rel").indexOf("alt") == -1
	       && a.getAttribute("title")
	       ) return a.getAttribute("title");
	  }
	  return null;
	},
	
	/*
	 * method: createCookie
	 *
	 * -> create a cookie
	 */
	createCookie: function(name,value,days) {
	  if (days) {
	    var date = new Date();
	    date.setTime(date.getTime()+(days*24*60*60*1000));
	    var expires = "; expires="+date.toGMTString();
	  }
	  else expires = "";
	  document.cookie = name+"="+value+expires+"; path=/";
	},
	
	/*
	 * method: readCookie
	 *
	 * -> retrieve a cookie value
	 */
	readCookie: function(name) {
	  var nameEQ = name + "=";
	  var ca = document.cookie.split(';');
	  
	  for(var i=0;i < ca.length;i++) {
	    var c = ca[i];
	    
	    while (c.charAt(0)==' ') {
	    	c = c.substring(1,c.length);
	    }
	    
	    if (c.indexOf(nameEQ) == 0) {
	    	return c.substring(nameEQ.length,c.length);
	    }
	  }
	  
	  /* cookie not found or with an empty value */
	  return null;
	},
	
	/*
	 * method: compareDates
	 *
	 * -> compare dates
	 */
	compareDates: function(expr) {
	 	var parsed = expr.split(" ");
	 	var firstDateArray = parsed[0].split("-");
	 	var secondDateArray = parsed[2].split("-");
	 	var first = new Date(firstDateArray[0], firstDateArray[1], firstDateArray[2]).getTime();
	 	var second = new Date(secondDateArray[0], secondDateArray[1], secondDateArray[2]).getTime();
	 	first = !isNaN(first) ? first : 0;
	 	second = !isNaN(second) ? second : 0;
	 	return eval("(first "+parsed[1]+" second)");
	},
	
	/*
	 * method: inchesToFeet
	 *
	 * -> convert inches into feet
	 */
	inchesToFeet: function(value) {
		value = Math.round(value);
		var inches = value % 12;
		var feet = (value - inches) / 12;
		
		return {"inches": inches, "feet": feet};
	},
	
	/*
	 * method: testChlValue
	 *
	 * -> test total cholesterol value against LDL cholesterol and HDL cholesterol
	 */
	testChlValue: function(self){
		var chl = parseFloat($("#"+self.prefix+"totalCholesterol").val());
		var hdl = parseFloat($("#"+self.prefix+"hdlCholesterol").val());
		var ldl = parseFloat($("#"+self.prefix+"ldlCholesterol").val());
		
		if(isNaN(ldl)) {
			ldl = 0;
		}
		
		if(isNaN(hdl)) {
			hdl = 0;
		}
		
		if(chl > (hdl + ldl)) {
			$("#"+self.prefix+"totalCholesterol").parent().find("[class='restrict']").remove();
			$("#"+self.prefix+"totalCholesterol").css("border", "1px #154E6B solid");
			$("#"+self.prefix+"hdlCholesterol").css("border", "1px #154E6B solid");
			$("#"+self.prefix+"ldlCholesterol").css("border", "1px #154E6B solid");
			return true;
		
		} else {
			$("#"+self.prefix+"totalCholesterol").parent().find("[class='restrict']").remove();
			$("#"+self.prefix+"totalCholesterol").parent().append(
				$("<span class=\"restrict\"></span>")
					.html(gMHCLangVars["chlTooLow"])
			);
			$("#"+self.prefix+"totalCholesterol").css("border", "1px #FF0000 solid");
			$("#"+self.prefix+"hdlCholesterol").css("border", "1px #FF0000 solid");
			$("#"+self.prefix+"ldlCholesterol").css("border", "1px #FF0000 solid");
			return null;
		}
	},
	
	/*
	 * method: testEmail()
	 *
	 * -> check for email match
	 */
	testEmail: function(self) {
		if(($("#"+self.prefix+"email").val() != $("#"+self.prefix+"confirmEmail").val()) && $("#"+self.prefix+"email").val() != "") {
			return "errorEmailMismatch";
			
		} else {
			return true;
		}
	},
	
	/*
	 * method: testEmailValid()
	 *
	 * -> email validation through regexp with a specific error messages
	 */
	testEmailValid: function(self) {
		var email = $("#"+self.prefix+"email").val();
		
		if(email.search(/^[a-zA-Z0-9_.]+@[a-zA-Z0-9_-]+\.[a-zA-Z.]{2,}$/) == (-1)) {
			return "errorEmailWrongFormat";
			
		} else {
			return true;
		}
	},
	
	/*
	 * method: testPassword()
	 *
	 * -> check for password match (password field)
	 */
	testPassword: function(self) {
		if(($("#"+self.prefix+"password").val() != $("#"+self.prefix+"retypePassword").val()) && $("#"+self.prefix+"password").val() != "") {
			return "errorPasswordMismatch";
			
		} else {
			return true;
		}
	},
	
	/*
	 * method: testNewPassword
	 *
	 * -> check for password match (new password field - confirmation field)
	 */
	testNewPassword: function(self) {
		if(($("#"+self.prefix+"newPassword").val() != $("#"+self.prefix+"retypeNewPassword").val()) && $("#"+self.prefix+"newPassword").val() != "") {
			return "errorPasswordMismatch";
			
		} else {
			return true;
		}
	},
	
	/*
	 * method: refreshMenu
	 *
	 * -> refresh menu
	 */
	refreshMenu: function() {
		var self = this;
		var profilesData = new Object();
		
		
		/* get profiles data */
		$.ajax({
			url: self.userDataResource+"?fields=profileId,creationDate",
			type: 'get',
			async: false,
			dataType: "json",
			success: function(responseObj) {
				
				if(responseObj["error"]) {
					return false;
					
				} else {
					profilesData = responseObj;
				}
			}
		});
		
		/* create new menu object */
		gMHCMenu = new MHCMenu(self.menuDataModelResource, self.menuDataResource, self.userRolesResource, profilesData)
		gMHCMenu.refresh();
		return true;
	},
	
	
	/*
	 * method: showTermsAndConditions
	 *
	 * -> display terms amd conditions in a modal window
	 */
	showTermsAndConditions: function() {
		var callbackFct = function(){ return;};
		
		if(typeof(gMHCModalWindow) != "undefined" && $.browser.msie) {
			gMHCModalWindow.setBackground();
			
			callbackFct = function(v,m){
				gMHCModalWindow.setForeground();
			};
		}
		
		/* prompt terms and condition in a modal window */
		$.prompt(gMHCLangVars["termsAndConditionsContent"], {
			prefix: "jqiSignup",
			focus: -1,
			callback: callbackFct
		});
	},
	
	/*
	 * method: isEmpty
	 *
	 * -> check if a value is empty
	 */
	isEmpty: function(value) {
		if(value == "" || value == undefined || value == null) {
			return true;
			
		} else { 
			return false;
		}
	},
	
	/*
	 * method: tryItSubmit
	 *
	 * -> try it form submit function
	 */
	tryItSubmit: function() {
		var ageInput = $("#gMHCTryItage");
		var heightInput = $("#gMHCTryItheight");
		var formEl = $("#gMHCHomeTryitContainer").find("form");
		var submit = true;
		var pattern = /^[0-9]+$/i;
		
		/* check age value */
		if(MHCCommon.isEmpty(ageInput.val())) {
			$(ageInput).css("border", "1px #FF0000 solid");
			submit = false;
		
		} else if(!ageInput.val().match(pattern)) {
			$(ageInput).css("border", "1px #FF0000 solid");
			submit = false;
			
		} else {
			$(this).css("border", "1px solid #154E6B");
		}
		
		/* check height value */
		if(heightInput.get(0)) {
			if(MHCCommon.isEmpty(heightInput.val())) {
				$(heightInput).css("border", "1px #FF0000 solid");
				submit = false;
			
			} else if(!heightInput.val().match(pattern)) {
				$(ageInput).css("border", "1px #FF0000 solid");
				submit = false;
				
			} else {
				$(this).css("border", "1px solid #154E6B");
			}
		}
		
		/* if a value is wrong, don't submit */
		if(!submit) {
			return false;
			
		} else {
			formEl.submit();
			return true
		}
	},
	
	/*
	 * method: addMyPlanPrintButton
	 *
	 * -> add a print button to myPlan pages
	 */
	addMyPlanPrintButton: function() {
		
		/* parse window location to see if the page is a myplan page */
		
		var urlArray = window.location.toString().split("/");
		var pageName = urlArray[urlArray.length-1];
		
		if(pageName.indexOf("myplan") != -1) {
			$("<div></div>").attr("id", "gMHCButtonsContainer")
				.append(
					$("<input type=\"button\"/>").attr("id", "gMHCPrintPage")
						.click(function(){
							window.print();
						}).val(gMHCLangVars.printPageButtonLabel)
						
				).insertBefore($("#gMHCContent"));
		}
		return true;
	},
	
	getOtherDomain: function() {
		if(gMHCDomains[0].indexOf(document.domain) == 0) {
			return gMHCDomains[1];
			
		} else if(gMHCDomains[1].indexOf(document.domain) == 0) {
			return gMHCDomains[0];
		
		} else {
			return false;
		}
	},
	
	xRequest: function(method, url, dataObj, callback) {
		try {
			var self = this;
			
			/* create unique id */
			var xid = "xPost_iframe_"+MHCCommon.randomId();
			
			/* create iframe */
			var iframeEl = $("<iframe name=\""+xid+"\" style=\"width:1px;height:1px;border:0px none;position:absolute;top:0;left:0;\"></iframe>")
							.appendTo("body");
			
			/* create form element */
			var formEl = $("<form method=\""+method+"\" target=\""+xid+"\" style=\"display:none;\" action=\""+url+"\"></form>")
							.appendTo("body");
			
			/* create inputs with dataObj values */
			$.each(dataObj,function(i,v){
				$("<input type=\"hidden\" name=\""+i+"\" value=\""+v+"\"/>").appendTo(formEl);
			});
			
			/* add event onload */
			iframeEl.load(function(){
				if(callback) {
					try {
					callback();
					} catch(e) {
						alert(e);
					}
					//window.setTimeout(function(){formEl.remove();iframeEl.remove();}, 1000);
				}
			});
			
			/* submit form */
			formEl.submit();
		} catch(e) {
			alert(e);
		}
	},
	
	
	/*
	 * method: md5
	 * -> convert a string to an hash using md5
	 *
	 */
	md5: function(string) {
	
	    function RotateLeft(lValue, iShiftBits) {
	        return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits));
	    }
	
	    function AddUnsigned(lX,lY) {
	        var lX4,lY4,lX8,lY8,lResult;
	        lX8 = (lX & 0x80000000);
	        lY8 = (lY & 0x80000000);
	        lX4 = (lX & 0x40000000);
	        lY4 = (lY & 0x40000000);
	        lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
	        
	        if(lX4 & lY4) {
	            return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
	        }
	        
	        if(lX4 | lY4) {
	        
	            if(lResult & 0x40000000) {
	                return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
	                
	            } else {
	                return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
	            }
	            
	        } else {
	            return (lResult ^ lX8 ^ lY8);
	        }
	     }
	
	    function F(x,y,z) { return (x & y) | ((~x) & z); }
	    function G(x,y,z) { return (x & z) | (y & (~z)); }
	    function H(x,y,z) { return (x ^ y ^ z); }
	    function I(x,y,z) { return (y ^ (x | (~z))); }
	
	    function FF(a,b,c,d,x,s,ac) {
	        a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
	        return AddUnsigned(RotateLeft(a, s), b);
	    };
	
	    function GG(a,b,c,d,x,s,ac) {
	        a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
	        return AddUnsigned(RotateLeft(a, s), b);
	    };
	
	    function HH(a,b,c,d,x,s,ac) {
	        a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
	        return AddUnsigned(RotateLeft(a, s), b);
	    };
	
	    function II(a,b,c,d,x,s,ac) {
	        a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
	        return AddUnsigned(RotateLeft(a, s), b);
	    };
	
	    function ConvertToWordArray(string) {
	        var lWordCount;
	        var lMessageLength = string.length;
	        var lNumberOfWords_temp1=lMessageLength + 8;
	        var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
	        var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
	        var lWordArray=Array(lNumberOfWords-1);
	        var lBytePosition = 0;
	        var lByteCount = 0;
	        
	        while(lByteCount < lMessageLength) {
	            lWordCount = (lByteCount-(lByteCount % 4))/4;
	            lBytePosition = (lByteCount % 4)*8;
	            lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<<lBytePosition));
	            lByteCount++;
	        }
	        lWordCount = (lByteCount-(lByteCount % 4))/4;
	        lBytePosition = (lByteCount % 4)*8;
	        lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
	        lWordArray[lNumberOfWords-2] = lMessageLength<<3;
	        lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
	        return lWordArray;
	    };
	
	    function WordToHex(lValue) {
	        var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;
	        
	        for(lCount = 0;lCount<=3;lCount++) {
	            lByte = (lValue>>>(lCount*8)) & 255;
	            WordToHexValue_temp = "0" + lByte.toString(16);
	            WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
	        }
	        return WordToHexValue;
	    };
	
	    function Utf8Encode(string) {
	        string = string.replace(/\r\n/g,"\n");
	        var utftext = "";
	
	        for(var n = 0; n < string.length; n++) {
	            var c = string.charCodeAt(n);
	
	            if(c < 128) {
	                utftext += String.fromCharCode(c);
	                
	            } else if((c > 127) && (c < 2048)) {
	                utftext += String.fromCharCode((c >> 6) | 192);
	                utftext += String.fromCharCode((c & 63) | 128);
	                
	            } else {
	                utftext += String.fromCharCode((c >> 12) | 224);
	                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
	                utftext += String.fromCharCode((c & 63) | 128);
	            }
	        }	
	        return utftext;
	    };
	
	    var x=Array();
	    var k,AA,BB,CC,DD,a,b,c,d;
	    var S11=7, S12=12, S13=17, S14=22;
	    var S21=5, S22=9 , S23=14, S24=20;
	    var S31=4, S32=11, S33=16, S34=23;
	    var S41=6, S42=10, S43=15, S44=21;
	
	    string = Utf8Encode(string);	
	    x = ConvertToWordArray(string);
	    a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
	
	    for(k=0;k<x.length;k+=16) {
	        AA=a; BB=b; CC=c; DD=d;
	        a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
	        d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
	        c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
	        b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
	        a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
	        d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
	        c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
	        b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
	        a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
	        d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
	        c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
	        b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
	        a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
	        d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
	        c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
	        b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
	        a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
	        d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
	        c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
	        b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
	        a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
	        d=GG(d,a,b,c,x[k+10],S22,0x2441453);
	        c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
	        b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
	        a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
	        d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
	        c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
	        b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
	        a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
	        d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
	        c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
	        b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
	        a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
	        d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
	        c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
	        b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
	        a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
	        d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
	        c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
	        b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
	        a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
	        d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
	        c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
	        b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
	        a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
	        d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
	        c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
	        b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
	        a=II(a,b,c,d,x[k+0], S41,0xF4292244);
	        d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
	        c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
	        b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
	        a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
	        d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
	        c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
	        b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
	        a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
	        d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
	        c=II(c,d,a,b,x[k+6], S43,0xA3014314);
	        b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
	        a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
	        d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
	        c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
	        b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
	        a=AddUnsigned(a,AA);
	        b=AddUnsigned(b,BB);
	        c=AddUnsigned(c,CC);
	        d=AddUnsigned(d,DD);
	    }
	    var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);
	    return temp.toLowerCase();
	},
	
	/*
	 * method: isVisible
	 *
	 * -> tell if the element is in the viewport
	 */
	isVisible: function(element) {
		var tCoords = {
			h: $(element).height(), 
			w: $(element).width(), 
			x: $(element).offset().left, 
			y: $(element).offset().top
		};
		
		var wInnerHeight = 0;
		var wInnerWidth = 0;
		
		if(window.innerWidth ) {
			wInnerWidth = window.innerWidth;
			wInnerHeight = window.innerHeight;
			
		} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
			wInnerWidth = document.documentElement.clientWidth;
			wInnerHeight = document.documentElement.clientHeight;
			
		} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
			wInnerWidth = document.body.clientWidth;
			wInnerHeight = document.body.clientHeight;
		}
		
		var wCoords = {
			h: wInnerHeight, 
			w: wInnerWidth, 
			x: $(window).scrollLeft(), 
			y: $(window).scrollTop()
		};

		var isVisibleX = (((tCoords.x + tCoords.w) > wCoords.x) && (tCoords.x < (wCoords.x + wCoords.w)));
		var isVisibleY = (((tCoords.y + tCoords.h) > wCoords.y) && (tCoords.y < (wCoords.y + wCoords.h)));
		
		return (isVisibleX && isVisibleY);
	},
	
	/*
	 * method: randomId
	 *
	 * -> generate a random value
	 */
	randomId: function(){
		return (Math.floor(Math.random()*100000)).toString();
	},
	
	/*
	 * method: onWindowLoad
	 *
	 * -> function to execute on window load
	 */
	onWindowLoad: function(event) {
		/* set language */
		MHCCommon.addLangChangeEvent();
		
		/* get possible domains */
		$.ajaxSetup({async:false});
		$.getJSON("php/domains.php", function(data){
			window.gMHCDomains = data;
			$.ajaxSetup({async:true});
		});
		
		/* set text size */
		var cookie = MHCCommon.readCookie("style");
		var title = cookie ? cookie : MHCCommon.getPreferredStyleSheet();
		MHCCommon.setActiveStyleSheet(title);
		
		/* refresh menu */
		MHCCommon.refreshMenu();
		MHCCommon.addMyAccountLink();
		
		/* add print button to myplan pages */
		MHCCommon.addMyPlanPrintButton();
	},
	
	/*
	 * method: onWindowUnload
	 *
	 * -> function to execute on window unload
	 */
	onWindowUnload: function(event) {
		var title = MHCCommon.getActiveStyleSheet();
  		MHCCommon.createCookie("style", title, 365);
	}
};

/* execute common tasks on page load */

/* W3C-Compliant case */
if(window.addEventListener) {
    window.addEventListener("load", MHCCommon.onWindowLoad, true);
    window.addEventListener("unload", MHCCommon.onWindowUnload, true);
   
/* other cases (eg: IE x.x browsers) */
} else {
	window.attachEvent("onload", MHCCommon.onWindowLoad);
	window.attachEvent("onunload", MHCCommon.onWindowUnload);
	
	/* onbeforeprint is IE-specific */
	window.onbeforeprint = MHCCommon.beforePagePrint;
}