/*	*********************************
	Open Platform JS Library requires JQuery
	*********************************

	================
	DO NOT WORD WRAP
	================
	
	Modifications:
	Date	Author				Description
	============================================================================
	27/7/7	Craig Mitchell		Created Library

*/

/* **** Shared constants **** */
var current_tax_year = '2009/2010'; // Update when updating constants below - shown to user in Assumptions in pensions calc
var calculation_date = new Date();	//[required in order to calculate year of birth for use in annuity rate calculation]
var growth_rate = 0.07;	//[assume FSA mid growth assumption - needs to be reviewed for each 6 April]
var price_inflation_rate = 0.025;	//[assume FSA mid growth assumption - needs to be reviewed for each 6 April]
var inflation_rate = price_inflation_rate;
var salary_inflation_rate = 0.025;	//[assume equal to price inflation rate - this means calculation based on % of salary contributions will match calculation based on monetary contributions]
var annuity_interest_rate = 0.006;	//[assume FSA mid growth assumption for index-linked annuities - needs to be reviewed for each 6 April]
var annuity_escalation_rate	= 0.00;	//[standard assumption - in conjunction with annuity interest rate, setting this to zero => index-linked annuities]
var annuity_term_certain = 5;	//[standard assumption]
var annuity_spouses_percentage = 0.5;	//[only used if married]
var annuity_spouses_age_difference = 3;	//[only used if married]
var annual_management_charge = 0.01;	//[standard assumption  - needs to be reviewed for each 6 April (not part of FSA basis, but should be regularly reviewed)]
var basic_state_pension_week = 95.25;
var basic_state_pension_week_couple = 152.30;
var basic_state_pension = basic_state_pension_week*52;  // - [standard assumption  - needs to be updated for each 6 April]

function replaceConstants() {
	$('span.growth_rate').empty().append(formatPC(growth_rate));

	$('span.inflation_rate').empty().append(formatPC(price_inflation_rate));
	$('span.salary_inflation_rate').empty().append(formatPC(salary_inflation_rate));
	$('span.price_inflation_rate').empty().append(formatPC(price_inflation_rate));

	$('span.annuity_interest_rate').empty().append(formatPC(annuity_interest_rate));
	$('span.annuity_escalation_rate').empty().append(formatPC(annuity_escalation_rate));
	$('span.annuity_term_certain').empty().append(annuity_term_certain);
	$('span.annuity_spouses_percentage').empty().append(formatPC(annuity_spouses_percentage));
	$('span.annuity_spouses_age_difference').empty().append(annuity_spouses_age_difference);
	$('span.annual_management_charge').empty().append(formatPC(annual_management_charge));
	$('span.basic_state_pension').empty().append(basic_state_pension);

	$('span.current_tax_year').empty().append(current_tax_year);
}

/* HTML Tidy Up - rounded corners et all */
$(document).ready(function(){
	replaceConstants();

	$('input').each(function(){
		if(!this.name) { this.name=this.id; }
		$(this).addClass(this.type); 
	});
	
	// Guide pages have a pattern where there is link to print a bunch of questions.
	// These links have a class of lighterGreyBoxPrinter, which will cause them to print
	// any sibling greyBox containers.
	// We also modify the default print beahviour to do nothing if this handler
	// will also be attached.
	$('.lighterGreyBoxPrinter').click(function() {
		var wrapper = document.createElement('div');
		wrapper.id = 'printableSummary';
		//var subjects = $(this).parent().parent().parent().parent().parent().siblings('.lighterGreyBox').clone();
		var subjects = $(this).parent().siblings('.lighterGreyBox').clone();
		openPrintWindowFromSelector(subjects);
		return false;
	});

	// Totally standard buttons
	$('#frmCalc').submit(function() { calculate(); watchFields(); return false; });
	$('#submit_calc').click(function() { calculate(); watchFields(); });

	$('.btn_save').click(function() { saveForm(); disableButtons($('.btn_delete'), false); alert('Your details have been saved'); return false; });
	$('.btn_delete').each(function() { disableButtons(this, true); }).click(function() { sC(cookieprefix+'details', ''); disableButtons($('.btn_delete'), true); return false; });
	$('.btn_restart').click(function() { 
		if(gC(cookieprefix+'details').length!=0) {
			if (confirm('You have already saved your details. Do you wish to delete them?')) { $('.btn_delete').click(); location.reload(); }
		} else { location.reload(); }
		return false;
	});
	$('.btn_adviser_contact').click(contact_adviser);
	
	$('.btn_print').not('.lighterGreyBoxPrinter').click(function() {
		if(typeof(calculate)=="undefined") {
			window.print();
		} else {
			if(calculate(false)) { window.print(); }
		}
		return false;
	});

	$('.btn_print_summary').click(function() {
		if(calculate(false)) {
			openPrintWindowFromSelector('.printableSummary > *');
		}
		return false;
	});

	if($.browser.msie) {
		$(window).resize(function() {
			var hc = document.getElementById('hc');
			var alignwith = ($shnh=$('.site-header-non-homepage')).length>0 ? $shnh[0] : null; 
			var outerpos = alignwith ? getAbsLeft(alignwith) : 0;
			if(hc && alignwith) {
				hc.style.position='absolute';
				hc.style.left=outerpos+'px';
				var otherHeight=$("div.strapLine").height()+$("p.next").height();
				hc.parentNode.style.height=(hc.offsetHeight+otherHeight)+'px';
			}
		});
		var hc = document.getElementById('hc');
		hc.onresize=function() { 
			//var otherHeight=getSiblingsOffSet(this, "h");
			var otherHeight=$("div.strapLine").height()+$("p.next").height();
			this.parentNode.style.height=(this.offsetHeight+otherHeight)+'px';
		}
	}
	
	// Hide all definitions with what is this link
	$('.definition').each(function(){
		var def=this.innerHTML;
		var link=!$(this).attr('link')?'what is this?':$(this).attr('link');
		$(this).empty().append(' <a href="#" class="definitionlink" def="'+escape(def)+'" link="'+escape(link)+'">'+link+'<\/a>');
		$(this).children().filter('a.definitionlink').click(function() {
			var link=!$(this).attr('link')?'what is this?':$(this).attr('link');
			if(!$(this).attr('expanded') || $(this).attr('expanded')=='false') {
				$(this).parent().prepend('<span class="showdef"><br/>'+unescape($(this).attr('def'))+'</span>').addClass('xdefinitionbox');
				$(this).attr('expanded', true);
				$(this)[0].innerHTML='close';
			} else {
				$(this).parent().removeClass('xdefinitionbox').children().remove('.showdef'); 
				$(this).attr('expanded', false);
				$(this)[0].innerHTML=unescape(link);
			}
			return false;
		});
	});
	
	setupTooltips('.tooltip', '.thickboxcontent');
});

function getSiblingsOffSet(node, dimension) {
	var container = node.parentNode;
	var totalOffset=0;
	for(var i=0; i< container.childNodes.length; i++) {
		var tmpNode=container.childNodes[i];
		if(tmpNode!=node) {
			switch(dimension.toLowerCase()) {
				case "x":
					totalOffset+=tmpNode.offsetLeft;
					break;
				case "y":
					totalOffset+=tmpNode.offsetTop;
					break;
				case "w":
					totalOffset+=tmpNode.offsetWidth;
					break;
				case "h":
					totalOffset+=tmpNode.offsetHeight;
					break;
				}
		}
	}
	return totalOffset;
}

function show_error (message) {
	if (document.getElementById('error_message').innerHTML.indexOf(message)==-1) {
		$('#error_message').append('<li>'+message+'<\/li>').parent().show();
	}
}

function focus_on_error() {
	var error_message=document.getElementById('error_message');
	var error_y=getAbsTop(error_message.parentNode);
	window.scrollTo(0, error_y);
}


/*****************************************/
/* Variables for passing info to contact */
/*****************************************/
var contactcookie='contactdetails';
var cookietitle='calcname';
var contacturl='contact.html';

/**** Cookie Save/Get Functions ***/
function sC(name,value) {
expiry = 'Friday, 31-Dec-2020 08:00:00 GMT';
//if (arguments.length==3) {
	//if (arguments[2]) {
		dt = new Date();
		dt.setUTCMinutes(dt.getUTCMinutes()+180);
		expiry = dt.toGMTString();
	//}
//}
document.cookie=name+'='+escape(value)+'; expires='+expiry+'; path=/';
} 

function gC(name) {
	value='';
	index=document.cookie.indexOf(name+'=');
	if (index == -1) { return ''; }
	countbegin=(document.cookie.indexOf('=',index)+1);
	countend=document.cookie.indexOf(';',index);
	if(countend==-1) { countend=document.cookie.length; }
	value = document.cookie.substring(countbegin,countend);
	return unescape(value);
} 
/* End cookie monster */

/**** Check a value is a valid number ****/
function isaN(value) {
	if (value.length==0) { return false; }
	var fV = parseFloat(value);
	return (!isNaN(fV));
}
/* End Is A Number */

/**** Scottish Widow's is_numeric function ****/
function is_numeric(string_to_check){ 
	var valid_chars = "0123456789.-", character, result = true;

	if(string_to_check.length == 0) return false;

	for(i = 0; i < string_to_check.length && result; i++){ 
		character = string_to_check.charAt(i); 
		if(valid_chars.indexOf(character) == -1){ result = false; } 
	} 
	return result; 
}
/* End Is Numeric */

/**** Formats a currency value ****/
function formatPrice(value) {
	var currency = arguments.length>=2?arguments[1]:'&pound;';
	var showpence = arguments.length>=3?arguments[2]: true;
	if (!isNaN(value)) {
		value=new String(value);
		var point = value.lastIndexOf('.');
		if (showpence) {
			if (point==-1) { 
				value=value+'.00';
			} else {
				if (point<(value.length-3)) { value=value.slice(0, point+3);}
				if (point>(value.length-3)) { value=value+'0';}
			}
		} else {
			if (point!=-1) { value = value.slice(0, point-1); }
		}
		return (currency+value);
	} else {
		return (value);
	}
}
/* End format price */

function scrollToObj(obj) {
	if(!obj) { obj=document.getElementById(obj); }
	if(obj && window.scrollTo) {
		var ypos=getAbsTop(obj);
		ypos += arguments.length > 1 ? arguments[1] : 0;
		window.scrollTo(0, ypos);
	}
}

/**** Absolute Positioning of DOM objects ****/
function getAbsLeft(obj) {
	return (obj.offsetLeft+(obj.offsetParent?getAbsLeft(obj.offsetParent):0));
}

function getAbsTop(obj) {
	return (obj.offsetTop+(obj.offsetParent?getAbsTop(obj.offsetParent):0));
}
/* End abs positioning */

function formatPC(amt) { 
	var output =round_number(amt*100, 1);
	
	/* No more rounding to 2dp if not required
	if ((output*10)%10==0) {
		output =output+'.00';
	} else if ((output*10)%1==0) {
		output =output+'0';
	}
	*/
	return (output);
	
}

function round_number(number, decimal_places){
	return (Math.round(number * Math.pow(10, decimal_places)) / Math.pow(10,decimal_places));
}

/****************************************************************************/
/*								Scottish Widows								*/
/*							Calculator   Functions							*/
/****************************************************************************/

function calculate_savings(termyears,monthlyamount,anngrowthrate,inflation,initialdeposit) {
	/* 
		function to return the amount of savings a user might have after x years
		termyears = duration in years that the user wants to save for
		monthlyamount = the amount hey wish to save each month.
		anngrowthrate = the assumed interest/growthrate (e.g 6)
		inflation (e.g 2.5)
		initialdeposit = amount hte user initially invests
	*/

	var monthlygrowthrate = Math.pow(1 + (anngrowthrate / 100.00), (1/12.00)) - 1;
	//var totalamount = (monthlyamount / monthlygrowthrate) * (Math.pow((1 + monthlygrowthrate),(12 * termyears)) - 1);
	var totalamount = initialdeposit * Math.pow((1 + (anngrowthrate / 100)) ,termyears) +  (monthlyamount / monthlygrowthrate) * (Math.pow((1 + monthlygrowthrate),(12 * termyears)) - 1);
	var totalamountadjustedinflation = totalamount / Math.pow((1 + (inflation / 100.00)),termyears);

	return (totalamountadjustedinflation);
};

function calculate_lump_sum(termyears,amount,anngrowthrate,inflation, initiallumpsum) {
	/*
		function to return the monthly amounts required to receive a specific lump sum in x years.
		termyears = duration in years that the user wants to save for
		amount = the amount they wish to save for.
		anngrowthrate = the assumed interest/growthrate (e.g 6)
		inflation (e.g 2.5)
		initiallumpsum = the value teh user wants to initially invest
	*/
	var monthlygrowthrate = Math.pow((1 + (anngrowthrate / 100)), (1/12)) - 1;
	var yearlyamountrequiredwithinflation = amount * Math.pow((1 + (inflation / 100)),termyears)
	var monthlyamountrequiredwithinflation = (yearlyamountrequiredwithinflation * monthlygrowthrate) / (Math.pow((1 + monthlygrowthrate),(12 * termyears)) - 1)
	return (monthlyamountrequiredwithinflation)
};

function contact_adviser() {
	saveForm(contactcookie);
	sC(cookieprefix+cookietitle, document.title);
	location.href=contacturl+'?prefix='+cookieprefix;
	return false;
}
/****************************************************************************/

function disableButtons(ctls, state) {
	var targets = (ctls.length) ? ctls : new Array(ctls);

	for (var i=0; i<targets.length; i++) {
		var targetstate = state==null ? !targets[i].disabled : state;
		targets[i].disabled = targetstate;
		targets[i].style.cursor = targetstate ? 'default' : 'pointer';
		if (state) {
      $(targets[i]).addClass('disabledButton');
    } else {
      $(targets[i]).removeClass('disabledButton');
    }
	}
}

/**
 * Opens print_window.html and populates its body with all elements matching
 * the selector.
 * 
 * @param selector elements to add to print window
 */
function openPrintWindowFromSelector(selector) {
	
	var prefix = '';
	if (window.location.href.indexOf('guides') !== -1) {
		prefix =  '../../calculators/';
	}
	
	var template = "" +
		"<html>" +
		"<head>" +
		"<title>Print Window</title>" +
		"<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\">" +
		"<title>Personal Budget calculator</title>" +
		"<link href=\"" + prefix + "../stylesheet/healthcheck.css\" rel=\"stylesheet\" type=\"text/css\">" +
		"<link href=\"" + prefix + "../stylesheet/print-summary.css\" rel=\"stylesheet\" type=\"text/css\">" +
		"<link href=\"" + prefix + "../stylesheet/print-summary-print.css\" media=\"print\" rel=\"stylesheet\" type=\"text/css\">" +
		"<script src=\"" + prefix + "../../js/jquery-1.3.1.min.js\"></script>" +
		"<script src=\"" + prefix + "../js/printHelpers.js\"></script>" +
		"<style>a.tooltip { display: none; }</style>" +
		"</head>" +
		"<body id='printWindow'><div id='printableSummary'>";
	if (typeof(selector) == 'string') selector = $(selector);
	
	selector.clone(true).each(function() {
		var div = document.createElement('div');
		div.appendChild(this);
		template += div.innerHTML;
	});

	template += "</div></body></html>";
	
	var w = window.open(prefix + "print_window.html", "_blank", "width=640,height=350,resizable=yes");
	w.document.open();
	w.document.write(template);
	w.document.close();
	w.print();
	
}

var activeTooltipAppended = false;
var activeTooltip = $('<div class="hc-tooltipContainer" title="Click to hide"><span class="close">X</span><h2 class="title">More information</h2><div class="content"></div></div>');

function setupTooltips(actuatorSelector, contentSelector) {

	if(!activeTooltipAppended) {
		$('body').append(activeTooltip);
		activeTooltipAppended = true;
	}

	$(contentSelector).hide();

	$(actuatorSelector).unbind('click').click(function(event) {
		if(activeTooltip.css('display')=='none') {
			showtoolTip(this, event);
		} else {
			activeTooltip.fadeOut();
		}
		return false;
	});
	$('.hc-tooltipContainer .close').unbind('click').click(function() {
		activeTooltip.fadeOut();
	});
}

function showtoolTip(ctl, event) {
	// Put content into tooltip and hide it so we can get its dimensions
	// href of this should be an element ID (prefixed with #) - but browsers
	// will prepend absolute url of document so we need to extract the ID
	var c = $('#' + ctl.href.split('#').pop()).get(0).innerHTML;
	var title=$(ctl).attr('tiptitle') || 'More information';
	$('h2.title', activeTooltip).empty().append(title);
	$('.content', activeTooltip).empty().append(c);
	activeTooltip.css({left: 0, top: 0, display: 'block', visibility: 'hidden'});
	var tw = activeTooltip.width();
	var th = activeTooltip.height();
	
	var quadrant = $.screen.eventQuadrant(event);
	
	var h = $(ctl).height();
	var w = $(ctl).width();
	var t = getAbsTop(ctl);
	var l = getAbsLeft(ctl);

	
	var css = { visibility: 'visible', display: 'none' };
	
	switch (quadrant) {
	case 'nw':
		$.extend(css, {left: l, top: t + h + 3});
		break;
	case 'ne':
		$.extend(css, {left: l + w - tw, top: t + h + 3});
		break;
	case 'se':
		$.extend(css, {left: l + w - tw, top: t - th - 8});
		break;
	case 'sw':
		$.extend(css, {left: l, top: t - th - 8});
		break;
	}
	activeTooltip.css(css);
	activeTooltip.fadeIn();
}

//
//
// Screen

jQuery.screen = {
  size: function() {
    var w, h;
    // http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/
    if (typeof(window.innerWidth) != 'undefined') {
      w = window.innerWidth;
      h = window.innerHeight;
    } else if (typeof(document.documentElement) != 'undefined'
  && typeof document.documentElement.clientWidth != 'undefined'
  && document.documentElement.clientWidth != 0) {
      w = document.documentElement.clientWidth;
      h = document.documentElement.clientHeight;
    } else {
      w = document.body.clientWidth,
      h = document.body.clientHeight
    }
    return { width: w, height: h };
  },
  // http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
  scrollOffsets: function() {
    var x, y;
    if(typeof(window.pageYOffset) == 'number') {
      y = window.pageYOffset;
      x = window.pageXOffset;
    } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
      y = document.body.scrollTop;
      x = document.body.scrollLeft;
    } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
      y = document.documentElement.scrollTop;
      x = document.documentElement.scrollLeft;
    }
    return { 'x': x, 'y': y };
  },
  viewport: function() {
    var size = jQuery.screen.size();
    var scroll = jQuery.screen.scrollOffsets();
    return {
      top: scroll.y,
      left: scroll.x,
      width: size.width,
      height: size.height
    };
  },
  quadrant: function(x, y) {
    var v = jQuery.screen.viewport();
    return ((y > v.top + v.height / 2) ? 's' : 'n') + ((x > v.left + v.width / 2) ? 'e' : 'w');
  },
  eventQuadrant: function(evt) {
    return jQuery.screen.quadrant(evt.pageX, evt.pageY);
  }
};

/*
	This function is run after the first calculation - it will watch each of the cookie fields for changes, calling
	calculate() if their value is altered.  This is intended to pre-empt a print with invalid values.
*/
var alreadyCalculated=false, cookiefields=null;
function watchFields() {
	if(cookiefields==undefined) { return; }
	if(cookiefields==null) { return; }
	if(alreadyCalculated) { return; }

	alreadyCalculated=true;
	for(var i=0; i<cookiefields.length;i++) {
	//	$('input[name='+cookiefields[i]+']').change(callcalculate);
	}
}

function callcalculate() {
	//Throw away result - and tell calc not to jump to either error or results	
	calculate(false);
}

