var pensionCalculator = new PensionCalculator();

function PensionCalculator() {

	var name = "Pension Calculator";	
	var calculatorURL = "/pension-sales-web/pensionCalculator/GetPensionCalculation.do";
	var assumptionsPopupURL = "/virgin/pension/popups/pensionCalculatorAssumptions.jsp";
	var childAssumptionsPopupURL = "/virgin/pension/popups/pensionCalculatorAssumptionsChild.jsp";
	var genericErrorObject = {"errorMessage":{"errorMessageKey":"genericException","errorDefaultMessage":"Unable to retrieve pension calculation<p>For calculations where there's less than ten years between current age and retirement age, call us on 08456 10 20 40</p>"}};
	var pensionCalculationResult = null;
	var properties = new Hash();
	var effects = new Effects();
	
                this.prepopulateValuesFromCookies = prepopulateValuesFromCookies;
	function prepopulateValuesFromCookies() {
		$$(".inputCalculatorParameter").each(function(s){
			var name = s.name.split('.');
			var persistedValue = getCookieValue(name[0] + "." + name[1]).split('=')[1];
			if(persistedValue) {
				if(s.type == 'radio') {
					if(s.value == persistedValue) s.checked = true;
				} else {
					s.value = persistedValue;
				}
			}
		});
	}

	this.getPensionCalculation = getPensionCalculation;
	function getPensionCalculation() {
		
		if(checkForInputsUpdate()) {
		
			getEffects().clearFieldErrors();
		
                                                if($('employerpayments-content')) {
                                                    if($('employerpayments-content').style.display == 'none') {
                                                        $('employerLumpSumAmount').value = "";
                                                        $('employerRegularPaymentAmount').value = ""; 
                                                    }
                                                }

			$$('.inputCalculatorParameter').each(function(s) {
				if(s.type == 'radio' && s.checked == true) {
					handleRadioInputs(s.name, s.value);			
				} else if(s.type != 'radio'){
                                                                        if(s.name == "pensionCalculation.regularPaymentAmount" || s.name == "pensionCalculation.lumpSumAmount") {
                                                                                var value = s.value.replace("£", "").replace("\.00", "");
					properties.set(s.name, value);
                                                                        } else {
                                                                                properties.set(s.name, s.value);
                                                                        }
				}
			});
	
			effects.showLoadingScreen('calculatorpanel-content');
	
			new Ajax.Request(calculatorURL, {
				parameters: properties,
				onSuccess: onSuccess,
				onFailure: onFailure,
				onException: onException,
				onCreate: onCreate,
				onComplete: onComplete
			});							
			
		} else {
			displayCalculationResults(pensionCalculationResult.pensionCalculationResultWrapper.calculationResults);
                                                getEffects().showResultsPanel();
		}
	}
	
	function handleRadioInputs(name, value) {	
		var fragments = name.split('.');
		var propertyName = fragments[0] + "." + fragments[1];
		properties.set(propertyName, value);
	}
	
	this.getCalculatorURL = getCalculatorURL;
	function getCalculatorURL() {
		return calculatorURL;
	}
	
	this.setCalculatorURL = setCalculatorURL;
	function setCalculatorURL(url) {
		calculatorURL = url;
	}
	
	this.getAssumptionsPopupURL = getAssumptionsPopupURL;
	function getAssumptionsPopupURL() {
		return assumptionsPopupURL;
	}
	
	this.setAssumptionsPopupURL = setAssumptionsPopupURL;
	function setAssumptionsPopupURL(url) {
		assumptionsPopupURL = url;
	}
	
	this.getPensionCalculationResult = getPensionCalculationResult;
	function getPensionCalculationResult() {
		return pensionCalculationResult;
	}
	
	function handleResponseErrors(errors) {
		try {
			errors.errorMessage.each(function(s) {
				$(s.errorMessageKey).innerHTML = s.errorDefaultMessage;
				$(s.errorMessageKey).parentNode.style.display = "block";
				var crossKey = s.errorMessageKey.split('.');
				if(crossKey.length < 2) {
                                                                           var  crossKeyId = $(crossKey[0] + ".cross");
                                                                           if(crossKeyId) {
                                                                               crossKeyId.style.display = "inline";
                                                                           } else {
                                                                               var crosses = document.getElementsByName(crossKey[0] + ".cross");
                                                                               for(var i = 0; i < crosses.length; i++) {
                                                                                   crosses[i].style.display = "inline";
                                                                               }
                                                                          }
                                                                } else {
                                                                           var crossKeyId = $(crossKey[0] + "." + crossKey[1] + ".cross");
                                                                           if(crossKeyId) {
                                                                               crossKeyId.style.display = "inline";
                                                                           } else {
                                                                               var crosses = document.getElementsByName(crossKey[0] + "." + crossKey[1] + ".cross");
                                                                               for(var i = 0; i < crosses.length; i++) {
                                                                                   crosses[i].style.display = "inline";
                                                                               }
                                                                          }
                                                                }
                                                                
			});	
		} catch(err) {
			$(errors.errorMessage.errorMessageKey).innerHTML = errors.errorMessage.errorDefaultMessage;
			$(errors.errorMessage.errorMessageKey).parentNode.style.display = "block";	
			var crossKey = errors.errorMessage.errorMessageKey.split('.');
			if(crossKey.length < 2) {
                                                                           var  crossKeyId = $(crossKey[0] + ".cross");
                                                                           if(crossKeyId) {
                                                                               crossKeyId.style.display = "inline";
                                                                           } else {
                                                                               var crosses = document.getElementsByName(crossKey[0] + ".cross");
                                                                               for(var i = 0; i < crosses.length; i++) {
                                                                                   crosses[i].style.display = "inline";
                                                                               }
                                                                          }
                                                                } else {
                                                                           var crossKeyId = $(crossKey[0] + "." + crossKey[1] + ".cross");
                                                                           if(crossKeyId) {
                                                                               crossKeyId.style.display = "inline";
                                                                           } else {
                                                                               var crosses = document.getElementsByName(crossKey[0] + "." + crossKey[1] + ".cross");
                                                                               for(var i = 0; i < crosses.length; i++) {
                                                                                   crosses[i].style.display = "inline";
                                                                               }
                                                                          }
                                                                }
		}
	}
	
	function displayCalculationResults(results) {
	
		$('totalWithoutEscalation').innerHTML = "&pound;" + results.actualValuesWithoutEscalation.fundValue;
		$('annualWithoutEscalation').innerHTML = "&pound;" + results.actualValuesWithoutEscalation.annualPension;
		
		$('totalWithEscalation').innerHTML = "&pound;" + results.actualValuesWithEscalation.fundValue;
		$('annualWithEscalation').innerHTML = "&pound;" + results.actualValuesWithEscalation.annualPension;
		
		$('todaysWithoutEscalation').innerHTML = "&pound;" + results.todaysMoneyWithoutEscalation.annualPension;
		$('todaysWithEscalation').innerHTML = "&pound;" + results.todaysMoneyWithEscalation.annualPension;
		
		$('retirementYear').innerHTML = results.retirementYear;
                                $('costOfDelay').innerHTML = results.costOfDelay.costOfDelayAmount;

	}
	
	function updateResultField(name, value) {
		$(name).innerHTML = value;
	}
	
	function checkForInputsUpdate() {
	
		if(properties.size() == 0) return true;
		
		var result = true
		var inputs = $$('.inputCalculatorParameter');
		inputs.each(function(s) {
			if(s.type == 'radio' && s.checked == false) return; //behaves like continue
			var name = s.name.split('.');
			if(!properties.get(name[0] + "." + name[1]) == s.value) {
				//result = true;
			}
		});
		return result;
	}
	
	this.exclusiveRadioButton = exclusiveRadioButton;
	function exclusiveRadioButton(group, radio) {
		$$('.' + group).each(function(s){
			if(s.name != radio.name) {
				s.checked = false;
			}
		});		
	}
	
	this.displayAssumptions = displayAssumptions;
	function displayAssumptions() {
		var retirementYear = pensionCalculationResult.pensionCalculationResultWrapper.calculationResults.retirementYear;
		var finalIncrementingPaymentAmount = pensionCalculationResult.pensionCalculationResultWrapper.calculationResults.actualValuesWithEscalation.finalRegularPaymentAmount;
		var url = assumptionsPopupURL + "?finalIncrementingPaymentAmount=" + finalIncrementingPaymentAmount + "&retirementYear=" + retirementYear;
		var options = "width=600,height=400,resizable=1";
		window.open(url, "assumptionsPopup", options);
	}

                this.displayAssumptionsChild = displayAssumptionsChild;
	function displayAssumptionsChild() {
		var retirementYear = pensionCalculationResult.pensionCalculationResultWrapper.calculationResults.retirementYear;
		var finalIncrementingPaymentAmount = pensionCalculationResult.pensionCalculationResultWrapper.calculationResults.actualValuesWithEscalation.finalRegularPaymentAmount;
		var url = childAssumptionsPopupURL + "?finalIncrementingPaymentAmount=" + finalIncrementingPaymentAmount + "&retirementYear=" + retirementYear;
		var options = "width=600,height=400,resizable=1";
		window.open(url, "assumptionsPopup", options);
	}
	
	this.openHelpPopup = openHelpPopup;
	function openHelpPopup(url) {
	
		var options = "width=600,height=300,resizable=1";
		window.open(url, "helpPopup", options);
	}
	
	function persistInputValues() {
		properties.each(function(s){
			document.cookie = s.key + "=" + s.value + ";";
		});
	}
	
	function onSuccess(transport) {
		pensionCalculationResult = transport.responseText.evalJSON();
		if(pensionCalculationResult.pensionCalculationResultWrapper.ok == 'false') {
			handleResponseErrors(pensionCalculationResult.pensionCalculationResultWrapper.errors);
		} else {
			displayCalculationResults(pensionCalculationResult.pensionCalculationResultWrapper.calculationResults);		
			getEffects().showResultsPanel();
			persistInputValues();
		}
		getEffects().removeLoadingScreen();
	}
	
	function onFailure(transport, exception) {
		handleResponseErrors(genericErrorObject);
		getEffects().removeLoadingScreen();
	}
	
	function onException(transport, exception) {
		handleResponseErrors(genericErrorObject);
		getEffects().removeLoadingScreen();
	}
	
	function onCreate(transport) {
	
	}
	
	function onComplete(transport) {
		
	}
		
	this.getEffects = getEffects;
	function getEffects() {
		return effects;
	}
	
	//================================================= EFFECTS SUBSYSTEM =================================================//
	
	function Effects() {
	
		var slideDuration = 1.5;
		var loadingDivId = 'loadingDiv';
		var loadingOpacity = 0.4;
		var calculatorPanelPadding = 2;
		var resultsPanelLink = "javascript:pensionCalculator.getPensionCalculation();";
		var calculatorPanelLink = "javascript:pensionCalculator.getEffects().showCalculatorPanel();";
	
		//============================================ CREATE IMAGE CACHE ============================================//
	
		var imageCache = new Array();
			
		var expandHeaderMinus = new Image();
		expandHeaderMinus.src = '/virgin/Images/expand-header-minus_tcm23-5184.gif';
		imageCache['/virgin/Images/expand-header-minus_tcm23-5184.gif'] = expandHeaderMinus;	

		var expandHeaderPlus = new Image();
		expandHeaderPlus.src = '/virgin/Images/expand-header-plus_tcm23-5185.gif';
		imageCache['/virgin/Images/expand-header-plus_tcm23-5185.gif'] = expandHeaderPlus;

		var downArrow = new Image();
		downArrow.src = '/virgin/Images/dropdown-arrow_tcm23-5183.gif';
		imageCache['/virgin/Images/dropdown-arrow_tcm23-5183.gif'] = downArrow;	

		var questionArrow = new Image(); 
		questionArrow.src = '/virgin/Images/dropdown-arrow-off_tcm23-5182.gif';
		imageCache['/virgin/Images/dropdown-arrow-off_tcm23-5182.gif'] = questionArrow;	
		
		var loading = new Image();
		loading.src = '/virgin/Images/loading_tcm23-5187.gif';
		imageCache['/virgin/Images/loading_tcm23-5187.gif'] = loading;

		//============================================ CREATE IMAGE CACHE ============================================//
	
		this.switchPanelVisibility = switchPanelVisibility;
		function switchPanelVisibility(element, imageID, onImage, offImage) {
			if($(element).style.display == "none") {
				displayPanel($(element));
				setImage(imageID, onImage)
			} else {
				hidePanel($(element));
				setImage(imageID, offImage);
			}
		}
		
		this.showResultsPanel = showResultsPanel;
		function showResultsPanel() {
			$('calculatorPanelLink').href = calculatorPanelLink;
			$('resultsPanelLink').href = "javascript:void(0);";
			slideUp('calculatorpanel-content');
			setImage('calculator-header-arrow', '/virgin/Images/dropdown-arrow-off_tcm23-5182.gif');
			setImage('result-header-arrow', '/virgin/Images/dropdown-arrow_tcm23-5183.gif');
			slideDown('resultspanel-content');					
		}
		
		this.showCalculatorPanel = showCalculatorPanel;
		function showCalculatorPanel() {
			$('calculatorPanelLink').href = "javascript:void(0);";
			$('resultsPanelLink').href = resultsPanelLink;
			slideUp('resultspanel-content');					
			setImage('result-header-arrow', '/virgin/Images/dropdown-arrow-off_tcm23-5182.gif');
			clearFieldErrors();
			slideDown('calculatorpanel-content');
			setImage('calculator-header-arrow', '/virgin/Images/dropdown-arrow_tcm23-5183.gif');
		}

		this.clearFieldErrors = clearFieldErrors;
		function clearFieldErrors() {
			$$('.fieldError').each(function(s){
				s.style.display = 'none';
			});
			$$('.topLevelFieldError').each(function(s){
							s.style.display = 'none';
			});
			$$('.fieldErrorCross').each(function(s){
				s.style.display = 'none';
			});
		}
		
		this.getSlideDuration = getSlideDuration;
		function getSlideDuration() {
			return slideDuration;
		}
		
		this.setSlideDuration = setSlideDuration;
		function setSlideDuration(duration) {
			slideDuration = duration;
		}
		
		this.showLoadingScreen = showLoadingScreen;
		function showLoadingScreen(elementID) {
		
			var element = $(elementID);
			var loadingDiv = new Element('DIV');			
			var img = imageCache['/virgin/Images/loading_tcm23-5187.gif'];
			
			element.parentNode.appendChild(loadingDiv);
			loadingDiv.style.height = element.getHeight() + calculatorPanelPadding + 'px';
			loadingDiv.style.top = element.offsetTop + 'px';
			loadingDiv.style.width = element.getWidth() + 'px';
			loadingDiv.style.position = 'absolute';
			loadingDiv.style.backgroundColor = '#808080';
			loadingDiv.setOpacity(loadingOpacity);
			loadingDiv.id = loadingDivId;
			loadingDiv.style.display = 'block';			
			loadingDiv.style.visibility = 'hidden';
					
			loadingDiv.appendChild(img);
			img.style.left = ((loadingDiv.getWidth() * 0.5) - (img.width * 0.5)) + 'px';
			img.style.top = ((loadingDiv.getHeight() * 0.5) - (img.height * 0.5)) + 'px';
			img.style.position = 'absolute';
			img.style.display = 'block';
			
			loadingDiv.style.visibility = 'visible';
		}
		
		this.removeLoadingScreen = removeLoadingScreen;
		function removeLoadingScreen() {
			$(loadingDivId).remove();
		}
		
		function setImage(imageID, imageSrc) {
			var image = imageCache[imageSrc];
			if(image == undefined) {
				var unknownImage = new Image();
				unknownImage.src = imageSrc;
				imageCache[imageSrc] = unknownImage;
				$(imageID).src = unknownImage.src;
			} else {
				$(imageID).src = image.src;
			}
		}
	
		function slideDown(elementID) {
			Effect.BlindDown(elementID, { duration: slideDuration });	
		}
		
		function slideUp(elementID) {
			Effect.BlindUp(elementID, { duration: slideDuration });	
		}

		function displayPanel(element) {
			element.style.display = "block";
		}
		
		function hidePanel(element) {
			element.style.display = "none";
		}
	}
	
	//================================================= EFFECTS SUBSYSTEM =================================================//
}