// pageControls.js - Mondial Quote Engine for Downunder Insurance Ltd, helper code
function getCheckedValue(radioName) {
	var radioObj = document.getElementsByName(radioName);
	if(!radioObj)
		return "";
	var radioLength = radioObj.length;
	if(radioLength == undefined)
		if(radioObj.checked)
			return radioObj.value;
		else
			return "";
	for(var i = 0; i < radioLength; i++) {
		if(radioObj[i].checked) {
			return radioObj[i].value;
		}
	}
	return "";
}

//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------

var xinit = {
	dayArray : [5,10,17,24,35,45],
	monthArray : [2,3,4,5,6,7,8,9,10,11,12],
	currentPlanOption : null,
	currentDestination: null,
	currentTripType : null,
	dependents : 0, // used for building/destroying dependents...
	firstColumnWidth : 40, // default width percent for first column (text descriptor | blank) for policies, extra benefits and fixed benefits.
	webDbName : '',
	screen1NextClicked : false,
	effects : [],
	
	initialize : function()
	{
		xinit.webDbName = $('webDbName').value;
		xinit.maxAge = parseInt($('maxAge').value);
		xinit.minAge = parseInt($('minAge').value);
		xinit.childMaxAge = parseInt($('childMaxAge').value);
		xinit.benefits = $('benefitValues').value.evalJSON();
		xinit.extraBenefits = $('extraBenefitValues').value.evalJSON();
		xinit.linkExtensionsWithBenefits = $('linkExtensionsWithBenefits').value.evalJSON();
		// clears up after Firefox on F5 or goback -- otherwise can lead to JS crashes
		document.forms[1].reset();
		
		$('editEffects').hide();
		
		// load any extension configurations, create a separate xinit.xxx for each.
		$$('.extConfig').each(function(entry){
									   	xinit[entry.id] = entry.value.evalJSON();
									   	
									   });
		
		// populate extension select box values from xinit.effects-config[items] 
		xinit.EffectsConfig.items.each(function(entry){
												 	var opt = new Element('option',{'value':entry.name});
													opt.update(entry.name);
													//opt.text = entry.name;
													$('itemType').insert(opt);
												 // xinit.EffectsConfig.items.detect(function(item){return item.name=='Camera'})
												 // returns object where name == camera, to get it's value.
												 });
		
	},	

	
	end : null
}

//-----------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------
Event.observe(window, 'load', xinit.initialize);
//-----------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------
var maths = {
	round : function(val){
		var dec = 2;
		var result = Math.round(val*Math.pow(10,dec))/Math.pow(10,dec);
		if (parseFloat(result) - parseInt(result) == 0)
		{
			result = result + '' + '.00';	
		}
	
		
		return result;
	},
	
	addCommas : function(number){
	number += '';
	var x = number.split('.');
	var x1 = x[0];
	var x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}
	return x1 + x2;

	},
	
	convertBenefitValue : function(benefitValue,doubleMe){
		var output = null;
			switch(benefitValue)
			{
				case "0":
				  output = "-- --";
				  break;    
				case null:
				 output = "-- --";
				 break;
				 case "":
				 output = "-- --";
				 break;
				 case "unlimited":
				 output = "unlimited";
				 break;
				default:
					output = "$" + maths.tryDoubleBenefitValue(benefitValue,doubleMe);
				 break;
			}
		
		return output;	
	},
	
	tryDoubleBenefitValue : function(benefitValue,doubleMe){
		
		var asNumber = parseInt(benefitValue.replace(/[^0-9]/g, ''));
		// change to only double family, not duo:
		// if (doubleMe=="Yes" && (xinit.currentPlanOption == "Family" || xinit.currentPlanOption == "Duo"))
		if (doubleMe=="Yes" && xinit.currentPlanOption == "Family")
		{
			asNumber =asNumber * 2;
		}
		
		output = maths.addCommas(asNumber);
		
		return output;	
	}
}

//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------

var pageControls = {
	
	lastOpenedSectionHeaderQueryDropper : null,
	
	sectionHeaderQueryDropper : function(tripTypeHelp)
	// drops down help text for section heads
	{
		// temp the last dropper
		// var lastDropper = pageControls.lastOpenedSectionHeaderQueryDropper;
		/*
		if (lastDropper)
		{
			var lastDropperEl = document.getElementById(pageControls.lastOpenedSectionHeaderQueryDropper);
			lastDropperEl.style.display = "none";
			pageControls.lastOpenedSectionHeaderQueryDropper = null;
		}
		
		if (lastDropper != tripTypeHelp)
		{
		
			var thisHelper = document.getElementById(tripTypeHelp);
			if (thisHelper)
			{
				thisHelper.style.display = "block";
				
			}
			pageControls.lastOpenedSectionHeaderQueryDropper = tripTypeHelp;
		}
		*/
		var thisHelper = $(tripTypeHelp);
		if (thisHelper.style.display == "none")
		{
			thisHelper.style.display = "block";	
		}
		else{
			thisHelper.style.display = "none";	
		}
	
	},
	
	setDestinationAvailabilityChild : function(elementRef)
	{
		//var element = document.getElementsByName(elementRef);
		pageControls.setDestinationAvailability(elementRef);
		
		// clear any 'invalid' notifications...
		validation.clearExisting('screen1');
	},
	
	setDestinationAvailability : function(radioCheck)
	{
		var screenEl = $('screen1');
		
		if (radioCheck.value=='single')
		{
			screenEl.className = "displaySingle";
		}
		else
		{
			screenEl.className = "displayFrequent";
		}
		
		
	},
	populateScreen2 : function(tripType)
	// called from ajasRequests.getPolicies:success;
	// xinit.policies holds policy data:
	{
		// kill ajax indicators...
		// build display
		// moved initial display from here to before Ajax request, to make screen more 'responsive'...
		// 
		
		// BUILD Policy Info Boxes: get policies from xinit.policies;
		var policies = "";
		
		// calculate column widths for tables...
		var firstColumnWidth = xinit.firstColumnWidth; //40;// percentage width of first column
		var remainingColumnsWidth = 100-firstColumnWidth; // ideally should be wholly divisible by 2 and 3 (and 4)
		var columns = xinit.policies.length +1;
		var columnWidth = (remainingColumnsWidth/xinit.policies.length).toFixed(2);
		
		
		var policyTable = new Element('table',{'id':'policyTable','class':'pt','width':'100%','cellpadding':'0','cellspacing':'0','border':'0'});
		$('screen2Policies').update(policyTable);
		
		
		
		var tableRow = '<tr><td width="' + firstColumnWidth + '%">&nbsp;</td>';
		
		
		
		xinit.policies.each(function(item,index)
									 {
										 var policyDiv = '<div id="policy-' + item.policy.refName + '" class="policyColumn">';
										 policyDiv += '<strong>' + item.policy.name + '</strong>';
										 
										 var policyBasePrice = '<div id="policy-base-' + item.policy.refName + '" class="policyColumnPrice">';
										 policyBasePrice += '$' + (parseFloat(item.policy.calculatedBase).toFixed(2));
										 policyBasePrice += '</div>';
										 
										 var policyDebug = '<div id="policy-debug-' + item.policy.refName + '"></div>';
										 
										 var policyQuote = '<div class="quoteMe"><a onclick="pageControls.populateScreen3(this,\'' + item.policy.refName +'\',\'' + index +'\');" href="Javascript:;">Select ></a></div>';
										 
										tableRow += '<td width="' + columnWidth + '%" valign="top">';
										tableRow += policyDiv + policyBasePrice + policyDebug + policyQuote + '</div>';
										tableRow += '</td>';
									 }
							)
		tableRow += '</tr>';
		policyTable.insert(tableRow);
		// Build Default Benefits Table
		// handle widths in CSS
		var benefitTable = new Element('table',{'id':'benefitTable','class':'bc','width':'100%','cellpadding':'0','cellspacing':'0','border':'0'});
		var benefitTableHolder = new Element('div',{'id':'benefitTableHolder','class':'smallTitle'}).update("<h3>Policy Sections & Benefits</h3>");
		//var tbody = new Element('tbody');
		//benefitTable.insert(tbody);
		$('screen2Policies').insert(benefitTableHolder);
		$('screen2Policies').insert(benefitTable);
		
		// if Duop, display note about benefits:
		if (xinit.currentPlanOption == "Duo") {
			$('screen2Policies').insert('<div style="font-size: 0.9em; font-style: italic"><strong>Note:</strong> Duo Cover &mdash; Single Cover benefits apply per insured person.</div>');
		}
			// benefit table footer:
			$('screen2Policies').insert('<div style="font-size: 0.9em; font-style: italic"><p>* sub-limits apply<br/># These sections are available under separate cover packages - see Additional Options<br/>++ The Maximum Benefit Limit for this Section can be increased by paying an additional premium - see Additional Options</p></div>');
			
			
		
		// header:
		var tableHeader = '<tr><td class="benefitTableHeaderEmpty" width="'+firstColumnWidth+'%"> </td><td class="benefitTableHeaderCell" colspan="' + columns + '" width="' + remainingColumnsWidth + '%">Maximum Benefit Limits</td></tr>';
		$('benefitTable').insert(tableHeader);
		
		
		var benefitType = (xinit.currentDestination=="Domestic" ? "domestic" : "international");
		
		// loop thru 'xinit.extensions', this gives us ROWS, then in each row, retrieve the appropriate policy[columns]
		// if all columns are empty, DON'T DISPLAY ROW
		// added count as index doesn't work as can be 'empty'
		var count = 0;
		xinit.benefits.each(function(benefit,index)
									{
										
										var tableRow = '<tr class="'+(count%2?"odd":"even")+'"><td width="' + firstColumnWidth + '%" class="extensionName" onclick="tableLogic.benefitDropRow(this,\'' + index + '\',' + columns + ');">';
										var notEmpty = false;
										tableRow += benefit.benefit.name + '</td>';
										xinit.policies.each(function(item,pindex){
															 tableRow += '<td  class="'+(pindex%2?"podd":"peven")+'" width="' + columnWidth + '%" valign="top">';
															 if (typeof(item.policy.benefits)!="undefined" && typeof(benefit.benefit) != undefined && typeof(item.policy.benefits[benefit.benefit.id]) != "undefined" && item.policy.benefits[benefit.benefit.id].extensionOnly == "No" )
															 {
															 	var benefitValue = item.policy.benefits[benefit.benefit.id][benefitType];
																var doubleMe =  item.policy.benefits[benefit.benefit.id].doubleMe;
																tableRow += maths.convertBenefitValue(benefitValue,doubleMe);
																notEmpty = true;
															 }
															 else 
															 {
																 tableRow += '-----';
															 }
															 tableRow += '</td>';
														 });
										
										
										
										tableRow += '</tr>';
										
										// only update row if there is content...
										
										if (notEmpty){count++; $('benefitTable').insert(tableRow);}
									}
							)
			//Re-trigger extensions, incase navigating...
			// if we've changed to Single, kill the 2nd pe cover
			if (xinit.currentPlanOption=="Single" && $('checkExt-PE-2') && $('checkExt-PE-2').checked) $('checkExt-PE-2').checked=false;
			// if Domestic, deactiate any checked excess (should be hidden already)
			if (xinit.currentDestination=="Domestic" && $('checkExt-Excess') && $('checkExt-Excess').checked) $('checkExt-Excess').checked=false;
			
			// load any benefit tables: only when navigationg, otherwise there won't be any checked...
			$A(document.getElementsByName('addExtensions')).each(function(extension){
											if (extension.checked){	
												var extName = extension.value;
												if (extName == "Effects"){
													// effects extension ticked, and we're navigating back here from screen 1
													// test whether stored effects exceed the limit for single policy
													// they *may* have been stored by the family/duo higher limit policy types, and have too high values.
													// action: blank for now.
													var multi = 1;
													if (xinit.currentPlanOption=="Duo" || xinit.currentPlanOption=="Family") multi = 2;
													if (xinit.effects && xinit.effects.total && xinit.effects.total > (multi * xinit.EffectsConfig.total)){
														extension.checked = false;
														xinit.effects = [];
														benefitLogic.removeExtensionBenefit(extName);
													}
												}
												// untick if extension is ticked, and doesn't apply (AFT | single trrip)
												var extensionTripType = extension.parentNode.parentNode.className;
												if (extensionTripType.toLowerCase().indexOf(xinit.currentTripType) == -1 && extensionTripType.indexOf('Both') == -1) {
													extension.checked = false;
												}
												else {
													benefitLogic.addExtensionBenefit(extName);
												}
											
											}
											});
		
			
			
			// recalc / add extensions to the policies
		policyLogic.addExtensions();	
		// highlight updated prices:
		$$(".policyColumn:not(.unavailable)").each(function(element){new Effect.Highlight(element)});

	},
	
	populateScreen3 : function(clickedEl,policyName,index)
	// called from [Select>] button in policy box.
	{
		// if inactive policy clicked, do nothing...
		if (clickedEl.parentNode.parentNode.className.indexOf('unavailable') !=-1) return false;
		// can proceed with valid policy:
		
		// kill screen 2
		$('screen2').style.display = "none";
		
		// and set classes?
		$('screen3').className = "details-" + xinit.currentPlanOption + " " + xinit.currentTripType;
		
		// and go Screen 3:
		$('screen3').style.display = "block";
		
		
		var extensionText = "";
		xinit.extensions = [];
		$A(document.getElementsByName('addExtensions')).each(function(extension){
											if (extension.checked){
												xinit.extensions.push(extension.value);
												var extRef = "ext-" + extension.value;
												var extName = $(extRef).cells[1].innerHTML;
												extensionText += "<li>" + extName +  "</li>";
											}
										});
		
		// CARRY POLICY TOTAL PRICE:
		//var policyTotal = $('policy-debug-' + policyName).innerHTML.split('Total: ')[1];
		var policyTotal = xinit.policies[index].policy.policyCost;
		xinit.policySelected = xinit.policies[index].policy.name;
		xinit.policySelectedRef = xinit.policies[index].policy.refName;
		xinit.policyCost = xinit.policies[index].policy.policyCost;
		
		// update policy Summary on screen3
		var amend = '<div style="text-align: center; margin-top: 10px; clear: both"><a class="navButton" href="Javascript:;" onclick="pageControls.backToScreen2();" title="Click to amend your chosen policy or to add extensions.">Amend</a></div>';
		var policySelected = '<div class="summaryRow"><strong>Policy Selected:</strong><span>' + xinit.policySelected + '</span></div>';
		
		$('screen3PolicySummaryInner').update($('policySummaryInner').innerHTML + policySelected + "<div class=\"summaryPrice\">Total: $" + policyTotal + "</div>" + (extensionText!=""?"<h3>Additional Options Selected:</h3><ul>" + extensionText + "</ul>" : "") + amend);
		
			
		// dep on number of adults, and whether pe or pe2 active, control pe input behavior:
		// need 2 radios and 2 input fields, class of hidden
		// 1 adult, 1 pe, no (hide) radios, pe1 uhidden
		// 2 adults, 1 pe -- show radios, both pes hidden. Activating radio, activates pe input and hides other (and blanks?)
		// 2 adults, 2 pes -- hide radios, show both inputs.
		// radios: #peAssignTo1 and peAssignTo2
		// inputs: #peApplicant1 and peApplicant2
		
		// init: hide everything:
		$('peAssignTo1','peAssignTo2','peApplicant1','peApplicant2').invoke('hide');
		
		var pes = xinit.extensions.findAll(function(n) { return n.indexOf('PE') != -1; });
		
		if (pes.length == 1 && xinit.currentPlanOption=="Single")
		{
			// 1 pes, 1 adult:	show full controls for 1 adult
			$('peApplicant1').show();
		}
		
		if (pes.length == 1 && (xinit.currentPlanOption=="Duo" || xinit.currentPlanOption=="Family"))
		{
			// 2 pes, 2 adults:	show full controls
			$('peAssignTo1','peAssignTo2').invoke('show');
		}
		
		if (pes.length == 2 && (xinit.currentPlanOption=="Duo" || xinit.currentPlanOption=="Family"))
		{
			// 2 pes, 2 adults:	
			$('peApplicant1','peApplicant2').invoke('show');
		}
		
		// already ticked?
		if ($('mondial_QE_peRadio1').checked) $('peApplicant1').show();
		if ($('mondial_QE_peRadio2').checked) $('peApplicant2').show();
		
		// clear any existing validation fields on SCREEN 3
		validation.clearExisting('screen3');
		
	},
	
	populateScreen4 : function()
	// from Next button on screen 3, if valid:
	{
		// kill screen 3
		$('screen3').style.display = "none";
		
		// and set classes?
		$('screen4').className = "details-" + xinit.currentPlanOption;
		
		// and go Screen 4:
		$('screen4').style.display = "block";
		// present summary of data and policy, with price, request confirmation, then to backend build & pay
		
		// glue fieldlists depending on adults, dependents, etc.
		
		
		// policy:
		
		var extensionText = "";
		$A(document.getElementsByName('addExtensions')).each(function(extension){
											if (extension.checked){
												var extRef = "ext-" + extension.value;
												var extName = $(extRef).cells[1].innerHTML;
												extensionText += "<li>" + extName +  "</li>";
											}
										});
		
		// CARRY POLICY TOTAL PRICE:
		//var policyTotal = $('policy-debug-' + xinit.policySelectedRef).innerHTML.split('Total: ')[1];
		// and build
		var policyTotal = xinit.policyCost;
		var policySummary = $('policySummaryInner').innerHTML;
		//$('policyDetailsSummary').update(policySummary);
		//$('policyDetailsSummary').insert('<div class="summaryRow"><strong>Policy Selected:</strong><span>' + xinit.policySelected + '</span></div>');
		//$('policyDetailsSummary').insert('<div class="summaryRow"><strong>Extensions Chosen:</strong><span>' + extensionText + '</span></div>');
		//$('policyDetailsSummary').insert('<div class="summaryRow finalCost"><strong>Total Cost:</strong><span>' + policyTotal + '</span></div>');
		
		var policySummaryHeader = '<div class="sectionHeader"><h2>Policy Details:</h2></div><div id="policyDetailsSummary" class="detailsSummary">';
		var policySelected = '<div class="summaryRow"><strong>Policy Selected:</strong><span>' + xinit.policySelected + '</span></div>';
		var extensionSummary = '<div class="summaryRow"><strong>Additional Options:</strong><span>' + (extensionText!="" ? extensionText : "None") + '</span></div>';
		var policyTotalSummary = '<div class="summaryRow finalCost">Total Cost: $' + policyTotal + '</div>';
		
		var amend = '<div style="text-align: center; padding: 10px; clear: both; border-top: 1px solid #ccc"><a class="navButton" href="Javascript:;" onclick="pageControls.backToScreen2from4();" title="Click to amend your chosen policy or to add extensions.">Amend Policy</a></div>';
		
		var policyCell = '<td width="50%" valign="top">' + policySummaryHeader + policySummary +policySelected+ extensionSummary  + '</div></td>';		
		
		
		// address block....
		var addressSummaryHeader = '<div class="sectionHeader"><h2>Applicant Details:</h2></div><div id="applicantDetailsSummary" class="detailsSummary">';
		var adults = 1;
		var dependents = false;
		switch(xinit.currentPlanOption)
		{
			case "Single":
				adults=1;
				dependents=true;
			break;    
			case "Duo":
			 	adults=2;
				dependents=false;
			break;
			case "Family":
			 	adults=2;
				dependents=true;
			break;	 
		}
		var AFT = false;
		if (xinit.currentTripType == 'frequent') {AFT = true; dependents=true};
		
		
		var addressFields = ((adults==2 || AFT) ? 'First ' : '') + 'Applicant: ' + $F('mondial_QE_title1') + ' ' + $F('mondial_QE_firstName1') + ' ' + $F('mondial_QE_lastName1') + ',';
		addressFields += 'Date of Birth: ' + $F('mondial_QE_dob1') + ',';
		// AFT ADDON
		if (adults==2 || (AFT==true && $F('mondial_QE_firstName2') !="" && $F('mondial_QE_lastName2') !="")){
			addressFields += 'Second Applicant: ' + $F('mondial_QE_title2') + ' ' + $F('mondial_QE_firstName2') + ' ' + $F('mondial_QE_lastName2') + ',';
			addressFields += 'Date of Birth: ' + $F('mondial_QE_dob2') + ',';	
		}
		
		if (dependents){
			numberDependents = $F('mondial_QE_dependents');
			for (var i=1; i<=numberDependents;i++)
			{
				addressFields += 'Dependent ' + i + ': ' + $F('mondial_QE_dep' + i + 'title') + ' ' + $F('mondial_QE_dep' + i + 'firstName') + ' ' + $F('mondial_QE_dep' + i + 'lastName');
				addressFields += ' (born ' + $F('mondial_QE_dep' + i + 'dob') + ').,';	
			}
		}
		
		addressFields += 'Telephone: ' + $F('mondial_QE_telephone1') + ' ' + $F('mondial_QE_telephone2') + ',';
		
		if ($F('mondial_QE_mobile') != ''){
			addressFields += 'Mobile: ' + $F('mondial_QE_mobile') + ',';
		}
		
		addressFields += 'Email: ' + $F('mondial_QE_email') + ',';
		
		addressFields += 'Address: ' + $F('mondial_QE_address1') + ($F('mondial_QE_address2')!='' ? ' ' + $F('mondial_QE_address2') : '');
		addressFields += '<br/>' + $F('mondial_QE_city') + ' ' + $F('mondial_QE_province') + '<br/>' +  $F('mondial_QE_postCode') ;
		
		
		// parse addressFields:
		var addressArray = addressFields.split(',');
		var addressParsed = "";
		addressArray.each(function(entry){
								   		var parts = entry.split(':');
										addressParsed += '<div class="summaryRow"><strong>' + parts[0] + ':</strong>';
										addressParsed += '<span>' + parts[1] + '</span></div>';
								   
								   });
		
		
		var addressAmend = '<div style="text-align: center; padding: 10px; clear: both; border-top: 1px solid #ccc"><a class="navButton" href="Javascript:;" onclick="pageControls.backToScreen3();" title="Click to amend the applicant details.">Amend Applicant Details</a></div>';
		var addressCell = '<td width="50%" valign="top">' + addressSummaryHeader + addressParsed + '</td>';
		
		var summaryTable = '<table width="100%" cellpadding="0" cellspacing="0" border="0"><tbody><tr>' + policyCell + addressCell + '</tr>';
		summaryTable += '<tr><td>' + amend + '</td><td>' + addressAmend + '</td></tr>';
		summaryTable += '<tr><td class="detailsSummary">' + policyTotalSummary  + '</td><td class="detailsSummary"><div class="finalCost">&nbsp;</div></td></tr>';
		summaryTable += '</tbody></table>';
		// and insert...(replace)
		$('detailsSummaries').update(summaryTable);
		
	},
	
	activatePE : function(radio,blankThis)
	// PE cover extension, show appropriate extension controls...
	{
		$('peApplicant1','peApplicant2').invoke('hide');
		// 
		if (radio.checked){
			$(radio.value).show();	
			$(blankThis).value="";
		}
		
	},
	
	addExtension : function(element)
	// called from extension checkboxes....
	// clear if already checked....
	{
		if (xinit.policies.length == 0) {
			element.checked = false;
			return false;
		}
		// add/remove functionality combined into add function:
		//policyLogic.addExtension(element.value);
		policyLogic.addExtensions();
		
		if (element.checked)
		{
			// BRANCH for 'special case' Personal Effects Cover
			if (element.value == "Effects"){
				windowing.displayWindow();
				$('editEffects').show();
			}
				// display benefit tables anyway
				benefitLogic.addExtensionBenefit(element.value);
			
		}
		else
		{
			benefitLogic.removeExtensionBenefit(element.value);
			if (element.value == "Effects"){
				$('editEffects').hide();
			}
			
		}
		
		// and highlight (available) policies:
		$$(".policyColumn:not(.unavailable)").each(function(element){new Effect.Highlight(element,{ queue: { position: 'end', scope: element.id,
limit: 1 },afterFinish:pageControls.cleanUpAfterAnim })})
	},
	
	cleanUpAfterAnim : function()
	{
		$$(".policyColumn:not(.unavailable)").each(function(element){element.style.backgroundColor = '#ffffff';});
	},
	
	buildDependents : function(numOfDependents)
	{
		numOfDependents = parseInt(numOfDependents);
		if (numOfDependents < xinit.dependents)
		{
			pageControls.cullDependents(numOfDependents+1);	
		}
		else if (numOfDependents > xinit.dependents)
		{
			for (var i=xinit.dependents+1;i<numOfDependents+1;i++)
			{
				if (!$('dep-' + i))	$('dependents').insert(pageControls.getDependent(i));
				
			}
		}
			xinit.dependents = numOfDependents;
		
	},
	
	getDependent : function(n)
	{
		var depCode ='<div class="inputRow" id="dep-' + n + '">	<label class="desc"></label><span style="font-size: 1.2em; width: 25px">' + n + '.</span><span><select class="field text" name="mondial_QE_dep' + n + 'title" id="mondial_QE_dep' + n + 'title"><option value="Mr">Mr</option><option value="Mrs">Mrs</option><option value="Ms">Ms</option><option value="Miss">Miss</option><option value="Dr">Dr</option><option value="Master">Master</option></select><label for="mondial_QE_title' + n + '">Title</label></span><span><input name="mondial_QE_dep' + n + 'firstName" class="field text" id="mondial_QE_dep' + n + 'firstName"  value="" size="8"/><label for="mondial_QE_dep' + n + 'firstName">First</label></span><span><input name="mondial_QE_dep' + n + 'lastName" class="field text" id="mondial_QE_dep' + n + 'lastName" value="" size="12"/><label for="mondial_QE_dep' + n + 'lastName">Last</label></span>		<span><input name="mondial_QE_dep' + n + 'dob" class="field text" id="mondial_QE_dep' + n + 'dob"  value="" size="13"/><a title="Click here to open a calendar date picker, or type the date into the box, in DD/MM/YY format" onclick="displayDatePicker(\'mondial_QE_dep' + n + 'dob\',true); this.blur();" href="Javascript:;" class="calendarPicker">Pick</a><label for="mondial_QE_dep' + n + 'dob">Date of Birth (DD/MM/YYYY)</label></span></div>';
					
					return depCode;

	},
	
	cullDependents : function(aboveThisNum)
	{
		while($('dep-' + aboveThisNum))
				{
					$('dep-' + aboveThisNum).remove();
					aboveThisNum++;
				}

	},
	
	backToScreen1 : function()
	{
		// navigate back to initial screen, resetting screen2's data:
		$('screen2').style.display = "none";
		$('screen1').style.display = "block";
		// reactivate screen1's button:
		xinit.screen1NextClicked = false;
		if ($('policySummaryInner'))$('policySummaryInner').update('');
		
		if ($('policyTable'))$('policyTable').remove();
		if ($('benefitTable'))
			{
				$('benefitTableHolder').remove();
				$('benefitTable').remove();
			}
		if ($('extensionBenefitTable')){
			$('extensionBenefitTable').remove();
			$('extensionBenefitTableHolder').remove();
		}
		
		xinit.policies = {};
		
	},
	
	backToScreen2 : function()
	{
		// navigate back to screen 2, from screen 3:
		$('screen3').style.display = "none";
		$('screen2').style.display = "block";
		
		
	},
	
	backToScreen2from4 : function()
	{
		// navigate back to screen 2, from screen **4** - amend policy button:
		$('screen4').style.display = "none";
		$('screen2').style.display = "block";
		
		
	},
	
	backToScreen3 : function()
	{
		// navigate back to screen 2, from screen 3:
		$('screen4').style.display = "none";
		$('screen3').style.display = "block";
	},
	
	failToGetPolicies : function()
	{
		// call if xinit.policies is empty after ajax request....	
		
		$('screen2Policies').update('<div class="invalidAlert" style="clear: none; font-size: 1.1em"><div class="alert"></div><strong>No policies available for selected date range.</strong> We have no policies available for the dates and destination you selected. Please either <a onclick="pageControls.backToScreen1();"  href="Javascript:;">select different dates</a>, or ring for assistance. </div>');
		
	},
	
	retryAjaxForPolicies : function()
	{
		$('screen2Policies').insert('<div class="invalidAlert" style="clear: none; font-size: 1.1em"><div class="alert"></div><strong>Server is currently Busy.</strong> The request to retrieve policies from our server is taking longer than expected. You may either continue to wait or press F5 and try again. </div>');

			clearTimeout(xinit.ajaxTimer);
	},
	
	
	
	end : null
}

//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------


var validation = {
	
	// validation:
		numericExpression : /^[0-9]+$/,
		decimalExpression : /^\d*(\.\d{1,2})?$/,
		emailAddress : /^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+@[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$/,
	// '
	validateScreen1 : function()
	// called from Next> button at base of screen 1.
	// validates that a destination is selected (if not multi) and that a date range is selected (if not multi)
	// compiles and sends to Ajax Agent in Domino
	// PREVENT RECLICKS
	{
		if (xinit.screen1NextClicked){
			return false;
		}
		xinit.screen1NextClicked = true;
		// clear existing invalids:
		validation.clearExisting('screen1');
		// Single | Multi?
		var tripTypeRadio = document.getElementsByName('tripType');
		var tripType = "frequent";
		
		var destination = '';
		var durationFrom = '';
		var durationTo = '';
		var planOption = '';
		var valid = true;
		var invalidElements = {};
		var screen1Data = '';
		var duration = '';
		
 
		if (tripTypeRadio[0].checked)
		{
			tripType = 'single';
			xinit.tripTypeName = 'Single Trip';
			// since this is single, gether (and validate) destination, duration, travellers...
			
			// DESTINATION
			destination = $('destination').value;
			if (destination == "")
			{
				// no destination specified; fail validation, add destination to array
				valid = false;
				invalidElements.destination = "<strong>Required Information</strong>: Please select a destination from the dropdown list. For help with choosing a destination, see our 'destination guide'.";
				$('destination').addClassName('invalidField');
			}
			
			// DURATION -- check UK format and to later than from...
			
			durationFrom = $F('tripDurationFrom');
			durationTo = $F('tripDurationTo');
			if (durationFrom == "" || durationTo == "")
			{
				invalidElements.duration = "<strong>Required Information</strong>: Please specify both a Start and End Date for your trip, in <strong>DD/MM/YYYY</strong> format.";
				valid = false;
				$('tripDurationFrom').addClassName('invalidField');
				$('tripDurationTo').addClassName('invalidField');
			}
			// start earlier than end AND start more than NOW
			if (durationFrom == 'test')
			{
				invalidElements.duration = "<strong>Incorrect Information</strong>: End Date must be later than Start Date, and both dates must be in the future, and in <strong>DD/MM/YYYY</strong> format.";
				valid=false;
			}
			
			// VALID DATES;
			var validFromDate = dateLogic.getUKDate(durationFrom);
			
			
			var validToDate = dateLogic.getUKDate(durationTo);
			
			
			if (!validFromDate || !validToDate || validToDate < validFromDate){
				invalidElements.duration = "<strong>Invalid Dates</strong>: End Date must be later than Start Date, and both dates must be in the future, and in <strong>DD/MM/YYYY</strong> format.";
				valid=false;	
				$('tripDurationFrom').addClassName('invalidField');
				$('tripDurationTo').addClassName('invalidField');
			}
			
			else {
				// set xinit.startDate and xinit.endDate for later date comparisons
				$('tripDurationFrom').value = getDateString(validFromDate);
				$('tripDurationTo').value = getDateString(validToDate);
				
				xinit.startDate = validFromDate;
				xinit.endDate = validToDate;
				// valid dates, get DURATION days or Months
				// 1. days : if less than 45 against day array.
				var daysBetween = 1 + dateLogic.getDays(validFromDate,validToDate);
				//console.log(daysBetween)
				if (daysBetween <= 45){
					//console.log(daysBetween);
					// get from Day Array up to and including 45 days.
					var i=0;
					duration = xinit.dayArray[i];// set to first array
					while (i < xinit.dayArray.length && daysBetween > xinit.dayArray[i])
					{
						duration = xinit.dayArray[i+1];
						//console.log ('looking for: ' + daysBetween + ' testing index ' + i + ' - ' + xinit.dayArray[i]);
						
						i++;
					}
					duration = duration + '-days';
				}
				else {
					// WHOLE MONTHS
					var monthsBetween = 1+ dateLogic.getMonths(validFromDate,validToDate);
					duration = monthsBetween + '-months';
				}
				// no more than 12 months worth (we're using months to ensure leap-years are handled)
				if (monthsBetween >12){
					invalidElements.duration = "<strong>End date too far in the future</strong>. You cannot request periods of more than 12 months.";
					valid = false;
				}
			
			}
			
			// TRAVELLER PLAN OPTION
			planOption = getCheckedValue('planOption');
			xinit.currentPlanOption = planOption;
			xinit.currentDestination = destination;
			xinit.currentTripType = 'single';
			xinit.duration = duration;
			
			screen1Data = '&tripType=single&destination=' + destination + '&duration=' + duration + '&planOption=' + planOption;
		}
		else {
			// Annual Frequent Traveller Policy:
			// Need valid Start Date:
			// DURATION -- check UK format and to later than from...
			
			var AFTStartDate = $F('AFTStartDate');
			var AFTAlert = "";
			xinit.currentDestination = "Worldwide";
			if (AFTStartDate == "")
			{
				invalidElements.duration  = "<strong>Required Information</strong>: Please specify a Start Date for the Policy, in <strong>DD/MM/YYYY</strong> format.";
				valid = false;
				$('AFTStartDate').addClassName('invalidField');
				
			}
			
			// VALID DATE;
			var validAFTStartDate = dateLogic.getUKDate(AFTStartDate);
			
			if (!validAFTStartDate){
				invalidElements.duration = "<strong>Invalid Dates</strong>: Start Date is incorrect. Date must be in the future, and in <strong>DD/MM/YYYY</strong> format.";
				valid=false;	
				$('AFTStartDate').addClassName('invalidField');
			}
			else {
				
				$('AFTStartDate').value = getDateString(validAFTStartDate);	
			}
			
			
			
			screen1Data = "&tripType=frequent";
			xinit.currentTripType = 'frequent';
			xinit.tripTypeName = 'Annual Frequent Traveller';
		}
		
		// if valid -> ajax
		// if invalid <-- screen1 with help
		if (valid){

			// clear screen1 and display prototype screen 2 for display interactiveness:
			// moved display code here:
			$('screen2').className = tripType;
			$('availableExtensions').className = xinit.currentPlanOption;
			$('availableExtensions').addClassName(xinit.currentDestination)
			
			// do at end or beginning?
			$('screen1').style.display="none";
			$('screen2').style.display="block";
			
			$('Xenu').style.display = "none";
			$('topHelp').style.display = "block";

			// build & show simple policy summary div
			var summaryData = "";
			summaryData = '<div class="summaryRow"><strong>Plan Type: </strong><span>' + xinit.tripTypeName + '</span></div>';
			if (tripType == "single"){
				summaryData += '<div class="summaryRow"><strong>Destination: </strong><span>' + $('destination').options[$('destination').selectedIndex].text + '</span></div>';
				summaryData += '<div class="summaryRow"><strong>Cover Option: </strong><span>' + xinit.currentPlanOption + '</span></div>';
				summaryData += '<div class="summaryRow"><strong>Policy Start: </strong><span>' + $('tripDurationFrom').value + '</span></div>';
				summaryData += '<div class="summaryRow"><strong>Policy End: </strong><span>' + $('tripDurationTo').value + '</span></div>';	
			}
			else {
				// AFT Polocicy:	
				summaryData += '<div class="summaryRow"><strong>Policy Start: </strong><span>' + $F('AFTStartDate') + '</span></div>';
				// future date:
				var AFTStartDate = dateLogic.getUKDate($F('AFTStartDate'));
				var future = new Date (AFTStartDate.getFullYear()+1, AFTStartDate.getMonth(), AFTStartDate.getDate()-1)
				
				summaryData += '<div class="summaryRow"><strong>Policy End: </strong><span>' + getDateString(future) + '</span></div>';	
				
			}
			
			
			$('policySummaryInner').insert(summaryData);
			
			// -------------------
			// send to Ajax
			// start failure timeouts, ajax display indicator, etc
			
			$('screen2Policies').update('<div class="ajaxIndicator"><p>Please wait, retrieving policies for the selected choices...</p></div>');
			
			// start timer
			xinit.ajaxTimer = setTimeout( "pageControls.retryAjaxForPolicies()", 12000 );

			ajaxRequests.getPolicies(tripType,screen1Data);
		}
		else{
			// remove all EMs
			// loop through fails, and create nodes:
			for (var failure in invalidElements)
			{
				// instantiate node
				var newNode = new Element('div',{ 'class': 'invalidAlert'}).update('<div class="alert"></div>' + invalidElements[failure]);
				$(failure + 'Active').insert({ before: newNode }); 
				$$(".alert").each(function(node){
										   			node.addClassName('animStart');
										   			new Effect.Pulsate(node,{pulses:2, afterFinish:validation.cleanUpAnimation});
										   })
			xinit.screen1NextClicked = false;
			}
			
		}
	},
	
	cleanUpAnimation : function()
	{
		$$(".animStart").each(function(node){
			node.removeClassName('animStart');
								   })
	},
	
	validateScreen3 : function()
	{
		// clear existing invalids:
		validation.clearExisting('screen3');
		var adults=1;// number of adults to validate
		var dependents=false;//should we validate dependents?
		var invalidElements = {};
		var screen3Valid=true;// assume valid, set to false if any element invalid:
		// work out how many adults, and how many dependents need to validate, then validate.... -- build array of stuff to validate...

		switch(xinit.currentPlanOption)
		{
			case "Single":
				adults=1;
				dependents=true;
			break;    
			case "Duo":
			 	adults=2;
				dependents=false;
			break;
			case "Family":
			 	adults=2;
				dependents=true;
			break;	 
		}
		
		
		// highlight ALL empty fields
		$$('#screen3 .field').each(function(item){if($F(item)==""){
														item.addClassName('invalidField');
														//screen3Valid=false;
												  }
												 });
		
		if ($F('mondial_QE_firstName1') =="" || $F('mondial_QE_lastName1') == ""){
				$('firstApplicant').insert({top:'<div class="invalidAlert"><div class="alert"></div><strong>Required fields missing:</strong> First Name and Last Name must be supplied.</div>'});
				screen3Valid=false;

			
		}
		
		
		var validDOB1 = dateLogic.getUKDate($F('mondial_QE_dob1'),true);
		if (!validDOB1) {
			$('mondial_QE_dob1').addClassName('invalidField');
			var errorText = "<strong>Invalid Date of Birth:</strong> Please specify a valid date of birth, in the format DD/MM/YYYY.";
			if ($$('#firstApplicant .invalidAlert').length > 0 && $$('#firstApplicant .invalidAlert')[0]!="") $$('#firstApplicant .invalidAlert')[0].insert('<p>' + errorText + '</p>');
			else $('firstApplicant').insert({top:'<div class="invalidAlert"><div class="alert"></div>' + errorText + '</div>'});
			screen3Valid=false;
		}
		else{
			// set field back to valid date
			$('mondial_QE_dob1').value = getDateString(validDOB1);
			// dob is valid, check age:
			if (!validation.validateAdultDOB(validDOB1)){
				// above max age, alert:
				$('mondial_QE_dob1').addClassName('invalidField');
				$('firstApplicant').insert({top:'<div class="invalidAlert"><div class="alert"></div>Traveller must be under ' + xinit.maxAge + ' and over ' + xinit.minAge + ' years of age on the start date of the policy.<p><strong>please ring Downunder 1800 148 766 for a quote.</p></div>'});
				screen3Valid=false;
			}
		}
		
		// blank 2nd traveller 'automatically invalid' empty fields
		if (xinit.currentTripType=="frequent") {
			if ($F('mondial_QE_firstName2') =="") $('mondial_QE_firstName2').removeClassName('invalidField'); 
			if ($F('mondial_QE_lastName2') =="") $('mondial_QE_lastName2').removeClassName('invalidField'); 
			if ($F('mondial_QE_dob2') =="") $('mondial_QE_dob2').removeClassName('invalidField'); 
			}
		
		if ((adults==2 && xinit.currentTripType=="single")|| (xinit.currentTripType=="frequent" && ($F('mondial_QE_firstName2') !="" || $F('mondial_QE_lastName2') != "" ))){
			//mondial_QE_title1,mondial_QE_firstName1,mondial_QElast_Name1,mondial_QE_dob1
			// compare policy start Date with dob for age check...
			if ($F('mondial_QE_firstName2') =="" || $F('mondial_QE_lastName2') == ""){
				$('secondApplicant').insert({top:'<div class="invalidAlert"><div class="alert"></div><strong>Required fields missing:</strong> First Name and Last Name must be supplied. ' + (xinit.currentTripType=='frequent' ? "In Annual Frequent Traveller Policies, the spouse is covered free, but must be specified correctly if present." :"") + '</div>'});
				screen3Valid=false;
				if ($F('mondial_QE_firstName2') =="") $('mondial_QE_firstName2').addClassName('invalidField'); 
				if ($F('mondial_QE_lastName2') =="") $('mondial_QE_lastName2').addClassName('invalidField'); 
				
			}
			var validDOB2 = dateLogic.getUKDate($F('mondial_QE_dob2'),true);
			if (!validDOB2) {
				$('mondial_QE_dob2').addClassName('invalidField');
				var errorText = "<strong>Invalid Date of Birth:</strong> Please specify a valid date of birth, in the format DD/MM/YYYY.";
				if ($$('#secondApplicant .invalidAlert').length > 0 && $$('#secondApplicant .invalidAlert')[0]!="") $$('#secondApplicant .invalidAlert')[0].insert('<p>' + errorText + '</p>');
				else $('secondApplicant').insert({top:'<div class="invalidAlert"><div class="alert"></div>' + errorText + '</div>'});
				screen3Valid=false;
			}
			else{
				$('mondial_QE_dob2').value = getDateString(validDOB2);
				// dob is valid, check age:
				if (!validation.validateAdultDOB(validDOB2)){
					// above max age, alert:
					$('mondial_QE_dob2').addClassName('invalidField');
					$('secondApplicant').insert({top:'<div class="invalidAlert"><div class="alert"></div>Second traveller must be under ' + xinit.maxAge + ' and over ' + xinit.minAge + ' years of age on the start date of the policy.<p><strong>please ring Downunder 1800 148 766 for a quote.</p></div>'});
					screen3Valid=false;

				}
			}
		}
		
		// validate PE cover:
		var pes = xinit.extensions.findAll(function(n) { return n.indexOf('PE') != -1; });
		var validatePE1 = false;
		var validatePE2 = false;
		var peRadios = true;
		var pe1valid = true;
		var pe2valid = true;
		
		if (pes.length == 1 && xinit.currentPlanOption!="Single"){
			// radio check, for which applicant
			// and validate that a radio is checked...
			if (!$('mondial_QE_peRadio1').checked && !$('mondial_QE_peRadio2').checked) peRadios = false;
			else{
				if ($('mondial_QE_peRadio1').checked) validatePE1 = true;
				if ($('mondial_QE_peRadio2').checked) validatePE2 = true;
			}
			
		}
		else if (pes.length == 1 && xinit.currentPlanOption=="Single") validatePE1 = true;
		
		if (pes.length == 2){
		// validate 2nd applicant	
			validatePE2 = true;
		}
		
		if (!peRadios){
			
			$('firstApplicant').insert({top:'<div class="invalidAlert"><div class="alert"></div><strong>Medical Exemption Cover Extension.</strong> Please specify which of the applicants the Medical Exemption Cover Extension applies to. If cover is required for <strong>both</strong> applicants, please <a href="javascript:;" onclick="pageControls.backToScreen2();">go back</a> and add a second Medical Cover Extension.</div>'});
			screen3Valid = false;
		}
		else{
			if (validatePE1 && $F('mondial_QE_pe1')==""){
				$('peApplicant1').insert({before:'<div class="invalidAlert"><div class="alert"></div><strong>Medical Exemption Cover Extension.</strong> Please provide Medical Reference Number for applicant 1</div>'});
				screen3Valid = false;
			}
			
			if (validatePE2 && $F('mondial_QE_pe2')==""){
				$('peApplicant2').insert({before:'<div class="invalidAlert"><div class="alert"></div><strong>Medical Exemption Cover Extension.</strong> Please provide Medical Reference Number for applicant 2</div>'});
				screen3Valid = false;
				
			}
			
		}
		
		
		
		// Dependents:
		
		if (dependents){
			// for each dependent, validate esp DOB;
			numberDependents = $F('mondial_QE_dependents');
			
			// mlr - 24.3.09 just in case there is a descepancy between available fields, and the value of mondial_qe_dependents, check they're built,
			// reuising the pageControls.buildDependents(parseInt($F('mondial_QE_dependents'))) function -- will ensure *right* number of fields when > Next clicked...
			
			pageControls.buildDependents(parseInt($F('mondial_QE_dependents')));
			
			// validate each one, only use 1 input box....
			var dependentsNamesValid = true;
			var dependentsDOBsValid = true;
			var dependentsDOBsInRange = true;
			
			for (var i=1; i<=numberDependents;i++)
			{
				if ($F('mondial_QE_dep' + i + 'firstName')=="" || $F('mondial_QE_dep' + i + 'lastName')=="" ) dependentsNamesValid = false;
				var validDOB = dateLogic.getUKDate($F('mondial_QE_dep' + i + 'dob'),true);
				if (!validDOB){
					dependentsDOBsValid = false;
					$('mondial_QE_dep'+ i + 'dob').addClassName('invalidField');
				}
				else {
					$('mondial_QE_dep'+ i + 'dob').value = getDateString(validDOB);
					
					
						if(!validation.validateChildDOB(validDOB)){
								dependentsDOBsInRange = false;
								$('mondial_QE_dep'+ i + 'dob').addClassName('invalidField');
						}
				}
				
				
			}
			
			if(!dependentsNamesValid || !dependentsDOBsValid || !dependentsDOBsInRange)
			{
				var text = "<strong>Dependents missing or invalid information:</strong> ";
				if (!dependentsNamesValid ) text+= "<br/>Dependent names missing or incomplete.";
				if (!dependentsDOBsValid ) text+= "<br/>Dependent dates of birth are missing, incomplete or not valid. Ensure dates are in DD/MM/YYYY format.";
				if (!dependentsDOBsInRange ) text+= "<br/>Dependents must be aged " + xinit.childMaxAge + " years or under on the start date of the policy. Please ring Downunder on 0800&nbsp;244&nbsp;633 to arrange a quotation.";
				screen3Valid=false;
				$('mondial_QE_dependents').insert({before: '<div class="invalidAlert"><div class="alert"></div>' + text + '</div>'});
				//$('dependents').scrollTo();
			}
		}
		
		
		// telephone numbers: must be numeric. Strip spaces:
		var screen3TelsValid = true;
		$('mondial_QE_telephone1','mondial_QE_telephone2','mondial_QE_mobile').each(function(item){
																							item.value = item.value.replace(/\s/g,'');																					 
																							 });
		
		var tel1 = $F('mondial_QE_telephone1');
		var tel2 = $F('mondial_QE_telephone2');
		if (!validation.numericExpression.test(tel1) || !validation.numericExpression.test(tel2) || tel1=="" || tel2==""  || tel1.length !=2  || tel2.length !=8)
		{
			$('telephoneAnchor').insert({before: '<div class="invalidAlert"><div class="alert"></div><strong>Invalid Telephone Number:</strong> Please enter a valid Telephone Number with 2 digit Area Code and a 8 digit number, without spaces, dashes, brackets, etc.</div>'});
			screen3Valid = false;
			$('mondial_QE_telephone1').addClassName('invalidField');
			$('mondial_QE_telephone2').addClassName('invalidField');
		}
		
		// mobile number not required, but if it is entered, must be numeric
		if ($F('mondial_QE_mobile') !="" && (!validation.numericExpression.test($F('mondial_QE_mobile')) || $F('mondial_QE_mobile').length < 9 || $F('mondial_QE_mobile').length > 10 )){
				$('mobileAnchor').insert({before: '<div class="invalidAlert"><div class="alert"></div><strong>Invalid Mobile Number:</strong> If entered, the Mobile number must be 9 or 10 digits long, numeric, no spaces, dashes, brackets, etc.</div>'});
				screen3Valid = false;
				$('mondial_QE_mobile').addClassName('invalidField');
		}
		
		// email: check email1 valid, and that email2 matches email1....
		var email = $F('mondial_QE_email');
		var emailConfirm = $F('mondial_QE_emailConfirm');
		var emailAlert = "";
		if (email == "" || !validation.emailAddress.test(email)){
			emailAlert = "<strong>Email address is invalid or missing</strong>. Please enter a valid email address, so that we can send you your policy details.";
			$('mondial_QE_email').addClassName('invalidField');
			$('mondial_QE_emailConfirm').addClassName('invalidField');
				
		} else {
			// if we're here, then email1 is valid. Check that email2 matches email1...	
			if (emailConfirm != email){
					emailAlert = "<strong>Confirm Email Address.</strong> Please check that you have correctly entered the confirmation email address. A valid email address is required to send you your policy details.";
					$('mondial_QE_emailConfirm').addClassName('invalidField');
			}
		}
		
		if (emailAlert != ""){
			$('emailAnchor').insert({before: '<div class="invalidAlert"><div class="alert"></div>'+ emailAlert +'</div>'});
			screen3Valid = false;
		}
		
		// ADDRESS BLOCK
		// validate 
		var addressAlert = "";// var to hold address alert message text, test if empty to trigger display of alert...
		if ($F('mondial_QE_address1') == "") addressAlert = "Please specify Street Address.";
		if ($F('mondial_QE_city') == "") addressAlert += "<br/>Please specify City.";
		if ($F('mondial_QE_province') == "") addressAlert += "<br/>Please select a State.";
		
		if ($F('mondial_QE_postCode') == "") addressAlert += "<br/>Please specify Post Code.";
		if (isNaN(parseInt($F('mondial_QE_postCode'))) || $F('mondial_QE_postCode').length > 6 || $F('mondial_QE_postCode').length < 3  ){
			addressAlert += "<br/>Please enter a valid Post Code (between 3 and 6 digits)";
			$('mondial_QE_postCode').addClassName('invalidField');
		}
		
		
		if (addressAlert != ""){
			// invalid address:	
			$('addressAnchor').insert({top: '<div class="invalidAlert"><div class="alert"></div><strong>Address incomplete:</strong> ' + addressAlert +'</div>'});
			screen3Valid = false;
		}
		
		
		// lastly, if we're invalid, scroll to the FIRST invalid element:
		if (screen3Valid){
			// good to go, go Screen 4 - Summary:
			//
			//
			pageControls.populateScreen4();
		}
		else{
			// something's invalid, focus it:
			var invalidAlerts = $$('#screen3 .invalidAlert');
			if (invalidAlerts.length > 0)invalidAlerts[0].scrollTo();
			$$("#screen3 .alert").each(function(node){
										   			node.addClassName('animStart');
										   			new Effect.Pulsate(node,{pulses:2, afterFinish:validation.cleanUpAnimation});
										   })
		}
		
	},
	
	validateScreen4 : function()
	// final screen before payment: Check the three top checkboxes are ticked...
	{
		validation.clearExisting('screen4');
		
		if ($('agree1').checked && $('agree2').checked && $('agree3').checked && $('agree4').checked){
			var form = document.forms[0];
			ajaxRequests.postToDomino();
		}
		else {
		// fail:
			$('TandC').insert({top: '<div class="invalidAlert"><div class="alert"></div><strong>Attention: </strong>You must agree to the relevant Important Information before purchasing a policy.<br clear="all"></div>'});
			$$("#screen4 .alert").each(function(node){
										   			node.addClassName('animStart');
										   			new Effect.Pulsate(node,{pulses:2, afterFinish:validation.cleanUpAnimation});
										   })
			
		}
	
	},
	validateAdultDOB : function(dob)
	{
		// dob as date object....
		// compare policy commencement date - xinit.startDAte, with Date of Birth, with Adult Age Limit (xinit.maxAge)
		var isValid = true;
		var bornYear = dob.getFullYear();
		// set dob to the expiry year (maxAge+1 to handle the the fact that you can be maxAge + 364 days and be okay)
		dob.setFullYear(bornYear+xinit.maxAge+1);
		if(dob <= xinit.startDate) isValid = false;
		
		// enforce min adult age
		//xinit.minAge = 18;
		// [10.09.2009: remove ...+xinit.minAge + 1) as was incorrectly causing minAge to be 19 not 18.
		dob.setFullYear(bornYear+xinit.minAge)
		//console.log(dob);
		if(xinit.startDate < dob) isValid = false;
		
		return isValid;
	},
	
	validateChildDOB : function(dob)
	{
		// dob as date object....
		// compare policy commencement date - xinit.startDAte, with Date of Birth, with Child Age Limit (xinit.childMaxAge)
		var isValid = true;
		var bornYear = dob.getFullYear();
		// set dob to the expiry year (maxAge+1 to handle the the fact that you can be maxAge + 364 days and be okay)
		dob.setFullYear(bornYear+xinit.childMaxAge+1);
		if(dob <= xinit.startDate) isValid = false;
		
		return isValid;
	},
	
	clearExisting : function(screenId)
	{
		$$('#' + screenId + ' .invalidAlert').each(function(item){item.remove()});
		$$('.invalidField').each(function(item){item.removeClassName('invalidField')});
	},
	
	
	
	end : null
}

//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------

var windowing = {
	
	displayWindow : function()
	{		
	
		// if browser (ie IE6) doesn't understand position:fixed:
		var positionSupport = true;
		if ($('modal').getStyle('position') !='fixed') positionSupport = false;
		if (!positionSupport){
			 var dims = document.viewport.getDimensions();
			$('modal').setStyle(dims);
			
		}
		
	
		var bodyWidth = document.viewport.getWidth();
		var bodyHeight = document.viewport.getHeight();
		var scrollOffset = document.viewport.getScrollOffsets();
		var width = 640;
		var height = 480;
		scrollOffset = [0,0];
		var posX = Math.round(bodyWidth/2 - (parseInt(width)/2)) + scrollOffset[0];
		var posY = Math.round(bodyHeight/2 - (parseInt(height)/2)) + scrollOffset[1];
		if (posY < 0)
				{
					posY = 0;
				}
		$('effectsHolder').setStyle({left: posX + 'px',top: posY + 'px', width: width + 'px',height: height + 'px',display: 'none', visibility: 'visible'});
		
		new Effect.Appear('effectsHolder', 
   		{ 
      		duration: 0.4,
			afterFinish:function(element)
			{
				//$(args.focusField).focus();
			}
		});
		
		// init list:
		effectsLogic.showList();
		$('modal').style.visibility = "visible";
	},
	
	fadeKillWindow : function()
	{
		
		$('modal').style.visibility = "hidden";
		
		new Effect.Fade('effectsHolder', 
   		 { 
      		duration: 0.3
      		}
    	 );
		
	}
	
	
}

//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------

var ajaxRequests = {

	getPolicies: function(tripType,screen1Data)
	// Called from screen1 valid -> Ajax server, send data, get back list of policies.
	// Calls [on:success callback - pageControls.populateScreen2() if successful, else handle fail...
	{
		// ajax stuff....
		var url = xinit.webDbName + 'mondialAjaxQuoteEngine?openagent' + screen1Data + '&id=' + Math.random();
											new Ajax.Request(url, {
												  method: 'get',
												  onSuccess: function(transport) {
													xinit.policies = transport.responseText.evalJSON();
													if (xinit.policies.length != 0) {
														pageControls.populateScreen2(tripType);
													}
													else {
														pageControls.failToGetPolicies();	
													}
													clearTimeout(xinit.ajaxTimer)
												  },
												  onFailure: function(transport) {
													$('screen2Policies').update('<div class="invalidAlert" style="clear: none; font-size: 1.1em"><div class="alert"></div><strong>Unable to retrieve Policy Information.</strong> There was a problem retrieving the policies from the server, please press F5 and Try Again. Alternatively, please ring for assistance. </div>');
		 										  }
												 
															  
												});

	},
	
	postToDomino : function()
	// send required data to back end, validate, and return policy Reg.
	// then trigger (pseudo)POST to Worldpay...
	{
		var url =  xinit.webDbName + 'mondialPolicyCreate?createdocument&id=' + Math.random();
		
		// dependents:
		var adults = 1;
		var dependents = false;
		var dependentData = "";
		var nonFieldData = ""; // eg policy name, stuff to virtualise into fields for posting...
		switch(xinit.currentPlanOption){
			case "Single":
				adults=1;
				dependents=true;
			break;    
			case "Duo":
			 	adults=2;
				dependents=false;
			break;
			case "Family":
			 	adults=2;
				dependents=true;
			break;	 
		}
		
		// override adults and dependents in the case of AFT
		if (xinit.currentTripType=='frequent'){
			adults = 2;
			dependents=true;	
			// blank any non-aft fields, or set to aft vals:
			$('tripDurationFrom').value = "";
			$('tripDurationTo').value = "";
			xinit.duration = "12-months";
			$('destination').disabled = true;
			
			nonFieldData += "&destination=Worldwide";
		} else {
			// blank any AFT fields, as we're not an AFT policy
			$('AFTStartDate').value = "";
		}
		
		
		nonFieldData += "&policySelected=" + xinit.policySelectedRef + "&policyTotalCost=" + xinit.policyCost + "&duration=" + xinit.duration;
		
		if (dependents){
			var numberDependents = $F('mondial_QE_dependents');
			for (var i=1; i<=numberDependents;i++)
			{
				dependentData += (dependentData != "" ? ";" : "") + $F('mondial_QE_dep' + i + 'title')+ ' ' + $F('mondial_QE_dep' + i + 'firstName') + ' ';
				dependentData +=  $F('mondial_QE_dep' + i + 'lastName') + ',' +  $F('mondial_QE_dep' + i + 'dob');
			}
		nonFieldData += "&dependentValues=" + escape(dependentData);
		}
		// if 1 adult, blank any existing adult-2 fields:
		// amend to disable too, otherwise was now posting the title2 field even though 'set' to blank. (ffx 3.1)
		// 24.3.09 - add from || (xinit... as AFT policies have adults==2 and can still have second traveller blank,
								  // using lastname as the criterium.
		if (adults==1 || (xinit.currentTripType=='frequent' && $F('mondial_QE_lastName2')=="")){
			$('mondial_QE_title2','mondial_QE_firstName2','mondial_QE_lastName2','mondial_QE_dob2','mondial_QE_pe2').each(function(item){item.value = "";item.disabled = true;});
		}
		
		// blank any pre-filled medical check numbers, in case of go-back and forward
		var extensions = xinit.extensions.inspect();
		if(extensions.indexOf('\'PE\'') == -1){$('mondial_QE_pe1')==""}
		if(extensions.indexOf('\'PE-2\'') == -1){$('mondial_QE_pe2')==""}
		 
		// extensions:
		nonFieldData += "&extensions=" + xinit.extensions.toString();
		
		// effects:
		if (xinit.extensions.toString().indexOf('Effects') != -1){
			// parse effects
			var effectsData = "";
			xinit.effects.each(function(item){
												effectsData += (effectsData!=""?";":"") + item.itemType + "," + item.itemDescription + "," + item.itemMake + "," + item.itemModel + 
												"," + item.itemValue;
										});
			nonFieldData += "&effects=" + escape(effectsData) + "&effectsTotal=" + (typeof(xinit.effects.total) != "undefined" ? xinit.effects.total : 0);
		}
		
		if (xinit.currentTripType == "single") {
			nonFieldData += "&destinationDescription=" + escape($('destination').options[$('destination').selectedIndex].text);
		}
		
		
		var saveStringCollect = $('mondialQuoteEngine').serialize();
		
		new Ajax.Request(url, {
			  method: 'post',
			  postBody:  saveStringCollect + nonFieldData,
			  onCreate : function()
			  {
				// set 'loader' for this save event
				$('modal').style.visibility = "visible";
				//$('initialLoading').update ('<div class="winInnerContent"><h1>Saving document...</h1><p>Your document is being saved, please wait...</p></div>');
				//$('initialLoading').style.visibility = "visible";
			  },
			  
			  onSuccess: function(transport) {
				var responseArray = transport.responseText;
				// responseArray should contain doc @unique id of saved doc, pass to URL query string to highlight...
				// TURN OFF BUNLOAD
				// bunload = false;
				//alert(responseArray)
				var cartId = responseArray.substr(0,11);
				if (cartId.indexOf('-') != -1)
				{
					//$('initialLoading').update ('<div class="winInnerContent"><h1>Document saved, exiting...</h1></div>');
					//window.onbeforeunload = null;
					//window.location.href = '/gcd.nsf/schemaViews?open&updated=' + responseArray;
					paymentLogic.processForPayment(cartId);
				}
				else
				{
					// error?
					//$('initialLoading').update ('<div class="winInnerContent"><h1>Problem? Not logged on?</h1></div>');
					alert ('Payment has been taken, but our system was unable to process your policy successfully. Please contact Downunder Insurance for assistance.')
				}
				
			  }	
			});
		
		
	},
	
	
	end : null
	
}

//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------

var policyLogic = {
	
	addExtensions : function()
	//called from pageControls.addExtension, via extension checkboxes
	{
		// add the extension to the list of added extensions & populate the benefits....
		// loop through xinit.policies, if policy allows extenions, add the price factor, if it doesn't allow it, deactivate the policy selection
		
		// need Special Case for Personal Effects cover, to do maths calc on Total Value of Items, not on Policy...
		
		xinit.policies.each(function(item)
									 {
										// policyDiv if : 'policy-' + item.policy.refName
										// policy base price id : 'policy-base-' + item.policy.refName
										// policy debug: 'policy-debug-' + item.policy.refName
										
										// Now loop thu all checkboxes, and recalculate the maths...
										// 1. blank this policy's values & remove baseExtended -- RESET.
										var policyName = item.policy.refName;
										var thisPolicyDiv = $('policy-' + policyName);
										var thisPolicyBase = $('policy-base-' + policyName);
										var thisPolicyDebug = $('policy-debug-' + policyName);
										
										item.policy.baseExtended = false;
										item.policy.calculatedBaseExtended = false;
										
										thisPolicyDiv.removeClassName('unavailable');
										thisPolicyBase.update('');
										thisPolicyDebug.update('');
										
										
										// 2. Now loop through the checked entries, mark policy inactive if ext not available, compile maths, do after loop thru extensions...:
										var priceStream = [];
										var replaceBase = false;
										var replaceCalculatedBase = false;
									
										
										$A(document.getElementsByName('addExtensions')).each(function(extension){
											if (extension.checked){
												var extName = extension.value;
												// SCOPE moved isPE here from outside loop, otherwise got globally set
												// issue #22.0
												var isPE = ""; // if PE cover, need different maths
												if (extName == "Effects") isPE = "PE";
												
												var policyExtension = item.policy.extensions[extName];
												// DOES This Policy have this extension?
												if (typeof(policyExtension) !="undefined"){
													// console.log('p ' + item.policy.refName + ' has e ' + policyExtension.value);
													// get value and 'type' of extension, return array or price data, depending on percent/fixed/replace base...
													var extensionValue = policyExtension.value;
													var extensionBaseValue = policyExtension.baseValue;
													var extensionValueType = policyExtension.type;
													var newPriceArray = policyLogic.updateExtensionPrice(extensionValue,extensionBaseValue,extensionValueType,isPE);
													//console.log(newPriceArray)
													// use new base price for calculations??
													if (newPriceArray[0]!='') {
														replaceBase=newPriceArray[0];
														replaceCalculatedBase = newPriceArray[1];
													}
													else{
														// add price data (percent|fixed) for this extension, to the priceStream array for updating policy maths
														priceStream.push(newPriceArray[2]); 
													}
												}
												else {
													// deactivate this Policy
													thisPolicyDiv.addClassName('unavailable');
												}
											}
										  })
										//console.log(priceStream);
										// if applicable, update this policy's base cost (set policies[name].baseExtended = value... RESET this on extension check......
										if (replaceBase) {
											// USE UPDATED BASE?
											item.policy.baseExtended = replaceBase;
											item.policy.calculatedBaseExtended = replaceCalculatedBase;
											
										}
										
										// update this (we're in a loop still, of policies) policy's maths...
										// now iterate through priceStream, as valuepairs in array...
										// set policy EXTENSION total to zero
										item.policy.totalExtensionPrice = 0;
										// calc new total extension price, uses updated base if available:
										if (priceStream.length >0 ) policyLogic.doPolicyMaths(item,priceStream);
										// update new values:
										var basePriceToUse = parseFloat((item.policy.calculatedBaseExtended ? item.policy.calculatedBaseExtended : item.policy.calculatedBase));
										//thisPolicyBase.update('$' + (item.policy.calculatedBaseExtended ? parseFloat(item.policy.calculatedBaseExtended).toFixed(2) + '(new)' : parseFloat(item.policy.calculatedBase).toFixed(2)))
										var finalPrice = Math.round((basePriceToUse + item.policy.totalExtensionPrice)*100)/100;
										thisPolicyBase.update('$' + finalPrice.toFixed(2));
										//thisPolicyDebug.update('Extension Total: ' + item.policy.totalExtensionPrice.toFixed(2) + '<br/>Total: $' + (basePriceToUse + item.policy.totalExtensionPrice).toFixed(2));
										thisPolicyDebug.update('<span style="font-size: 0.9em">inc Additional Options cost: $' + item.policy.totalExtensionPrice.toFixed(2) + ' </span>');
										item.policy.policyCost = finalPrice.toFixed(2);

									 }
							)
		
	},
	
	doPolicyMaths : function(item,priceStream)
	// called from add extension, in loop for policies...
	{
		//var policyName = item.policy.refName;
		//var thisPolicyDiv = $('policy-' + policyName);
		//var thisPolicyBase = $('policy-base-' + policyName);
		//var thisPolicyDebug = $('policy-debug-' + policyName);
		var thisPolicyExtensionTotal = item.policy.totalExtensionPrice;
		
		
		var basePriceToUse = (item.policy.baseExtended ? item.policy.baseExtended : item.policy.base);
		
		priceStream.each(function(pricePair){
								  			var priceType = pricePair.split(',')[0]
											var priceValue = parseFloat(pricePair.split(',')[1])
											if (priceType == "X"){
												thisPolicyExtensionTotal = thisPolicyExtensionTotal + (basePriceToUse * priceValue);
											}
											else if (priceType == "PE"){
												var effectsTotal = effectsLogic.getEffectsTotal();
												thisPolicyExtensionTotal = thisPolicyExtensionTotal + (effectsTotal * priceValue);// total of effects * percentage increase on effects...
											}
											else {
												thisPolicyExtensionTotal = thisPolicyExtensionTotal + priceValue;
											}
								  
								  
								  });
		// output:
		item.policy.totalExtensionPrice = thisPolicyExtensionTotal;
		
	},
	
	updateExtensionPrice : function(extensionValue,extensionBaseValue,extensionValueType,isPE)
	// called from addExtension loops, takes input basePrice, and returns output based on extension value, and the type of extension(AddValue | AddPercent | MatrixValue | Replace)
	// build an array every time this is called...
	{
		newBasePrice = '';
		newCalculatedPrice = '';
		valueString = null;
		switch(extensionValueType)
		{
			case "AddValue":
			  // add fixed number to base
			  valueString = '1,' + extensionValue;
			  break;    
			case "MatrixValue":
			  // add fixed number to base, used by PE
			  // DUO/FAMILYL
			  valueString = '1,' + extensionValue;
			 break;
			 case "AddPercent":
				// Add Percentage to base 'X' -- get replaced later if base value is updated
				// if pe cover, output PE instead of X, so calculation can use PE total, not Policy Total
				if (isPE=="PE") valueString = 'PE,' + (extensionValue/100);
				else valueString = 'X,' + (extensionValue/100);
			 break;
			 case "Replace":
			 // Replace base value with this one
				newBasePrice = extensionBaseValue;
				newCalculatedPrice = extensionValue;
			 break;
		}
		
		return [newBasePrice,newCalculatedPrice,valueString]; 
	},
	
	removeExtension : function(name)
	// if extension checkbox is cleared
	{
		
	},
	
	end : null
}

//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------

var tableLogic = {
	
	benefitDropRow	: function(clickedCellEl,benefitIndex,colspan)
	{
		// kill any previous...
		var previousRow = $('benefitDropRow');
		var previousIndex = null;
		if(previousRow)
		{
			previousIndex = previousRow.index;
			previousRow.remove();	
		}
		
		// if not click on same entry, create dropdown, otherwise assume we've closed current endry, and do nothing
		if (previousIndex != benefitIndex)
		{
		
			var benefitHTML = "No more information is available about this benefit. Please refer to the full Policy Terms for details.";
			
			var benefit = xinit.benefits[benefitIndex];
			
			if (benefit && benefit.benefit.help && benefit.benefit.help !="")
			{
				benefitHTML = benefit.benefit.help;
			}
			
			
			var rowParent = clickedCellEl.parentNode;
			var rowParentClass = rowParent.className;
			$(rowParent).insert({after:'<tr id="benefitDropRow" class="' + rowParentClass + '"><td colspan="' + colspan + '" class="tableHelperRow">' + benefitHTML + '</td></tr>'});
			// assign trackable attribute, so we can prevent reopening on click of this row...
			$('benefitDropRow').index = benefitIndex;
		}
		
	},
	
	extraBenefitDropRow	: function(clickedCellEl,benefitIndex,colspan)
	{
		// kill any previous...
		var previousRow = $('extraBenefitDropRow');
		var previousIndex = null;
		if(previousRow)
		{
			previousIndex = previousRow.index;
			previousRow.remove();	
		}
		
		// if not click on same entry, create dropdown, otherwise assume we've closed current endry, and do nothing
		if (previousIndex != benefitIndex)
		{
		
			var benefitHTML = "No more information is available about this benefit. Please refer to the full Policy Terms for details.";
			
			var benefit = xinit.extraBenefits[benefitIndex];
			
			if (benefit && typeof(benefit.help!="undefined") && benefit.help !="")
			{
				benefitHTML = benefit.help;
			}
			
			
			var rowParent = clickedCellEl.parentNode;
			var rowParentClass = rowParent.className;
			$(rowParent).insert({after:'<tr id="extraBenefitDropRow" class="' + rowParentClass + '"><td colspan="' + colspan + '" class="tableHelperRow">' + benefitHTML + '</td></tr>'});
			// assign trackable attribute, so we can prevent reopening on click of this row...
			$('extraBenefitDropRow').index = benefitIndex;
		}
		
	},
	
	extensionDropRow : function(hiddenRowId)
	{
		if (xinit.extensionHelpOpen && xinit.extensionHelpOpen == hiddenRowId)
		{
			$(hiddenRowId).addClassName('hideTR');
			xinit.extensionHelpOpen = null;
		}
		else
		{
			// close previous?
			if (xinit.extensionHelpOpen)
			{
				$(xinit.extensionHelpOpen).addClassName('hideTR');
			}
			
			// open new
			if ($('modal').style.visibility =="hidden")
			{
				$(hiddenRowId).removeClassName('hideTR');
				xinit.extensionHelpOpen = hiddenRowId;
			}
		}
		
	},
	
	end : null
	
}

//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------

var benefitLogic = {
	addExtensionBenefit	: function(extensionRef)
	// called from onclick on extension checkbox, via pageControls.addExtension
	// has an extension ref. Look this up in the linkExtensionsWithBenefits table to get a list of benefit IDs -- 
	// loop through the benefit ids, and look up the policy extension values
	{
		// 1. Get ids of relevant extensions:
		var extensions = xinit.linkExtensionsWithBenefits[extensionRef];
		if (!extensions) return false;
		// instantiate table
		
		// is there a benefit extension table already?, if not create it:
		if(!$('extensionBenefitTable'))
			  {
				var extensionBenefitTable = new Element('table',{'id':'extensionBenefitTable','class':'bc','width':'100%','cellpadding':'0','cellspacing':'0','border':'0'});
				var extensionBenefitTableHolder = new Element('div',{'id':'extensionBenefitTableHolder'}).update('<h3>Additional Options Policy Sections & Benefits</h3>');
				
				$('policyTable').insert({after:extensionBenefitTable});
				$('policyTable').insert({after:extensionBenefitTableHolder});
				
				
			  }
			 
		// calc table column widths...
		var firstColumnWidth = xinit.firstColumnWidth; //40;// percentage width of first column
		var remainingColumnsWidth = 100-firstColumnWidth; // ideally should be wholly divisible by 2 and 3 (and 4)
		var columns = xinit.policies.length +1;
		var columnWidth = (remainingColumnsWidth/xinit.policies.length).toFixed(2);
		var benefitType = (xinit.currentDestination=="Domestic" ? "domestic" : "international");
		// iterate thru extension benefit ids
		
		var tableBody = "";
		var extensionEntries = extensions.split(',');
		var groupRow = "";
		var tableContent = "";
		
		$A(extensionEntries).each(function(refId,index)
									 {
										 // for each id, look up in xinit.extraBenefits, to get row descriptor and help,
										 // then loop thru policies for values...
										
										
										var groupName = (xinit.extraBenefits[refId] ? xinit.extraBenefits[refId].group : "");
										if (groupName !="" && groupRow =="")
										{
											groupRow= '<tr><td class="extraBenefitHeader"><img src="tick16.png" height=16 width=16 alt="Extension Added">' + groupName + ':</td>';
											for (var i=1;i<columns;i++)
											{
												groupRow += '<td>&nbsp;</td>';	
											}
											groupRow += '</tr>';
											
										}
										
										var tableRow = '<tr id="extraBenefitRow' + refId + '"class="'+(index%2?"odd":"even")+'"><td width="' + firstColumnWidth + '%" class="extensionName' + (groupRow==""?" extensionSingle":"") + '" onclick="tableLogic.extraBenefitDropRow(this,\'' + refId + '\',' + columns + ');">';
										var notEmpty = false;
										
										tableRow += (groupRow==""?'<img src="tick16.png" height=16 width=16 alt="Extension Added">':'');
										tableRow += (typeof(xinit.extraBenefits[refId])!="undefined" ? xinit.extraBenefits[refId].name : "") + '</td>';
										
										xinit.policies.each(function(item)
														 {
															 tableRow += '<td width="' + columnWidth + '%" valign="top">';
															 if (typeof(item.policy.benefits)!="undefined" && typeof(item.policy.benefits[refId]) != "undefined" )
															 {
															 	var benefitValue = item.policy.benefits[refId][benefitType];
																var doubleMe =  item.policy.benefits[refId].doubleMe;
																tableRow += maths.convertBenefitValue(benefitValue,doubleMe);
																notEmpty = true;
															 }
															 else 
															 {
																 tableRow += '-----';
																
															 }
															 tableRow += '</td>';
														 }
														)
										
										
										
										tableRow += '</tr>';
										
										// only update row if there is content...
										// insert at TOP of table???
										if (notEmpty) tableContent += tableRow;
									 }
									)
		
		tableBody = '<tbody id="tb' + extensionRef + '" class="extensionBenefitGroup">' + groupRow + tableContent + '</tbody>';
		
		
		// header:
		if (!$('theader')) {
				var tableHeader = '<tbody id="theader"><tr><td class="benefitTableHeaderEmpty" width="'+firstColumnWidth+'%"> </td><td class="benefitTableHeaderCell" colspan="' + columns + '" width="' + remainingColumnsWidth + '%">Maximum Benefit Limits</td></tr></tbody>';
				$('extensionBenefitTable').insert({top:tableHeader});
		}
				
				$('theader').insert({after:tableBody});
		
		
	},
	
	removeExtensionBenefit	: function(extensionRef)
	{
		/*
		var extensions = xinit.linkExtensionsWithBenefits[extensionRef];
		if (!extensions) return false;
		$A(extensions.split(',')).each(function(refId)
									 {
										if ($('extraBenefitRow' + refId))
										{
											if ($('extraBenefitDropRow') && $('extraBenefitDropRow').index && $('extraBenefitDropRow').index == refId)
											{
												$('extraBenefitDropRow').remove();
											}
											$('extraBenefitRow' + refId).remove();
										}
									 }
									 )
		*/
		
		// rebove tbody group:
		if ($('extensionBenefitTable') && $('tb' + extensionRef))
		{
			$('tb' + extensionRef).remove();
		}
		// remove table?
		if ($('extensionBenefitTable') && $('extensionBenefitTable').rows.length <= 1)
		{
			$('extensionBenefitTable').remove();
			$('extensionBenefitTableHolder').remove();
		}
		
	},
	
	end : null
	
}

//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------

var effectsLogic = {
	edit : null,
	effectsTemplate : new Template('<tr><td><a href="Javascript:;" title="click to edit this effect" onclick="effectsLogic.editEffect(#{xindex});">#{itemType} </a></td><td>#{itemDescription}</td><td>#{itemMake}</td><td>#{itemModel}</td><td>$#{itemValue}</td><td><a href="Javascript:;" class="effectRemove" onclick="effectsLogic.removeEffect(#{xindex});">remove</a></td></tr>'),
	
	addEffect : function()
	{
		// from add button in effects window.
		// we're either editing an existing effect, or adding a new one.
		var effect = null;
		var form = document.forms[0];
		effect = Form.serializeElements([$('itemType'),$('itemDescription'),$('itemMake'), $('itemModel'),$('itemValue')],true);
		var isValid = true;
		// editing:
		if (effectsLogic.edit || effectsLogic.edit==0){
			if (effectsLogic.validate(effect)){
				// we're valid. delete existing entry and replace:	
				xinit.effects[effectsLogic.edit] = effect;
				xinit.effects[effectsLogic.edit].xindex = effectsLogic.edit;
				
				//effect = xinit.effects[effectsLogic.edit];
				effectsLogic.showList();
			}
			else isValid = false;
		}
		else{
			// adding new one
			if (effectsLogic.validate(effect)){
				// we're valid. Push:	
				var indexNo = xinit.effects.push(effect);
				xinit.effects[indexNo-1].xindex = indexNo-1;
				effect = xinit.effects[indexNo-1];
				var addRow = effectsLogic.effectsTemplate.evaluate(effect);
				$('effectsListTable').insert(addRow);
			}
			else isValid = false;
		}
		
		if ($('emptyEffects'))$('emptyEffects').hide();
	
		// update 'list':
		
		
		// update prices:
		effectsLogic.updatePrices();
		
		// empty fields: -- DON'T IF PRICE FAILS UPDATE
		if (isValid)
		{
			$('itemDescription','itemMake','itemModel','itemValue').invoke('clear');
			$('itemType').options.selectedIndex = 0;
			
			// remove edit var
			effectsLogic.edit = null;
			$('effectsButton').update('Add');
		}
		
		
		
		return isValid;
	},
	
	editEffect : function(effect)
	{
		//opens an effect for editing:
		// switch button
		$('effectsButton').update('Update');
		// set edit id to allow resave of same item...
		effectsLogic.edit = effect;
		$('itemDescription').value = xinit.effects[effect].itemDescription;
		$('itemMake').value = xinit.effects[effect].itemMake;
		$('itemModel').value = xinit.effects[effect].itemModel;
		$('itemValue').value = xinit.effects[effect].itemValue;
		$('itemType').value = xinit.effects[effect].itemType;


	},
	
	validate : function(effect)
	// validates the 'live' input boxes.
	{
		var isValid = true;
		var alertMsg = "";
		// clear fields:
		$$('#effectsAdd .invalidField').each(function(entry){entry.removeClassName('invalidField');});
		$('effectsMsg').removeClassName('invalidAlert');
		if ($('effectsMsg').originalText) $('effectsMsg').update($('effectsMsg').originalText);
		
		// strip non-alphanumerics from itemMake, itemModel, itemDescription;
		effect.itemMake = effect.itemMake.replace(/[^a-zA-Z 0-9]+/g,'');
		effect.itemModel = effect.itemModel.replace(/[^a-zA-Z 0-9]+/g,'');
		effect.itemDescription = effect.itemDescription.replace(/[^a-zA-Z 0-9]+/g,'');
		
		// description: not blank:
		//if (effect.itemDescription == ""){
		//	isValid = false;
		//	alertMsg = "Item Description must be provided."
		//	$('itemDescription').addClassName('invalidField')		
		//}
		
		// Type must be specified:
		if (effect.itemType == 0 || effect.itemMake =="" || effect.itemModel ==""){
			isValid = false;
			if (effect.itemType == 0){
				alertMsg = "Please specify the Type of Item to be added:";
				$('itemType').addClassName('invalidField');
			}
			if (effect.itemMake == ""){
				alertMsg += "\nPlease specify the Make of the Item.";
				$('itemMake').addClassName('invalidField');
			}
			if (effect.itemModel == ""){
				alertMsg += "\nPlease specify the Model of the Item.";
				$('itemModel').addClassName('invalidField');
			}
		}
		else {
		
			// can only continue with validation if item type is valid...
			
			
			// value numeric and not blank:
			if (effect.itemValue =="" || effect.itemValue == 0 || !validation.decimalExpression.test(effect.itemValue)) {
				isValid = false;
				alertMsg += (alertMsg !="" ? "<br/>" :"") + "Item value must be specified correctly. Numbers only.";
				if (effect.itemValue == 0) alertMsg += " Zero value not allowed.";
				$('itemValue').addClassName('invalidField')
			}
			
			// check item value against lookup
			// xinit.EffectsConfig.items.detect(function(item){return item.name=='Camera'}).itemValue
			
			// DOUBLE TOTAL LIMITS FOR FAMILY & DUO POLICIES...
			// individual item limit not doubled...
			// YES, WE DO KNOW THIS ALREADY, IT'S SET IN SCREEN _1_
			var multi = 1;
			if (xinit.currentPlanOption=="Duo" || xinit.currentPlanOption=="Family") multi = 2;
			
			var limits = xinit.EffectsConfig.items.detect(function(item){return item.name==effect.itemType});
			if (isValid){
				
				if (parseFloat(effect.itemValue) > limits.itemLimit) {
					
					isValid = false;
					alertMsg += (alertMsg !="" ? "<br/>" :"") + 'Item value for ' + effect.itemType + ' has a maximum per-item limit of $' + limits.itemLimit;
					$('itemValue').addClassName('invalidField')
				}
			}
			
			if (isValid){
				// check totals for ALL Items in *this* item type, haven't exceeded the limit
				// round effect.itemValue up to nearest pound.
				effect.itemValue = Math.round(effect.itemValue);
				
				var typeTotal = 0;
				var priceInType = xinit.effects.findAll(function(item){return item.itemType==effect.itemType});
				priceInType.pluck('itemValue').each(function(entry){typeTotal+=parseFloat(entry)});
				
				if ((typeTotal + parseFloat(effect.itemValue)) > (priceInType.totalItemLimit * multi)){
					isValid = false;
					alertMsg += (alertMsg !="" ? "<br/>" :"") + 'Total value for ' + effect.itemType + ' has exceeded its limit of $' + (multi*limits.totalItemLimit) + '. You cannot add any more items of this type.';
					$('itemValue').addClassName('invalidField')
					
				}
			}
			var effectsTotal = 0;
			var lastAddedValue = 0;
			if (isValid){
				// check total total hasn't exceeded the limit...
				
				xinit.effects.pluck('itemValue').each(function(entry){effectsTotal+=parseFloat(entry)});
				

				if ((effectsTotal + parseFloat(effect.itemValue)) > (multi * xinit.EffectsConfig.total)){
					isValid = false;
					alertMsg += (alertMsg !="" ? "<br/>" :"") + 'Total value for this Extension has exceeded its limit of $' + (multi*xinit.EffectsConfig.total) + '. You cannot add any more items to the policy.';
					$('itemValue').addClassName('invalidField');
					
				}
			}
		}
		
		if (alertMsg !=""){
			$('effectsMsg').originalText = $('effectsMsg').innerHTML;
			$('effectsMsg').addClassName('invalidAlert');
			$('effectsMsg').update('<span class="alert"></span><strong>Please Check and Try Again: </strong>' + alertMsg);
			$$(".alert").each(function(node){
										   			node.addClassName('animStart');
										   			new Effect.Pulsate(node,{pulses:2, afterFinish:validation.cleanUpAnimation});
										   })
		}
		else {
			// update and store total:
			effectsTotal += parseFloat(effect.itemValue);
			xinit.effects.total = effectsTotal;
			$('effectsTotal').update('<p>Total value covered: $' + maths.addCommas(effectsTotal) +'</p>');	
		}
		
		return isValid;
	},
	
	removeEffect : function(effect)
	{
		// kill array entry
		xinit.effects.splice(effect,1);

		// recalc prices
		
		// redraw list
		effectsLogic.showList();
		
	},
	
	showList : function()
	{
		// called on opening of window.
		// kill the 'empty' message.
		// if no items, re-add the empty message.
		
		$('effectsList').update('');
		
		
		var effectsList = "";
		//var emptyEffects = "";

		if (xinit.effects.length >0){
			//emptyEffects = "";
			xinit.effects.each(function(entry,index){
										entry.xindex = index;
			effectsList += effectsLogic.effectsTemplate.evaluate(entry,index);
										})
			
		}
		
		
		$('effectsList').update('<div><table width="100%"  cellpadding="2" cellspacing="2" border="0" id="effectsListTable"><thead><tr><th width="20%">Item Type</th><th width="18%">Description:</th><th width="18%">Make:</th><th width="18%">Model:</th><th width="15%">Value:</th><th width="11%"></th></tr></thead><tbody>' + (effectsList !="" ? effectsList : '<tr id="emptyEffects"><td colspan="6">No Items Added Yet.</td></tr>') + '</tbody></table></div>');
		
		var effectsTotal = 0;
		xinit.effects.pluck('itemValue').each(function(entry){effectsTotal+=parseFloat(entry)});
		xinit.effects.total = effectsTotal;
		$('effectsTotal').update('<p>Total value covered: $' + maths.addCommas(effectsTotal)+'</p>');	
		
	},
	
	updatePrices : function()
	{
		
		
	},
	
	okayEffect : function()
	{
		// if, say value is filled in, validate and add before closing.
		//if ($F('itemValue') !="")
		//{
			//if (!effectsLogic.addEffect()) return false;

		//}
		// untick: IF NO ADDED EFFECTS
		if (xinit.effects.length == 0){
			$('checkExt-Effects').checked = false;
			$('editEffects').hide();
			benefitLogic.removeExtensionBenefit('Effects');
			
		}
		
		policyLogic.addExtensions();
		windowing.fadeKillWindow();
	},
	
	cancelEffect : function()
	{
		// untick: IF NO ADDED EFFECTS
		if (xinit.effects.length == 0){
			$('checkExt-Effects').checked = false;
			$('editEffects').hide();
			benefitLogic.removeExtensionBenefit('Effects');
			
		}
		// update costs for effects...
		
		policyLogic.addExtensions();
		
		windowing.fadeKillWindow();
	},
	
	getEffectsTotal : function()
	// called from policyLogic.doPolicyMaths -- priceStream array calc.
	{
		var total = 0;
		
		xinit.effects.each(function(entry){
										total = total + parseFloat(entry.itemValue);
									});
		
	
		return total;
		
	},
	
	
	end : null	
	
}
//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------
var paymentLogic = {
	
	processForPayment : function(cartId)
	{
		//create payment provicer specific data, and POST the form to them.
		// triggered after AJAX success.
		$('cost').value = xinit.policyCost;
		$('cartId').value = cartId;
		$('name').value = $F('mondial_QE_title1') + ' ' + $F('mondial_QE_firstName1') + ' ' + $F('mondial_QE_lastName1');
		$('postcode').value = $F('mondial_QE_postCode');
		$('address').value = $F('mondial_QE_address1') + ", " + $F('mondial_QE_address2') + ($F('mondial_QE_address2')!="" ? ', ' : '') + $F('mondial_QE_city') + ', ' + $F('mondial_QE_province');
		$('tel').value =  $F('mondial_QE_telephone1') + '' + $F('mondial_QE_telephone2');
		$('email').value = $F('mondial_QE_email');
		
		
		document.forms['WORLDPAY'].submit();
		
		//window.location.href = "mondialPaymentProcess?openagent&paymentStatus=y&policyRef=" + cartId;
	},
	
	end : null
	

}

//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------
var dateLogic = {
	
	getUKDate : function(value,isDOB)
	// attempts to turn a DD/MM/YYYY value into a valid date object.
	// check that YYYY is > now's year -- effectively 4 digits....
	// check that MM < 12 -- uk date format
	// check that DD < num of days in that month???
	// return 'error' if not..
	{
		if (value=="") return false;
		var result = '';
		var today = new Date();
		today.setHours(0);
		today.setMinutes(0);
		today.setSeconds(0);
		today.setMilliseconds(0);
		var dateArray = value.split('/');
		// check for 3 parts
		if (dateArray.length <3)return false;
		// parts:
		var day = parseInt(dateArray[0],10);
		var month = parseInt(dateArray[1],10);
		var year = parseInt(dateArray[2],10);
		// check year > now
		if (isNaN(year) || (isDOB != true && year < today.getFullYear())) return false;
				
		// check Month <=12 ? Not UK Format
		if (month > 12) return false;
		// check day <= number of days in month
		var monthDays = [31,29,31,30,31,30,31,31,30,31,30,31];
		if (day > monthDays[month-1]) return false;
		
		var validDate = new Date(month + '/' + day + '/' + year + ' 00:00');
		
		
		if (isDOB !=true && validDate < today) return false;
		
		// if isDOB and future date, fail:
		if (isDOB ==true && validDate > today) return false;
		
		return validDate;
	},
	
	getDays : function (date1, date2) {
	// gets number of days between two date(object)s...
	
		// The number of milliseconds in one day
		var ONE_DAY = 1000 * 60 * 60 * 24
	
		// Convert both dates to milliseconds
		var date1_ms = date1.getTime()
		var date2_ms = date2.getTime()
	
		// Calculate the difference in milliseconds
		var difference_ms = Math.abs(date1_ms - date2_ms)
		
		// Convert back to days and return
		return Math.round(difference_ms/ONE_DAY)
	
	},
	getMonths : function (date1, date2) {
	// gets number of MONTHS between two date(object)s...
	
		var usrDate = date1;
		var curDate = date2;
		var usrYear, usrMonth = usrDate.getMonth()+1;
		var curYear, curMonth = curDate.getMonth()+1;
		if((usrYear=usrDate.getFullYear()) < (curYear=curDate.getFullYear())){
			curMonth += (curYear - usrYear) * 12;
		}
		var diffMonths = curMonth - usrMonth;
		if(usrDate.getDate() > curDate.getDate()) diffMonths--;
		
		return diffMonths;
			
	},
	
	end : null

}