// JavaScript Document
<!--
window.onerror=null;

bState = true;

oReq = new Collection("combined income","","number of dependants","other loans","credit cards","","interest rate","loan term","");

oVal = new Collection("combined income","","number of dependants","other loans","credit cards","","interest rate","loan term","");

oType = new Collection("int","","int","int","int","","flt","int",""); //number type

oMin = new Collection(400,"",0,0,0,"",3,8,"");	//min values

oMax = new Collection(1000000,"",10,3000000,50000,"",25,40,""); //max values

function controller(oForm) 
{
   while (bState) 
   {
      if (!Required(oForm))
         break;
      if (!Validate(oForm))
         break;
      if (!SetValue(oForm))
         break;
      if (bState) 
	  {
          bState = false;
      }
   }
   bState = true;
}

function Required(oView) 
{
   for (i in oView) 
   {
      for (j in oReq) 
	  {
        if (i==oReq[j]) 
		{      
           if (isMissing(oView[i])) 
		   {
               return(false);
           }
        }
     }
  }
  return true;
}

function Validate(oView) 
{
   for (i in oView) 
   {
      for (j in oVal) 
	  {
        if (i==oVal[j] && oType[j]!="") 
		{      
           if (isTest(oView[i], oType[j])) 
		   {
               return(false);
           }
        }
     }
  }
  return(true);
}

function SetValue(oView) 
{
   aLoan = new Loan(stripFormatting(oView.income.value), get_checked(oView.frequency), oView.dependants.value, get_checked(oView.jointincome), stripFormatting(oView.otherloans.value),stripFormatting(oView.cclimit.value), stripFormatting(oView.interest.value), oView.term.value, 0 );
	
	aLoan.calcPeriods();
    aLoan.calcIncome();
	aLoan.setRate();

   oView.canborrow.value = calcRound(aLoan.calcBorrowAmount());

   return(true);

}

function isMissing(oCtrl) 
{
	if (oCtrl.value == "") 
	{  
		alert("The required field '"+oCtrl.name+"' is blank. Please enter a number."); 
		oCtrl.focus();
      	oCtrl.select();
		 return(true);
    }
   	else
    { 
		return(false);
   	}

}

function isTest(oCtrl, oTest) 
{
	var input = stripFormatting(oCtrl.value);
    if ((oTest=="int" && !isInteger(input))||(oTest=="flt" && !isNumber(input)))
    {
      alert("The '"+oCtrl.name+"' field contains an invalid character. Please enter a number.");
      oCtrl.focus();
      return(true);
	}
	else
	{ 
      return(false);
	}
}

function inRange(oCtrl, minVal, maxVal)
{
	var input = oCtrl;
	if (maxVal == ""||maxVal == null)
	{
		if (parseFloat(input) < minVal)
		{
			  return(minVal);
		}
	}
	else
	{
		if (parseFloat(input) < minVal)//if under set to min limit
		{
			  return(minVal);
		}
		if(parseFloat(input) > maxVal) //if over set to max limit
		{
			  return(maxVal);
		}
	}
	return input;
}

function isNumber(input) 
{
	var dec = 0;
   for (var i=0;i<input.length;i++) 
   {
       var oneChar = input.substring(i, i+1);
	 
       if (oneChar < "0" || oneChar > "9") 
	   {
          if (oneChar == ".") 
		  {
			  dec++;
		  }
		  else
		  { 
             return(false);
          }
       }
   }
   if(dec >1)
   {
	   return(false);
   }
   else
   {
   		return(true);
   }
}

function isInteger(input)
{
   for (var i=0;i<input.length;i++) 
   {
       var oneChar = input.substring(i, i+1);
       if (oneChar < "0" || oneChar > "9") 
	   {  
             return(false);
       }
   }
   return(true);
}

function Collection(item1, item2, item3, item4, item5, item6, item7, item8, item9) 
{
   this.item1 = item1;
   this.item2 = item2;
   this.item3 = item3;
   this.item4 = item4;
   this.item5 = item5;
   this.item6 = item6;
   this.item7 = item7;
   this.item8 = item8;
   this.item9 = item9;
}

function Loan(Income, Frequency, Dependants, Joint, OLoans, CCLimit, Rate, Term, Periods) 
{
   this.Income = Income; 
   this.Frequency = Frequency;
   this.Dependants = Dependants;
   this.Joint = Joint;
   this.OLoans = OLoans;
   this.CCLimit = CCLimit;
   this.Rate = Rate;
   this.Term = Term;
   //this.Payment = Payment;
   this.Periods = Periods;
   this.setRate = setRate;
   this.calcIncome = calculateIncome;
   this.calcPeriods = calculatePeriods;
   this.calcTax = calculateTax;
   this.calcLivingExp = calculateLivingExp;  
   this.calcOtherLoans = calculateOtherLoans;
   this.calcBorrowAmount = calculateBorrowAmount;
}

function radio_item(value) 
{   
   this.value = value;
}

function get_checked(radio_object)
{
	contents = new radio_item();
	
	for(var i=0;i<radio_object.length;i++)
	{
      if(radio_object[i].checked == true) 
	  {
        	contents.value = radio_object[i].value;
      }   
	}
   return(contents.value);
}

function calcRound(num) 
{
   var result="$"+formatInt(num);

   return(result);
}


function formatInput(input,type)
{
	var value = stripFormatting(input.value);
	for (b in oVal) 
	{
		if(oVal[b] == input.name)
		{
			if(!isNumber(value)||value.isNaN)
			{	
				value = String(oMin[b]);
			}
			else
			{
				value = String(inRange(value, oMin[b], oMax[b]));
			}
		}
	}
	switch (type)
	{
		case "int": //integer
			input.value = formatInt(value);
			break;
		case "cur": //currency - no cents
			input.value = "$"+formatInt(value);
			break;
		case "flt": //float - 2 decimal places
			input.value = formatFlt(value)+"%";
			break;
	}

}
function formatInt(num)
{
	num = String(Math.floor(num));
	var len = num.length;
	var result = "";
	if (len < 4)
	{
		result = num;
	}
	else
	{
		var unary = "";
		if(num.charAt(0) == "-")
		{
			num = num.substr(1,(len-1)); //remove minus sign
			unary = "-";
			len -=1;
		}
		for(i=len;i>=0;i--)
		{
			if(((len-i)%3 == 0)&&(i != len)&&(len-i != len))
			{
				result = ","+num.charAt(i)+result;
			}
			else
			{
				result = num.charAt(i)+result;
			}
		}
		result = unary+result;
	}
	return result;
}

function formatFlt(num)
{
var result=formatInt(num);
	var decimal = num.indexOf(".");
	
	if (decimal > -1)
	{
		var len = num.length;
		var dnum = num.substring(decimal+1,len);
		
		var dlen = dnum.length;
		switch (dlen)
		{
			case 0:
				result = result+".00";
				break;
			case 1:
				result = result.concat(".",num.substr(decimal+1,1),"0");
				break;
			case 2:
				result = result.concat(".",num.substr(decimal+1,2));
				break;
			default:
				 d1 = num.substr(decimal+1,2);
				 d2 = num.substring(decimal+3,len);
				 dnum = d1.concat(".",d2);
				 dnum = Math.round(dnum);
				 if(dnum == 100)
				 {
					 result = parseInt(result)+1;
					 result = result+".00";
				 }
				 else
				 {
				 	result = result.concat(".",dnum);
				 }
				break; 
		 }
	}
	else
	{
		result = result+".00";
	}

   return(result);
}
function stripFormatting(input)
{
	var value = input.replace(/,/g,"");
	value = value.replace(/\$/g,"");
	value = value.replace(/%/g,"");
	
	return value;
}

function calculatePeriods() 
{
   switch (this.Frequency)
   {
	   case "yearly":
	   	this.Periods=1;
		break;
	   case "monthly":
	   	this.Periods=12;
	   break;
	   case "fortnightly":
	   	this.Periods=26;
	   break;
	   case "weekly":
	   	this.Periods=52;
		break;	
   }
}

function calculateIncome()
{
	this.Income = this.Periods*this.Income;
}

function calculateTax()
{
	
var tax = 0;	
if(this.Income<6001)
	{tax = 0;}
else if(this.Income<21601)
	{tax =((this.Income-6001)*0.17);}
else if	(this.Income<58001)
	{tax =((this.Income-21601)*0.30)+2652;}
else if(this.Income<70000)
	{tax =((this.Income-58001)*0.42)+13572;}
else	
	{tax =((this.Income-70000)*0.47)+18612;}
	
return tax;
}

function calculateLivingExp()
{
	if(this.Joint == "no")
		{var a = 10000;}
	else
		{var a = 14500;}
	if (this.Dependants < 1)	
		{var b = 0;}
	else
		{var b = 3400 + ((this.Dependants-1)*2300);}

	var lexp = (a+b)/this.Periods; //divide by period if not yearly

return lexp;
}
function setRate()
{
	this.Rate = (this.Rate/100)+0.015;
}

function calculateOtherLoans()
{
	var p = parseInt(this.OLoans) + parseInt(this.CCLimit);
	var r = this.Rate;
	var q = this.Periods;
	var n = this.Term;
	var payment = 0;
	if(p >0 )
	{
		payment = ((p*r)/(q*(1-(Math.pow((1+(r/q)),(-n*q))))));
	}
		
return payment;
}

function calculateBorrowAmount()
{	
	var netAvail = ((this.Income - this.calcTax())/this.Periods) - (this.calcLivingExp() + this.calcOtherLoans());
	var r = this.Rate/this.Periods;
	var pv = netAvail*((1 - Math.pow((1+r),-this.Term*this.Periods))/r);
	if (pv < 1)
	{
		pv = 0;
	}
return pv;
}

function prepareEdit(input)
{
	input.value = stripFormatting(input.value);
	input.select();
}

function clearResult()
{
	document.loancalc.canborrow.value = "";
}
function blockNonNumbers(type)
{
	switch (type)
	{
		case "int":
		if (event.keyCode < 48 || event.keyCode > 57)
		{
			 event.returnValue = false;
		}
		break;
		case "flt":
		if ((event.keyCode < 48 || event.keyCode > 57) && event.keyCode != 46)
		{
			 event.returnValue = false;
		}
	}
}
//-->