/*
	Tax Depreciation Calculator code
	Author Whale Informatics - info@whale-informatics.com
*/

// extend Date type with get Day of Year method
Date.prototype.getDOY = function() {
var onejan = new Date(this.getFullYear(),0,1);
return Math.ceil((this - onejan) / 86400000);
}

// strip separator from floatstring
function stripFloatString(fltstr) {
	fltstr=fltstr.replace(',','').replace(' ','');
	return fltstr;
}

// calcs rental return based upon input fields
function calc_return() {
	
	// parse and display input values
	var prop_value=parseFloat(stripFloatString(document.form.prop_value.value));
	document.form.prop_value.value=formatNumber(prop_value,"### ### ##0");
	
	var rent=parseFloat(stripFloatString(document.form.rent.value));
	document.form.rent.value=formatNumber(rent,"### ##0");
	
	var rental_return=(rent*52)/prop_value*100;
	
	writeInner('rental_return',formatNumber(rental_return,"#0.0")+' %');
	
	// hide recalc button
	setVisible('calc_button',false);
	
	// process recommendations
	
	if (rental_return<5) {
		document.getElementById('result_nogo').style.display='block';
		document.getElementById('result_longterm').style.display='none';
		document.getElementById('result_go').style.display='none';
	}
	if (rental_return>=5 && rental_return<6) {
		document.getElementById('result_nogo').style.display='none';
		document.getElementById('result_longterm').style.display='block';
		document.getElementById('result_go').style.display='none';
	}
	if (rental_return>=6) {
		document.getElementById('result_nogo').style.display='none';
		document.getElementById('result_longterm').style.display='none';
		document.getElementById('result_go').style.display='block';
	}
}

function changeValue(field,value) {
	var old_value=parseFloat(stripFloatString(document.form[field].value));
	document.form[field].value=formatNumber(old_value+value,"### ### ##0");
	
	calc_return();
}

var panelUp = true;

function invalidate_result() {
	// show the recalc button
	setVisible('calc_button',true);

	if (!panelUp) {
		// collapse result only when it is already expanded
		// alert('collapse');
		animate('result',0,0,resultPanelWidth,0,500);
		panelUp = true;
	}
}

// catch input field Enter/TAB and Keypress
// if Enter/TAB ->
// if other Keypress -> submit invalidate_result()
function catchKey(e) {
	var keyCode;

	// fetch keypress code
	if (!e) var e = window.event
		if (e.keyCode) keyCode = e.keyCode;
		else if (e.which) keyCode = e.which;

	// alert(keyCode);
		
	// check if Enter or TAB was pressed
 	// if((keyCode==13) || (keyCode==9))
 		// submit action
 	//	calc_return();

	// suppress Enter to disable FORM submit
 	if ((keyCode==13)) {
 		e.cancelBubble = true;
 		if (e.stopPropagation) e.stopPropagation();
 			return false;
 	}
 	
 	// check whether any digit/space/comma/period/backspace/delete character key was pressed (change of content)
 	if ( ((keyCode>=48) && (keyCode<=57)) || (keyCode==32) || (keyCode==188) || (keyCode==190) || (keyCode==8) || (keyCode==46) )
 		invalidate_result();

	// cancel out any alphabetical characters pressed
 	if ((keyCode>=65) && (keyCode<=90)) {
 		e.cancelBubble = true;
 		if (e.stopPropagation) e.stopPropagation();
 			return false;
 	}
 	
 	// alert('true');
	return true;
}

// retrieves actual/computed property CSS value (uses special IE_computedStyle script)
// el = elemeent, property = property name (e.g. height, width)
function realPropValue(el,property) {
	var propValue;
	
	if (window.getComputedStyle)
		propValue = window.getComputedStyle(el, null).getPropertyValue(property);
	else
		propValue = IE_computedStyle.get(el,property);
	
	return propValue;
}


var resultPanelHeight;
var resultPanelWidth;

// perform main tasks when user hits calc button
function exec() {

	// main calculation
	if (!calc())
		return;

	// hide recalc button
	setVisible('calc_button',false);

	// add 're' to calc_button
	writeInner('calc_button_prefix','re');
	
	// reads result panel height
	resultPanelHeight = realPropValue(document.getElementById('result_panel'),'height');
	resultPanelHeight = resultPanelHeight.substr(0,resultPanelHeight.length-2)*1;

	// alert('height: '+resultPanelHeight);
	
	resultPanelWidth = realPropValue(document.getElementById('result_panel'),'width');
	resultPanelWidth = resultPanelWidth.substr(0,resultPanelWidth.length-2)*1;
	
	// animate expand result window
	animate('result',0,0,resultPanelWidth,resultPanelHeight,1000);
	
	// set flag to true
	panelUp = false;
}

// forces current width to inline style to allow animation code to pickup current width correctly
function setResultWidth() {
	var el = document.getElementById('result');
	
	el.style.width = realPropValue(document.getElementById('result_panel'),'width');
}

// init date vars
var now=new Date()
var nowDay=now.getDate();
var nowMonth=now.getMonth();
var nowYear=now.getFullYear();

var constructMonth=0;
var constructYear=0;

var purchaseDay;
var purchaseMonth;
var purchaseYear;

var constructCostSqm;
var floorArea;
var propertyType;

var div43AllowanceGroup;

var finishQuality;
var capitalCity;
var regionalAdjustment;

var todaysConstructCost;
var origConstructCost;

var purchaseDateDiv40Value;

// main calc function for tax depreciation

function calc() {
	// validate input first
	if (!validate_input())
		return false;
	
	// calc todays construction cost
		
	propertyType = document.form.propertyType.value;
	finishQuality = document.form.finishQuality.value;
	floorArea = document.form.floorArea.value;
	capitalCity = document.form.capitalCity.value;
	
	// determine constructCostSqm value
	determineConstructCostSqm();
	
	// determine regional adjustment
	var regionalAdjustmentRatios=new Array(1.14,1.1,1,1,1.03,1.04,1.1,.92); // cairns,brisbane,sydney,canberra,melbourne,adelaide,perth,hobart
	regionalAdjustment=regionalAdjustmentRatios[capitalCity-1];
	
	todaysConstructCost = constructCostSqm * floorArea * regionalAdjustment;
	// alert('todays construct cost:'+todaysConstructCost);
	
	// calc original construction cost
	
	constructMonth = document.form.constructMonth.value;
	constructYear = document.form.constructYear.value;
	
	// calc BPI factor then - now
	var BPIratio = calcBPIRatio(constructMonth,constructYear,nowMonth,nowYear);
	origConstructCost = todaysConstructCost * BPIratio;
	// alert('orig construct cost:'+origConstructCost);
	
	// set div40 Percentages + propertyGroup
	switch(propertyType.substr(0,3))
	{
	 case "res":
		div40Perc = new Array(.16,.14,.12,.1);
		div43AllowanceGroup = 3;
		break; 	
	 case "com":
		div40Perc = new Array(.16,.14,.12,.1);
		div43AllowanceGroup = 2
		break;
	 case "ind":
		div40Perc = new Array(.1,.08,.06,.04);
		div43AllowanceGroup = 2;
		break;
	 case "ret":
		div40Perc = new Array(.14,.12,.1,.08);
		div43AllowanceGroup = 2;
		break;
	 case "hom":
		div40Perc = new Array(.2,.18,.16,.14);
		div43AllowanceGroup = 2;
		break;
	}

	// calc plant&equipment value at purchase date
	
	// calc construction age in yrs
	var age = ( purchaseYear*12 + purchaseMonth - constructYear*12 - constructMonth )/12;
	// alert(age);
	var ageBucket = Math.floor(age/5);
	if (ageBucket>3) ageBucket=3;
	// alert('age bucket: '+ageBucket);
		
	purchaseDateDiv40Value = origConstructCost * div40Perc[ageBucket];
	// alert('purchase date div40 value: '+purchaseDateDiv40Value);

	// calc each year's div43 deprc
	var yearlyDiv43Depr = (origConstructCost - purchaseDateDiv40Value) * div43DeprPerc()
	// alert('Yearly div43 depr: '+yearlyDiv43Depr);
	
	// calc div40 depreciation for 1st 10 years starting from purchase date
	
	var div40DeprPercSeries = new Array(0.1586,0.1250,0.098,0.0786,0.0645,0.0539,0.0457,0.0393,0.0341,0.0299);
	var div40DeprSeries = new Array(0,0,0,0,0,0,0,0,0,0);
	
	var c=0;
	for(c=0;c<=9;c++)
		div40DeprSeries[c]=purchaseDateDiv40Value*div40DeprPercSeries[c];
	
	// write data back to form
	
	// main estimated costs
	writeInner('origConstructCost',formatNumber(origConstructCost,"### ### ##0"));
	writeInner('purchaseDateDiv40Value',formatNumber(purchaseDateDiv40Value,"### ### ##0"));
	
	// depreciation schedule for 1st 10 years
	
	var div40total=0;
	var div43total=0;
	var div40;
	var div43;
	var yeartotal;
	
	// determine 1st year share given purchase date
	var purchaseDate=new Date(purchaseYear,purchaseMonth-1,purchaseDay);
	var doy=purchaseDate.getDOY();
	if (purchaseMonth>=7)
		doy=doy-182.5;
	else
		doy=doy+182.5;

	var part2ratio = doy/365;
	if (part2ratio<0) part2ratio=0;
	var part1ratio = 1 - part2ratio;
	
	// process 1st fiscal year
	div40 = div40DeprSeries[0] * part1ratio;
	div40total = div40total + div40;
	div43 = yearlyDiv43Depr * part1ratio;
	div43total = div43total + div43;
	
	writeInner('yr1div40',formatNumber(div40,"### ### ##0"));
	writeInner('yr1div43',formatNumber(div43,"### ### ##0"));
	writeInner('yr1total',formatNumber(div40+div43,"### ### ##0"));
	
	// cycle through remaining 9 fiscal years
	for(c=1;c<=9;c++) {
		div40 = div40DeprSeries[c-1] * part2ratio + div40DeprSeries[c] * part1ratio;
		div40total = div40total + div40;
		div43 = yearlyDiv43Depr;
		div43total = div43total + div43;
		
		writeInner('yr'+(c+1)+'div40',formatNumber(div40,"### ### ##0"));
		writeInner('yr'+(c+1)+'div43',formatNumber(div43,"### ### ##0"));
		writeInner('yr'+(c+1)+'total',formatNumber(div40+div43,"### ### ##0"));
	}
	
	// display totals
	writeInner('totaldiv40',formatNumber(div40total,"### ### ##0"));
	writeInner('totaldiv43',formatNumber(div43total,"### ### ##0"));
	writeInner('totaltotal',formatNumber(div40total+div43total,"### ### ##0"));
	
	return true;
}

// validate the user input
function validate_input() {
	constructMonth=parseFloat(stripFloatString(document.form.constructMonth.value));
	if (isNaN(constructMonth) || constructMonth<1 || constructMonth>12 || Math.round(constructMonth)!=constructMonth) {
		alert('invalid construction date month - please re-enter');
		document.form.constructMonth.focus();
		return false;
	}
	constructYear=parseFloat(stripFloatString(document.form.constructYear.value));
	if (isNaN(constructYear) || constructYear<1950 || constructYear>2050 || Math.round(constructYear)!=constructYear) {
		alert('invalid construction date year - please re-enter');
		document.form.constructYear.focus();
		return false;
	}

	purchaseDay=parseFloat(stripFloatString(document.form.purchaseDay.value));
	if (isNaN(purchaseDay) || purchaseDay<1 || purchaseDay>31 || Math.round(purchaseDay)!=purchaseDay) {
		alert('invalid purchase date month - please re-enter');
		document.form.purchaseDay.focus();
		return false;
	}
	purchaseMonth=parseFloat(stripFloatString(document.form.purchaseMonth.value));
	if (isNaN(purchaseMonth) || purchaseMonth<1 || purchaseMonth>12 || Math.round(purchaseMonth)!=purchaseMonth) {
		alert('invalid purchase date month - please re-enter');
		document.form.purchaseMonth.focus();
		return false;
	}
	purchaseYear=parseFloat(stripFloatString(document.form.purchaseYear.value));
	if (isNaN(purchaseYear) || purchaseYear<1950 || purchaseYear>2050 || Math.round(purchaseYear)!=purchaseYear) {
		alert('invalid purchase date year - please re-enter');
		document.form.purchaseYear.focus();
		return false;
	}
	
	// test construct date <= purchase date
	if (!(constructYear<purchaseYear || (constructYear==purchaseYear && constructMonth<=purchaseMonth))) {
		alert('construction date should be earlier than purchase date - please re-enter');
		document.form.constuctMonth.focus();
		return false;
	}
	
	return true;
}

// determine todays construction cost per sqm for building type
function determineConstructCostSqm() {
	// cost info as per 2007, for each year later add 2.5%
	
	var res1=new Array(897,1109,1389);
	var res2=new Array(1886,2901,4508);
	var res3=new Array(1121,1302,1868);
	var res4=new Array(1265,1521,1975);
	var res5=new Array(1441,1814,2722);
	
	var com1=new Array(1036,1336,2000);
	var com2=new Array(1154,1357,2059);
	var com3=new Array(1458,1802,2129);
	var com4=new Array(1886,2280,2753);
	
	var ind1=new Array(643,711,823);
	var ind2=new Array(569,667,785);
	var ind3=new Array(679,786,1087);
	var ind4=new Array(662,744,1016);
	
	var ret1=new Array(1181,1451,1710);
	var ret2=new Array(937,1165,1297);
	var ret3=new Array(1024,1121,1303);
	var ret4=new Array(711,831,947);
	
	var hom1=new Array(1636,2052,2681);
	var hom2=new Array(1433,1800,1964);
	var hom3=new Array(1373,1762,1893);
	var hom4=new Array(2123,2276,2375);
	
	var inflationFactor=Math.pow(1.025,nowYear-2007);
	
	switch(propertyType)
	{
	 case "res1":
	 	constructCostSqm = res1[finishQuality-1]
		break;
	 case "res2":
	 	constructCostSqm = res2[finishQuality-1]
		break;
	 case "res3":
	 	constructCostSqm = res3[finishQuality-1]
		break;
	 case "res4":
	 	constructCostSqm = res4[finishQuality-1]
		break;
	 case "res5":
	 	constructCostSqm = res5[finishQuality-1]
		break;
	 case "com1":
	 	constructCostSqm = com1[finishQuality-1]
		break;
	 case "com2":
	 	constructCostSqm = com2[finishQuality-1]
		break;
	 case "com3":
	 	constructCostSqm = com3[finishQuality-1]
		break;
	 case "com4":
	 	constructCostSqm = com4[finishQuality-1]
		break;
	 case "ind1":
	 	constructCostSqm = ind1[finishQuality-1]
		break;
	 case "ind2":
	 	constructCostSqm = ind2[finishQuality-1]
		break;
	 case "ind3":
	 	constructCostSqm = ind3[finishQuality-1]
		break;
	 case "ind4":
	 	constructCostSqm = ind4[finishQuality-1]
		break;
	 case "ret1":
	 	constructCostSqm = ret1[finishQuality-1]
		break;
	 case "ret2":
	 	constructCostSqm = ret2[finishQuality-1]
		break;
	 case "ret3":
	 	constructCostSqm = ret3[finishQuality-1]
		break;
	 case "ret4":
	 	constructCostSqm = ret4[finishQuality-1]
		break;
	 case "hom1":
	 	constructCostSqm = hom1[finishQuality-1]
		break;
	 case "hom2":
	 	constructCostSqm = hom2[finishQuality-1]
		break;
	 case "hom3":
	 	constructCostSqm = hom3[finishQuality-1]
		break;
	 case "hom4":
	 	constructCostSqm = hom4[finishQuality-1]
		break;
	}
	
	constructCostSqm=constructCostSqm*inflationFactor;
}

function calcBPIRatio(constructMonth,constructYear,nowMonth,nowYear) {
	var constructBPI = getBPI(constructMonth,constructYear);
	var nowBPI = getBPI(nowMonth,nowYear);
	
	return (constructBPI/nowBPI);
}

function getBPI(month,year) {
	var BPIvalue
	
	if(year==1966) {BPIValue=14.22};
	if(year==1967) {BPIValue=14.37};
	if(year==1968) {BPIValue=14.43};
	if(year==1969) {BPIValue=15.04};
	if(year==1970) {BPIValue=16.06};
	if(year==1971) {BPIValue=17.07};
	if(year==1972) {BPIValue=18.29};
	if(year==1973) {BPIValue=22.36};
	if(year==1974) {BPIValue=28.05};
	if(year==1975) {BPIValue=31.30};
	if(year==1976) {BPIValue=38.61};
	if(year==1977) {BPIValue=41.92};
	if(year==1978) {BPIValue=43.08};
	if(year==1979) {BPIValue=45.53};
	if(year==1980) {BPIValue=51.04};
	if(year==1981) {BPIValue=59.46};
	if(year==1982) {BPIValue=67.38};
	if(year==1983) {BPIValue=66.66};
	if(year==1984) {BPIValue=69.35};
	if(year==1985) {BPIValue=73.89};
	if(year==1986) {BPIValue=79.99};
	if(year==1987) {BPIValue=83.68};
	if(year==1988) {BPIValue=89.58};
	if(year==1989) {BPIValue=97.70};
	if(year==1990) {BPIValue=103.1};
	if(year==1991) {BPIValue=103.51};
	if(year==1992) {BPIValue=99.87};
	if(year==1993 && month>=1 && month<=3) {BPIValue=100.86};
	if(year==1993 && month>=4 && month<=6) {BPIValue=101.36};
	if(year==1993 && month>=7 && month<=9) {BPIValue=101.87};
	if(year==1993 && month>=10 && month<=12) {BPIValue=102.87};
	if(year==1994 && month>=1 && month<=3) {BPIValue=104.93};
	if(year==1994 && month>=4 && month<=6) {BPIValue=106.98};
	if(year==1994 && month>=7 && month<=9) {BPIValue=110.59};
	if(year==1994 && month>=10 && month<=12) {BPIValue=113.16};
	if(year==1995 && month>=1 && month<=3) {BPIValue=116.55};
	if(year==1995 && month>=4 && month<=6) {BPIValue=117.69};
	if(year==1995 && month>=7 && month<=9) {BPIValue=117.69};
	if(year==1995 && month>=10 && month<=12) {BPIValue=117.69};
	if(year==1996) {BPIValue=117.69};
	if(year==1997 && month>=1 && month<=3) {BPIValue=118.87};
	if(year==1997 && month>=4 && month<=6) {BPIValue=120.04};
	if(year==1997 && month>=7 && month<=9) {BPIValue=121.22};
	if(year==1997 && month>=10 && month<=12) {BPIValue=122.10};
	if(year==1998 && month>=1 && month<=3) {BPIValue=122.71};
	if(year==1998 && month>=4 && month<=6) {BPIValue=123.32};
	if(year==1998 && month>=7 && month<=9) {BPIValue=123.93};
	if(year==1998 && month>=10 && month<=12) {BPIValue=124.54};
	if(year==1999 && month>=1 && month<=3) {BPIValue=124.54};
	if(year==1999 && month>=4 && month<=6) {BPIValue=125.79};
	if(year==1999 && month>=7 && month<=9) {BPIValue=125.79};
	if(year==1999 && month>=10 && month<=12) {BPIValue=125.79};
	if(year==2000 && month>=1 && month<=3) {BPIValue=128.31};
	if(year==2000 && month>=4 && month<=6) {BPIValue=129.56};
	if(year==2000 && month>=7 && month<=9) {BPIValue=125.79};
	if(year==2000 && month>=10 && month<=12) {BPIValue=125.79};
	if(year==2001 && month>=1 && month<=3) {BPIValue=125.79};
	if(year==2001 && month>=4 && month<=6) {BPIValue=126.42};
	if(year==2001 && month>=7 && month<=9) {BPIValue=128.31};
	if(year==2001 && month>=10 && month<=12) {BPIValue=129.56};
	if(year==2002 && month>=1 && month<=3) {BPIValue=130.21};
	if(year==2002 && month>=4 && month<=6) {BPIValue=131.51};
	if(year==2002 && month>=7 && month<=9) {BPIValue=132.80};
	if(year==2002 && month>=10 && month<=12) {BPIValue=138.00};
	if(year==2003 && month>=1 && month<=3) {BPIValue=144.90};
	if(year==2003 && month>=4 && month<=6) {BPIValue=149.97};
	if(year==2003 && month>=7 && month<=9) {BPIValue=153.03};
	if(year==2003 && month>=10 && month<=12) {BPIValue=170.00};
	if(year==2004 && month>=1 && month<=3) {BPIValue=187.00};
	if(year==2004 && month>=4 && month<=6) {BPIValue=190.40};
	if(year==2004 && month>=7 && month<=9) {BPIValue=193.80};
	if(year==2004 && month>=10 && month<=12) {BPIValue=195.50};
	if(year==2005 && month>=1 && month<=3) {BPIValue=201.37};
	if(year==2005 && month>=4 && month<=6) {BPIValue=207.23};
	if(year==2005 && month>=7 && month<=9) {BPIValue=210.16};
	if(year==2005 && month>=10 && month<=12) {BPIValue=213.10};
	if(year==2006 && month>=1 && month<=3) {BPIValue=215.23};
	if(year==2006 && month>=4 && month<=6) {BPIValue=219.49};
	if(year==2006 && month>=7 && month<=9) {BPIValue=223.76};
	if(year==2006 && month>=10 && month<=12) {BPIValue=228.02};
	if(year==2007 && month>=1 && month<=3) {BPIValue=232.58};
	if(year==2007 && month>=4 && month<=6) {BPIValue=234.86};
	if(year==2007 && month>=7 && month<=9) {BPIValue=239.42};
	if(year==2007 && month>=10 && month<=12) {BPIValue=243.86};
	if(year>=2008) {BPIValue=248.86};

	return BPIValue;
}

function div43DeprPerc() {
	var div43DeprPerc;
	
	var c = constructYear+(constructMonth/12);
	
	if(c<1982.636 && div43AllowanceGroup==1){div43DeprPerc=0}
	if(c>1982.636 && c<1984.725 && div43AllowanceGroup==1){div43DeprPerc=0.025}
	if(c>1984.725 && c<1985.630 && div43AllowanceGroup==1){div43DeprPerc=0.04}
	if(c>1985.630 && c<1987.792 && div43AllowanceGroup==1){div43DeprPerc=0.04}
	if(c>1987.792 && c<1992.238 && div43AllowanceGroup==1){div43DeprPerc=0.025}
	if(c>1992.238 && div43AllowanceGroup==1){div43DeprPerc=0.04}
	
	if(c<1982.636 && div43AllowanceGroup==2){div43DeprPerc=0}
	if(c>1982.636 && c<1984.725 && div43AllowanceGroup==2){div43DeprPerc=0.025}
	if(c>1984.725 && c<1985.630 && div43AllowanceGroup==2){div43DeprPerc=0.04}
	if(c>1985.630 && c<1987.792 && div43AllowanceGroup==2){div43DeprPerc=0.04}
	if(c>1987.792 && c<1992.238 && div43AllowanceGroup==2){div43DeprPerc=0.025}
	if(c>1992.238 && div43AllowanceGroup==2){div43DeprPerc=0.025}
	
	if(c<1982.636 && div43AllowanceGroup==3){div43DeprPerc=0}
	if(c>1982.636 && c<1984.725 && div43AllowanceGroup==3){div43DeprPerc=0}
	if(c>1984.725 && c<1985.630 && div43AllowanceGroup==3){div43DeprPerc=0}
	if(c>1985.630 && c<1987.792 && div43AllowanceGroup==3){div43DeprPerc=0.04}
	if(c>1987.792 && c<1992.238 && div43AllowanceGroup==3){div43DeprPerc=0.025}
	if(c>1992.238 && div43AllowanceGroup==3){div43DeprPerc=0.025}

	return div43DeprPerc;
}