
// ----------------------------------------------------------------------------

// National Insurance Contributions Calculator
// (c) 1999 DIGITA.COM

// Jul 99	Craig Buckler	Original Build
// Oct 01	Tom Dommett		Update to v2 XML
// Apr 02	Craig Buckler	Budget 2002 updates
// Aug 02	Tom Dommett		Standardised Text and Help
// Apr 03	Craig Buckler	Post-Budget updates
// May 04	Craig Buckler	Post-Budget updates
// Mar 05	Tom Dommett		Post-Budget updates
// Apr 06	Craig Buckler	Post-Budget updates

// ----------------------------------------------------------------------------

function calculate(element) {

	var frm = document.calculator;

	var deductions,netfortax,bandsize1,bandsize2,taxband1,taxband2,taxband3;
	var taxdue,denom,code,nicbandexempt,nicbandsize,nicband,nicdue,nictopay;
	var c,v,i,t,done;

	var bs1, bs2, nbe, nbs, tb1, tb2, tb3, nb1, nb2;

	// 2005/2006 defaults
	bs1 = 2150;
	bs2 = 31150;	//31150 + 2150 = REAL RATE OF 33300!
	nbe = 5044;
	nbs = 33540;
	tb1 = 0.10;
	tb2 = 0.22;
	tb3 = 0.40;
	nb1 = 0.094;
	nb2 = 0.11;
	nb3 = 0.01;

	var salary = evalnum(frm.salary.value);
	if (salary == "NaN") salary=0;
	if (salary == 0) {
		alert("Please enter your salary.");
		frm.salary.focus();
		return;
	}
	else frm.salary.value = evalpound(salary);

	code="";
	t = frm.code.value;
	if (t == "NaN") t="";
	for (i=0; i<t.length; i++) {
		c=t.charAt(i);
		if (c != " ") code += c;
	}

	if (frm.chkweekly.checked) denom = 52;
	else denom = 12;

	bandsize1 = bs1/denom;
	bandsize2 = bs2/denom;
	nicbandexempt = nbe/denom;
	nicbandsize = nbs/denom;

	done = false;

	code = code.toUpperCase ();
	if (code.match (/(^[A-Z]{1,1}[0-9]+$)|(^[0-9]+[A-Z]{1,1}$)|(^[A-Z]{2,2}$)/gi))
	{

		// for people that misread
		if (code == 'D0')
			code = 'DO';

		if (code == 'NT' || code == 'BR' || code == 'DO')
		{
			c = code;
			v = "";
			done = true;
		}
		else
		{

			l=code.length;
			c = code.charAt (l-1);

			if (c>="A" && c<="Z")
			{
				v = evalnum(code);
				if (v>0)
					done = true;
			}
			else
			{

				c = code.charAt(0);
				revCode = true;
				if (c>="A" && c<="Z")
				{
					v = evalnum(code);
					if (v>0)
						done = true;
				}
			}
		}

	}

	if (!done)
	{
		alert ("Please enter an appropriate tax code.");
		element.focus ();
		return;
	}

	if (c=="K") {
		deductions = ((-v * 10) - 10 ) / denom;
	}
	else {
		deductions = (v * 10) / denom;
	}

	netfortax = salary - deductions;
	if (netfortax < 0) netfortax=0;

	if (netfortax >= bandsize1) taxband1 = bandsize1;
	else taxband1 = netfortax;

	taxdue = (taxband1 * tb1);

	taxband2=0;
	if (netfortax >= bandsize1 + bandsize2) taxband2 = bandsize2;
	else {
		if (netfortax > bandsize1) taxband2 = netfortax - bandsize1;
	}
	taxdue += (taxband2 * tb2);

	taxband3=0;
	if (netfortax > bandsize1 + bandsize2) taxband3 = netfortax - bandsize1 - bandsize2;
	taxdue += (taxband3 * tb3);

	// New Code for 2005 / 2006. Use of special tax codes
	// --------------------------------------------------

	if (c == 'NT')
		taxdue = 0;

	if (c == 'BR')
		taxdue = salary * tb2;

	if (c == 'DO')
		taxdue = salary * tb3;

	frm.tax.value = evalpound(taxdue);


	// New Code for 2003 / 2004. Including new NI Rules
	// ------------------------------------------------

	if (frm.chkaged.checked || salary < nicbandexempt)
	{
		nictopay = 0;
	}
	else
	{
		if (salary > nicbandsize) {
			nictopay = (nicbandsize - nicbandexempt) * ((frm.chkserps.checked)? nb1 : nb2);
			nictopay += (salary - nicbandsize) * nb3;
		}
		else
		{
			nictopay = (salary - nicbandexempt) * ((frm.chkserps.checked)? nb1 : nb2);
		}
	}

	frm.nic.value = evalpound (nictopay);


}



//----------------------------------------------------------------------------
//		Basic Tax Code check
//		KW 01/2007
//----------------------------------------------------------------------------

function GetTaxCode()
{
	//'Set Default Values from http://www.hmrc.gov.uk/rates/it.htm
	var PersonalAllowanceto65 = 5035  
	var PersonalAllowance65to74 = 7280 
	var PersonalAllowance75plus = 7420 
	var BlindPersonsAllowance = 1660
	var StartingRateTop = 2090 //10%
	var BasicRateTop = 32400 //22%  (higher rate 40%)
	
	var frm = document.frmTaxcode;

	
	var INCOME = evalnum(frm.INCOME.value);
	var TCCAGE =  toInt(GetAge(frm.TCCAGE.value));
	var SPAGE =  toInt(GetAge(frm.SPAGE.value));
	var MARRIE = false;
	var FEMALE = false;
	var EMPLOY = true;
	var BLINDP = false;
	if (frm.MARRIE[0].checked)
		{MARRIE = "true";
		}
	if (frm.MARRIE[1].checked)
		{MARRIE = "false";
		}
	if (frm.FEMALE[0].checked)
		{FEMALE = "false";
		}
	if (frm.FEMALE[1].checked)
		{FEMALE = "true";
		}
	if (frm.EMPLOY[0].checked)
		{EMPLOY = "true";
		}
	if (frm.EMPLOY[1].checked)
		{EMPLOY = "false";
		}
	if (frm.BLINDP[0].checked)
		{BLINDP = "true";
		}
	if (frm.BLINDP[1].checked)
		{BLINDP = "false";
		}
	if (TCCAGE < 65)
		{
	//  if age < 65
	//		if single 
	//			or married (& not claiming married couples allowance)
	//			or taxe on emergency code
	//				^ letter = "L"
			TaxCodeLetterSection = "L"
		}
	else
		{
		if (TCCAGE < 75)
			{
	// if age >65 and <75
			if (MARRIE == "false" )
				{
	//		if single
	//				^ letter = "P"
					TaxCodeLetterSection = "P"
				}
			else
				{
				if (FEMALE== "true") 
					{
	//		if married woman (entitled to the full age raelated allowance) 
	//				^ letter = "P"
						TaxCodeLetterSection = "P"
					}
				else
					{
	//		if married man	(entitled to the full age raelated allowance, estimated at basic rate)
					if (SPAGE < 75)
						{
	//				if  wife < 75
	//					^ letter = "V"
						TaxCodeLetterSection = "V"
						}
					else
						{
	//				if  wife > 74
	//					^ letter = "T"
						TaxCodeLetterSection = "T"
						}
					}
				}
			}
		else
			{
	//  if age > 74
	//			^ letter = "Y"
			TaxCodeLetterSection = "Y"
			}
		}
	
	//DO if you have tax deducted at the higher rate.
	if (INCOME > BasicRateTop)
		{
			TaxCodeLetterSection = "DO"
		}
	//NT if you do not have to pay tax. This code does not include a number.
	if (EMPLOY == "false") 
		{
			TaxCodeLetterSection = "NT"	//??
		}
	//BR if you have not been given any allowances and tax will be deducted at the basic rate. This code may be given where you have more than one job.
	//OT no allowances have been given or remain after other adjustments have been made. Tax will be paid at the lower, basic or higher rate, depending on the level of income.



	var AllowancesTotal
	var BenefitsTotal
	var TaxCodeNumericSection
	var TaxCodeLetterSection
	var TaxCode

	var PersonalAllowanceto65 = 5035  //http://www.hmrc.gov.uk/rates/it.htm
	var PersonalAllowance65to74 = 7280 
	var PersonalAllowance75plus = 7420 

	//   Personal allowance 
	var PersonalAllowance = 5035 
	if (TCCAGE < 65)
		{
			PersonalAllowance = PersonalAllowanceto65
		}
	else
		{
			if (TCCAGE < 75)
				{
					PersonalAllowance = PersonalAllowance65to74
				}
				else
				{
					PersonalAllowance = PersonalAllowance75plus
				}
		}
	// + Death/Superannuation
	var DTHSPA = evalnum(frm.DTHSPA.value);
	// + Company expenses
	var EXPENS = evalnum(frm.EXPENS.value);
	// + Loan interest
	var LOANEN = evalnum(frm.LOANEN.value);
	// + Retirement annuity
	var RTRANN = evalnum(frm.RTRANN.value);
	// ^= Total allowances
	AllowancesTotal = PersonalAllowance + DTHSPA + EXPENS + LOANEN + RTRANN
	// + Bline persons tax credit
	if (BLINDP == "true")
		{
			AllowancesTotal = AllowancesTotal + BlindPersonsAllowance
		}
	//   Car benefit
	var CARBEN = evalnum(frm.CARBEN.value);
	// + Van benefit
	var VANBEN = evalnum(frm.VANBEN.value);
	// + Fuel benefit
	var FULBEN = evalnum(frm.FULBEN.value);
	// + Employer's Loan
	var LOANEM = evalnum(frm.LOANEM.value);
	// + Other benefits
	var OTHBEN = evalnum(frm.OTHBEN.value);
	// + Part time earnings
	var PTEARN = evalnum(frm.PTEARN.value);
	// + Other taxable income
	var OTHTAX = evalnum(frm.OTHTAX.value);
	// + Untaxed income
	var UTAXED = evalnum(frm.UTAXED.value);
	// + 4.545454545 * Tax underpaid
	var UNDPAY = 4.545454545 * evalnum(frm.UNDPAY.value);
	// + Allowances elsewhere
	var ALOCEL = evalnum(frm.ALOCEL.value);
	// ^= Total deductions
	BenefitsTotal = CARBEN + VANBEN + FULBEN + LOANEM + OTHBEN + PTEARN + OTHTAX + UTAXED + UNDPAY + ALOCEL

	// 	(Total allowances - Total deductions) 10 
	// ^= Integer section of tax code
	TaxCodeNumericSection = toInt( (AllowancesTotal - BenefitsTotal) / 10 )

	TaxCode = TaxCodeNumericSection + TaxCodeLetterSection;
	
	frm.personalallowance.value = PersonalAllowance
	frm.totaldeductions.value = BenefitsTotal
	frm.totalallowances.value = AllowancesTotal
	frm.taxcode.value = TaxCode

}

function GetAge(DOB) 
{ var A, Age, Yrs
  with (new Date())
    { var Y = getFullYear(), M = getMonth()+1, D = getDate() }
  A = DOB.split(/\D+/); // allows any separators
  Age = ( PDCount(Y, M, D) - PDCount(A[2], A[1], A[0]) ) / 1000;
  return Age;
 }
function PDCount(Y, M, D) { return (Y*20 + +M)*50 + +D }

/*  GLOBAL FUNCTIONS */

//----------------------------------------------------------------------------
//		Scripts for all calculators
//		Tom Dommett September 2001
//
//----------------------------------------------------------------------------
//	S T A N D A R D   S C R I P T S
//----------------------------------------------------------------------------

var frm = document.calculator;

// ----------------------------------------------------------------------------

function changePage(pageNumber) {

	document.calculator.page.value = pageNumber;
	document.calculator.submit();

}

// Added for taxcode checker 13/10/2005
function spouseCheck(id) {
	if (document.getElementById('MARRIE') != null) {
		if (document.getElementById('MARRIE').checked==true && document.getElementById('SPAGE').value == '') { 
		alert('Please enter the date of birth for your Spouse.'); 
		document.all.SPAGE.focus();
		} 
		else changePage(id);
	}
	else {
		changePage(id);
	}
}

function restart() {

	document.location = document.location;

}

// ----------------------------------------------------------------------------
function selectBox(frmE, selectText) {

	var i;
	var selectIndex = 0;

	for(var i=0;i<document.calculator[frmE].length;i++) {
		if(document.calculator[frmE].options[i].value == selectText) { selectIndex = i;}
	}

	return selectIndex;
}

// ----------------------------------------------------------------------------
function radioButtons(frmE, selectText) {

	var i;
	var selectIndex = 0;
	var frmElement = document.calculator[frmE];

	for(var i=0;i<frmElement.length;i++) {
		if(frmElement[i].value == selectText) { selectIndex = i;}
	}

	frmElement[selectIndex].checked = true;
}

// ----------------------------------------------------------------------------
function evalnumber(element) {

	var en = evalnum(element.value);

	if(element.max != "") {
		if(en > element.max) { 
			en = element.max;
			alert ("The maximum is " + element.max + ".");
			element.focus ();
		}
	}

	if(element.min != "") {
		if(en < element.min) { 
			en = element.min;
			alert ("The minimum is " + element.min + ".");
			element.focus ();
		}
	}
	element.value = en;

}

// ----------------------------------------------------------------------------
function evalmoney(element) {

	var en = evalnum(element.value);

	if(element.max != "") {
		if(en > element.max) { 
			en = element.max;
			alert ("The maximum is " + element.max + ".");
			element.focus ();
		}
	}

	if(element.min != "") {
		if(en < element.min) { 
			en = element.min;
			alert ("The minimum is " + element.min + ".");
			element.focus ();
		}
	}

	if(element.format == '#') { 
		element.value = evalpoundonly(en);
	} else {
		element.value = evalpound(en);
	}

}

// ----------------------------------------------------------------------------
function evaldate(element) {

	if(element.value == '' && element.optional == 'true') { return; }

	if(verify_date(element.value)) {

		var en = formatdate(verify_date(element.value));

		if(element.min != "") {
			if(en < element.min) { 
				en = element.min;
				alert ("The earliest date is " + unformatdate(element.min) + ".");
			}
		}

		if(element.max != "") {
			if(en > element.max) { 
				en = element.max;
				alert ("The latest date is " + unformatdate(element.max) + "."); 
			}
		}

		en = unformatdate(en);
		element.value = verify_date(en);
		return true;
	}
	else { 
		alert("Please enter a valid date");
		element.select();
		element.focus();
		return false;
	}

	

}

// ----------------------------------------------------------------------------

function evaltaxcode(element) {

	var code = element.value;

	done = false;
	revCode = false;
	
	code = code.toUpperCase ();
	if (code.match (/(^[A-Z]{1,1}[0-9]+$)|(^[0-9]+[A-Z]{1,1}$)|(^[A-Z]{2,2}$)/gi))
	{
	
		// for people that misread
		if (code == 'D0')
			code = 'DO';
			
		if (code == 'NT' || code == 'BR' || code == 'DO')
		{
			c = code;
			v = "";

			done = true;
		}
		else
		{
				
			l=code.length;
			c = code.charAt (l-1);
		
			if (c>="A" && c<="Z")
			{
				v = evalnum(code);
				if (v>0)
					done = true;
			}
			else
			{
	
				c = code.charAt(0);
				revCode = true;
				if (c>="A" && c<="Z") 
				{
					v = evalnum(code);
					if (v>0)
						done = true;
				}
			}
		}
	
	}

	if (!done) 
	{
		alert ("Please enter an appropriate tax code.");
		element.focus ();
		return;
	}
	else
	{
		if(!revCode) { element.value = v + c; } else {  element.value = c + v; }
	}

}

// ----------------------------------------------------------------------------

// ----------------------------------------------------------------------------
function evalnum(numstr) {

	var i,c,neg;
	var ret="";
	var p=false;

	neg = 1;
	if (numstr.indexOf("-") >=0) { neg = -1; }

	for (i=numstr.length-1; i>=0; i--) {
		c=numstr.charAt(i);

		if (c == ".") {
			if (p == false) p=true;
			else c="";
		}

		if ((c < "0" || c > "9") && c != ".") c="";

		ret = c + ret;
	}

	if (ret=="" || ret=="NaN") ret="0";
	return parseFloat(ret*neg);

}

// ----------------------------------------------------------------------------
function popupHelp(pageurl, help){

	var win=open("", "help", "width=250,height=350,menubar=no,toolbar=no,status=no,resizable=yes,scrollbars=yes");

	win.document.clear();
	win.document.open();
	//win.document.write("<html><head><title>Calculator help</title><style>\n");
	//win.document.write("body { font-family: arial,helv,helvetica,san-serif; font-size: 0.8em; }\n");
	//win.document.write("p { margin:1em 0em 1em 0em; }\n");
	//win.document.write("ul { list-style-type: disc; list-style-position: outside; margin: 1em 0em 1em 3em; }\n");
	//win.document.write("ol { list-style-type: decimal; list-style-position: outside; margin: 1em 0em 1em 3em; }\n");
	//win.document.write("li { margin-top: 1em; }\n");
	//win.document.write(".title { font-size:1.1em; font-weight:bold; }\n");
	//win.document.write("a { text-decoration: none; color: #336699; }\n");
	//win.document.write("a:link { text-decoration: none; color: #336699; }\n");
	//win.document.write("a:visited { text-decoration: none; color: #336699; }\n");
	//win.document.write("a:hover { text-decoration: underline; color: #0000CC; }\n");
	//win.document.write("</style></head><body leftmargin=\"4\" marginwidth=\"4\" topmargin=\"4\" marginheight=\"4\">");
	win.document.write("<html><head><title>Calculator help</title>\n");
	win.document.write("<link href=\"../assets/styles/global.css\" rel=\"stylesheet\" type=\"text/css\" />\n");
	win.document.write("</head><body><div id=\"help\">");

	win.document.write(helpStart+help+helpEnd);
	win.document.write("</body></html>");
	win.document.close();
	win.focus();

}



// ----------------------------------------------------------------------------
function popupInfo(pageurl){

	var win=open(pageurl, "Information", "width=400,height=600,menubar=no,toolbar=no,status=no,resizable=yes,scrollbars=yes");

	win.focus();

}


// ----------------------------------------------------------------------------
function evalpound(num) {

	var i,l,d,n;
	var nums;
	var ret;

	nums = String(Math.round(num*100));
	n = ((num < 0)? 1:0);

	while (nums.length <3) nums = "0" + nums;

	l = nums.length-3;
	ret = "." + nums.charAt(l+1) + nums.charAt(l+2);

	d=0;
	for (i=l; i>=0; i--) {
		ret = nums.charAt(i) + ret;
		d++;
		if (d==3 && i>n) {
			ret="," + ret;
			d=0;
		}
	}

	ret = "\u00a3" + ret;
	return ret;

}


// ----------------------------------------------------------------------------
function evalpoundonly(num) {

	var i,l,d;
	var nums;
	var ret='';

	nums = String(Math.round(num*100));

	while (nums.length <3) nums = "0" + nums;

	l = nums.length-3;
	//ret = "." + nums.charAt(l+1) + nums.charAt(l+2);

	d=0;
	for (i=l; i>=0; i--) {
		ret = nums.charAt(i) + ret;
		d++;
		if (d==3 && i>0) {
			ret="," + ret;
			d=0;
		}
	}

	ret = "\u00a3" + ret;
	return ret;

}

// ________________________________________________________
// verify that the value entered is a date
function verify_date(str) {
	var ret = "";

	if (str!="" && str==str.replace(/[^-\/0-9]/g, "")) {

		// parse date
		str = str.replace(/\//g, "-");
		var pdate = str.split("-");

		if (pdate.length==3) {

			var d=0; var m=0; var y=0;

			d = toInt(pdate[0]);
			m = toInt(pdate[1]);

			y = pdate[2];
			if(y<1850) {
				if(y<100 && y>0) {
					//presume 2 figure:
					if ( y<10) { y = toInt(y) + 2000; }
					else { y = toInt(y) + 1900; }
				}
				else { y = 0; }
			} else { if(y > 2050) { y = 0; } }

			// valid date?
			if (d>0 && m>0 && y>0) {

				var vdate = new Date(y, (m-1), d);

				if (d==vdate.getDate() && (m-1)==vdate.getMonth() && y==vdate.getFullYear()) {

					// create return string
					if (d<10) { ret = ret + "0"; }
					ret = ret + String(d) + "/";
					if (m<10) { ret = ret + "0"; }
					ret = ret + String(m) + "/" + String(y);

				}
			}
		}
	}

	return ret;
}

// ----------------------------------------------------------------------------
function formatdate(dateString) {

	var day1, month1, year1;

	year1 = dateString.substring(6, 10);
	month1 = dateString.substring(3, 5);
	day1 = dateString.substring(0, 2);

	return year1 + month1 + day1;

}

// ----------------------------------------------------------------------------
function unformatdate(dateString) {

	var day1, month1, year1;

	year1 = dateString.substring(0, 4);
	month1 = dateString.substring(4, 6);
	day1 = dateString.substring(6, 8);

	return day1 + "/" + month1 + "/" + year1;

}

// ----------------------------------------------------------------------------
function daysBetween(date1, date2) {

	var day1, day2, month1, month2, year1, year2, diff;

	year1 = date1.substring(0, 4);
	year2 = date2.substring(0, 4);

	month1 = date1.substring(4, 6);
	month2 = date2.substring(4, 6);

	day1 = date1.substring(6, 8);
	day2 = date2.substring(6, 8);

	year1 -= 1970;
	year2 -= 1970;
	month1--
	month2--

	var MinMilli = 1000 * 60
  	var HrMilli = MinMilli * 60
  	var DyMilli = HrMilli * 24

	diff = Date.UTC(year2, month2, day2, 0, 0, 0) - Date.UTC(year1, month1, day1, 0, 0, 0)
	diff = Math.round(diff / DyMilli);

	return diff;

}


// ----------------------------------------------------------------------------
// converts a string to a decimal integer

function toInt(str) {

	var ret=0;
	var state=1;

	// clean string
	str = String(str);
	str = str.replace(/\u00a3| |,/g, "");

	// find negative values
	if (str.charAt(0) == "-") {
		state = -1;
		str = str.replace(/-/g, "");
	}

	// if numeric
	if (!isNaN(str)) {

		// remove leading zeros
		while (str.length>1 && str.charAt(0)=="0") {
			str = str.substr(1, str.length-1);
		}

		// find integer and convert to correct state
		ret = parseInt(str) * state;
	}

	return ret;
}

// ----------------------------------------------------------------------------
// Returns the Object Reference

function GetContextObject (objName)
{	
	if (document.all)			// IE4 +
	{
		var objContext = document.all[objName];
	}
	else if (document.getElementById )	// Netscape 6 +
	{
		var objContext = document.getElementById (objName);
	}
	else					// Netscape 4.7 is not currently supported
	{
		var objContext = nothing;
	}
	return objContext;
}

// ----------------------------------------------------------------------------
// Returns the Absolute Top of an Object

function GetObjectTop (objContext)
{
	var yPosition = objContext.offsetTop;
	var objParent = objContext.offsetParent;
	while (objParent != null)
	{
		yPosition += objParent.offsetTop;
		objParent = objParent.offsetParent;
	}
	return yPosition;
}

// ----------------------------------------------------------------------------
// Returns the Absolute Left of an Object

function GetObjectLeft (objContext)
{
	var xPosition = objContext.offsetLeft;
	var objParent = objContext.offsetParent;
	while (objParent != null)
	{
		xPosition += objParent.offsetLeft;
		objParent = objParent.offsetParent;
	}
	return xPosition;
}





