// Pay or Invest JS File


//Script for error suppression
function bpTrapError(msg, URI, ln) {return true;}
window.onerror = bpTrapError;


//----------BEGIN GENERIC FUNCTIONS----------------------------------------------------------
function fnGetObj(name)
{ //Generic function to get object reference for most browsers
  if (document.getElementById)
  {
  	this.obj = document.getElementById(name);
	this.style = document.getElementById(name).style;
  }
  else if (document.all)
  {
	this.obj = document.all[name];
	this.style = document.all[name].style;
  }
  else if (document.layers)
  {
   	this.obj = document.layers[name];
   	this.style = document.layers[name];
  }
}

function fnValidateNumeric(fieldname)
{ //Validate a Field contains only valid numbers.

  //var fieldObj = new fnGetObj(fieldname);
  //var strValue = fieldObj.obj.value;
  //var strValue = fnTrimAll(fieldname);
  var strValue = fieldname;


  var objRegExp  =  /(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/;
  return objRegExp.test(strValue);
}

function fnTrimAll(strValue) 
{ //Remove leading and trailing spaces plus commas and dollar signs from provided string

  strValue = fnRemoveCommas(strValue);
  strValue = fnRemoveDollarSigns(strValue);
  var objRegExp = /^(\s*)$/;

  //check for all spaces
  if(objRegExp.test(strValue))
  {
    strValue = strValue.replace(objRegExp, '');
    if( strValue.length == 0)
    return strValue;
  }

  //check for leading & trailing spaces
  objRegExp = /^(\s*)([\W\w]*)(\b\s*$)/;
  if(objRegExp.test(strValue))
  {
    //remove leading and trailing whitespace characters
    strValue = strValue.replace(objRegExp, '$2');
  }

  return strValue;
}

function fnValidateInteger(fieldname)
{ //Validate a Field contains a valid integer number.

  var fieldObj = new fnGetObj(fieldname);
  var strValue = fieldObj.obj.value;
  strValue = fnTrimAll(strValue);

  var objRegExp  = /(^-?\d\d*$)/;
  return objRegExp.test(strValue);
}

function fnCheckField(fieldname)
{ //Check a Field (cannot be null, empty string, zero length, or string of blanks)
  
  var fieldObj = new fnGetObj(fieldname);
  var teststring = fieldObj.obj.value;

  teststring = fnTrimAll(teststring);
  if ((teststring == '') || (teststring == null) || (teststring.length == 0))
  {
    return false;
  }

  return true;
}

function fnValidatePosNum(fieldname)
{ //Validate a Number is Positive (including 0)

  var fieldObj = new fnGetObj(fieldname);
  var strValue = fieldObj.obj.value;
  strValue = fnTrimAll(strValue);

  return (parseInt(strValue,10)>=0); 
}


function fnRemoveCommas(strValue)
{  //Remove commas from string

  var objRegExp = /,/g; //search for commas globally
  
  //replace all matches with empty strings 
  return strValue.replace(objRegExp, '');
  
}

function fnRemoveDollarSigns(strValue)
{  //Remove dollar sign from string

  if(strValue.indexOf('$') >= 0)
  {
    strValue = strValue.substring(1, strValue.length);
  }
   return strValue;
}

function fnAddCommas(srcNumber)
{  //Add commas to number string

   var txtNumber = '' + srcNumber;
   if (isNaN(txtNumber) || txtNumber == "") {
      return srcNumber;
   }
   else 
   {
      var rxSplit = new RegExp('([0-9])([0-9][0-9][0-9][,.])');
      var arrNumber = txtNumber.split('.');
      arrNumber[0] += '.';
      do
      {
         arrNumber[0] = arrNumber[0].replace(rxSplit, '$1,$2');
      } 
      while (rxSplit.test(arrNumber[0]));
      if (arrNumber.length > 1)
      {
         return arrNumber.join('');
      }
      else
      {
      return arrNumber[0].split('.')[0];
      }
   }
}

function fnShowHide(fieldname, desiredaction)
{  //Function to Show or Hide a Field
   
   var fieldObj = new fnGetObj(fieldname);

   if (desiredaction == "Hide")
   {
      if (fieldObj.style.display != "none")
      {
         fieldObj.style.display = "none";
      }
   }
   
   if (desiredaction == "Show")
   {
      if (fieldObj.style.display == "none")
      {
         fieldObj.style.display = "";
      }
   }
}


function findPosX(obj)
{
	var curleft = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}

function findPosY(obj)
{
	var curtop = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
}

function fnShowNote(InfoText,obj,NoteHeight)
{
  var ToolTip = new fnGetObj("largenote");
  
  if (ToolTip.style.visibility=="visible") {
	ToolTip.style.visibility = "hidden";
  } 
  else {
	  
	  ToolTip.style.left = findPosX(obj);
	  ToolTip.style.top = findPosY(obj)-NoteHeight;
	
	  var ToolTipText = new fnGetObj("largenotetext");
	  ToolTipText.obj.innerHTML = "<font size=1 color='#000000' style='font-family:Verdana, Arial, Helvetica, sans-serif'>" + InfoText + "</font>";
	
	  ToolTip.style.visibility = "visible";
	  //window.status="visible";  
  }
  
}


function fnHideNote() {
   var ToolTip = new fnGetObj("largenote");
   ToolTip.style.visibility = "hidden"; 
   //window.status="hidden";  
}


function fnAddDollarSign(number)
{
	var output, num;
	if(isNaN(eval(number))) num = 0;
	else num = number.toFixed(2)
	
	
	var commas = fnAddCommas(num);
	
	if(number < 0){
		output = "-$" + commas.substring(1, commas.length);	
	}
	else{
		output = "$" + commas;	
	}
	return output;
}



function fnFormatInput(ref)
{
	//alert(ref.id);
	var ref = new fnGetObj(ref.id);
	var value = fnTrimAll(ref.obj.value);

	//Remove non-numeric characters; This is to prevent users from pasting a string.
	value = fnRemoveNonNumeric(value);

	//Remove unnecesary 0's from the input.
	value = fnRemoveLeadingZeros(value);

	//Add commas
	value = fnAddCommas(value);

	//Display the value on the textbox
	ref.obj.value = value;
	
	
}

function fnFormatInput2(id) //This version is used for the Current Age and Age of Retirement
{
	var ref = new fnGetObj(id);
	var value = fnTrimAll(ref.obj.value);
	
	
	//Remove non-numeric characters; This is to prevent users from pasting a string.
	value = fnRemoveNonNumeric(value);

	//Remove unnecesary 0's from the input.
	value = fnRemoveLeadingZeros(value);

	//If Age of Retirement = 0, then make it 1 (default value)
	if(value == 0 && id == 'ageAtRetirement') value = 1;
	

	//Display the value on the textbox
	ref.obj.value = value;
	
}


function fnCheckInput(e, ref, count) //Check user's input | DO NOT ALLOW COMMAS
{
	
	/*
	Function will do the following:
		-Function checks every keystroke (onKeyPress event) for the set parameters below.
		-If the user presses a key that is not defined, the function will return false.
		-The function has a counter to limit the amount of characters the user can enter. 
		 This is useful when you want to format the text inside the textbox after the user enters data. Example: textbox maxlength='8', 
		 function limits user to 6 chartacters, so we have 2 characters available for commas, periods, etc. (need to do this for Safari and NS)
		-Function limits the user to only one period per textbox.
		
	List of ASCII codes:
	
		Symbol		Code
		------		----
		,			44
		.			46
		$			36
		<			60
		>			62
		0 - 9		48 - 57
		a - z		97 - 122
		A - Z		65 - 90
		backspace	8
		delete		127
		del (Mac)	63272
		tab			9
		Arrows		0
		
	For more symbols: http://www.ascii.cl/htmlcodes.htm
	*/
	
	var key = window.event ? e.keyCode : e.which; //Determine which key the user pressed
	//alert("key: " + key);
	//var keychar = String.fromCharCode(key);
	
	//If key pressed is one of the following, return true: 'delete', 'backspace', 'tab' 
	//This is a workaround for the MAC not allowing users to delete input once the limit (counter) reached 6.
	
	// delete (win)  backspace   --tab--    delete (Mac)  left arrow (Mac) right arrow (Mac)
	if(key == 127 || key == 8 || key ==9 || key == 63272 || key == 63234 || key == 63235) 
	{
		
		return true;
		fnCalculatePayBal();
	}
	else
	{
		var id = ref.id;
		//alert(ref.id);
		var element = new fnGetObj(id);
		var counter;
		counter = element.obj.value.length; //Count the number of characters in the text box
		//alert(counter);
		
		if (counter >= count) //If user enteres more than 6 characters return false and prevent user from entering more data
		{	
			if(key == 0) return true; //Allow Arrow Keys when the limit is reached
			else return false;				
		}
		else
		{

			// ------------------ Numbers-----------------------   --comma--      --period--    ---delete---  Backspace
			if ((key > 47 && key < 58) || (key == 0 || key == 8 || /*(key == 44) ||*/ (key == 46)) || key == 127 || key == 8) //Valid Input (numbers, commas, periods, backspace, delete
			{
				var elContent = element.obj.value; //Get textbox content
				//alert("elContent: " + elContent);
				
				if((key == 46) && elContent.indexOf(".") != -1) //If there is already a period on the input field, return false
				{
					return false;	
				}
				if(key == 0) return true; //Do not run the function if user presses the arrow keys
				else setTimeout("fnCalculatePayBal();", 100); //delay: allows function to capture the entire value inputted; otherwise, last value entered is lost.
			}
			else //Invalid input, return false
			{
				return false;
			}
		}
	}
}

function fnCheckInput2(e, ref, count) //Check user's input | DO NOT allow periods or commas
{
	var key = window.event ? e.keyCode : e.which; //Determine which key the user pressed
	//alert("key: " + key);
	//var keychar = String.fromCharCode(key);
	
	//If key pressed is one of the following, return true: 'delete', 'backspace', 'tab' 
	//This is a workaround for the MAC not allowing users to delete input once the limit (counter) reached 6.
	
	// delete (win)  backspace   --tab--    delete (Mac)  left arrow (Mac) right arrow (Mac)
	if(key == 127 || key == 8 || key ==9 || key == 63272 || key == 63234 || key == 63235) 
	{
		return true;
		fnCalculatePayBal();
	}
	else
	{
		var id = ref.id;
		//alert(ref.id);
		var element = new fnGetObj(id);
		var counter;
		counter = element.obj.value.length; //Count the number of characters in the text box
		//alert(counter);
		
		if (counter >= count) //If user enteres more than 6 characters return false and prevent user from entering more data
		{	
			if(key == 0) return true; //Allow Arrow Keys when the limit is reached
			else return false;			
		}
		else
		{

			// ------------------ Numbers-----------------------   --comma--      --period--    ---delete---  Backspace
			if ((key > 47 && key < 58) || (key == 0 || key == 8 || (key == 44) /*|| (key == 46)*/) || key == 127 || key == 8) //Valid Input (numbers, commas, periods, backspace, delete
			{
				var elContent = element.obj.value; //Get textbox content
				//alert("elContent: " + elContent);
				
				/*
				if((key == 46) && elContent.indexOf(".") != -1) //If there is already a period on the input field, return false
				{
					return false;	
				}
				*/
				if(key == 0) return true; //Do not run the function if user presses the arrow keys
				else setTimeout("fnCalculatePayBal();", 100); //delay: allows function to capture the entire value inputted; otherwise, last value entered is lost.
			}
			else //Invalid input, return false
			{
				return false;
			}
		}
	}

//clearTimeout(globalTimeout);
//globalTimeout = setTimeout("fnShowHide('loaderDiv', 'Show');", 100);
}


function fnRemoveLeadingZeros(value)
{
	/*
	Function will do the following:
		-If there are zeros to the left of a number, it will remove all of them. Example: '00150' -> '150'
		-If there is a period and there are more than one zero to the left of it, it will remove all but one zero. Example: '00.50' - > '0.50'
		-If the value starts with a period, it will add a zero to the left of the period. Example: '.50' - > '0.50'
		-If the user entered one or more zeros in the input box, the value will default to one zero. Example: '000' -> '0'
		-If the last character is a period, the function will remove the period. Example: '5000.' - > '5000'
		
	Assumptions:
		-The user will only be allowed to enter ONE period in the text box. (fnCheckInput)
	*/
	
	
	val = value;
	
	var newVal = val;
	var nextVal;
	var prevVal;
	var currCharacter;
	
	if(val.indexOf(".") == 0) newVal = "0" + newVal; //If the value starts with a period, add a zero. Example: ".5" -> "0.5"
	//if(val.indexOf(".") == (val.length - 1)) newVal = newVal + "00";
	
	if(val.indexOf("0") != -1)
	{
		
		for(i = 0; i <= val.length - 1; i++)
		{
					
			if(val.charAt(i) == "0") //If current character is zero, start validation
			{
							
				prevVal = i-1;
				nextVal = i+1;
				
				if(prevVal < 0) prevVal = 0; //If previous value does not exist, make prevVal the current value
				
				if(val.charAt(prevVal) == "0")
				{
						
					if(i < val.indexOf(".")) //If the current character comes BEFORE the period
					{
						var curr = parseInt(i);
						var period = parseInt(val.indexOf("."));
					
						if((period - curr) <= 1)
						{
							break;	
						}
						else if((period - curr) > 1)
						{
							newVal = val.substring(nextVal);
						}
							
					}
					else
					{
						//alert(val.charAt(nextVal));
						if(val.charAt(nextVal) == "0")
						{
							newVal = val.substring(nextVal);
						}
						else if(val.charAt(nextVal) != "0")
						{
							newVal = val.substring(nextVal);
							break;
						}
			
					}
				
				}
				
			}
			else if(val.charAt(i) != "0")  //If current character is NOT zero, break loop
			{
				break;	
			}
			
		}
	}
	
	if(newVal.indexOf(".") == (newVal.length - 1)) newVal = newVal.substring(0, newVal.length - 1); //If the last character is a period, remove the period.
	if(newVal == "") newVal = 0; //If the user entered 1 or more zeros in the input field, default it to 1 zero
	
	return newVal;
}


function fnAddSpaces(value, spaces)
{
	var sOutput = "";
	var iCounter = 0;
	
	for(iChar = 0; iChar <= value.length - 1; iChar++)
	{
		sOutput += value.charAt(iChar);
		if (value.charAt(iChar) != " ") 
		{
			iCounter++;
			if (iCounter == spaces) 
			{
				iCounter = 0;
				sOutput += " ";
			}	
		} 
		else 
		{
			iCounter = 0;	
		}
		
	}	
	
	return sOutput;
}

function fnRemoveNonNumeric(value)
{
	var sOutput = "";
	
	for(l = 0; l <= value.length - 1; l++)
	{
			
		if (fnValidateNumeric(value.charAt(l)) == true || value.charAt(l) == ".") //If the character is numeric OR a period, add to output string
		{
			sOutput += value.charAt(l);
							
		} 
	
	}	
	//alert(sOutput);
	return sOutput;
}

function fnHideShowText(id, value, action)
{
	/*
	Insert the following parameters in the input element (textbox):
	
	onfocus=\"fnHideShowText(this.id, this.value, 'Hide')\" 
	onBlur=\"fnHideShowText(this.id, this.value, 'Show')\"
	
	*/
	
	var ref = new fnGetObj(id);
	var val = value;

	
	if(action == 'Hide') //User clicks on textbox (onFocus)
	{
		//alert("Hide");	
		ref.obj.className = 'txtbox';	
		if(value == pop19) //If textbox value = defaul value
		{
			val='';	
			ref.obj.value = val;
		}
	
	}
	else if (action == 'Show') //User clicks out of textbox (onBlur)
	{
		//alert("Show");
		if(value == '') 
		{
			val= pop19;
			ref.obj.className = 'txtboxGrey';
			ref.obj.value = val;
		}
		
	}
	
}


//----------END GENERIC FUNCTIONS----------------------------------------------------

//Global Variables

var currBal; //amountYouOwe;
var currPayment;
var intRate;
var monthlySavings;
var monthsToPay; 
var rateChange;

var option1, option2, option3;

var Interest;
var AmortizedPayment;

var globalTimeout;

//Arrays
var intPaidArr = new Array();
var timeToPayArr = new Array();
var emptyArr = new Array();
var labelArr = new Array();

//Graph variables
var graphDecimalsFlag; 
var label;
var ValScaler=1;
var graphDecimalsFlag2; 
var label2;
var ValScaler2=1;
var threshold=0;
var AbsMaxVal;

function fnAttachEvents()
{
	var formElements = new Array();
	formElements = document.getElementsByTagName('input');
	
	for(var i = 0; i < formElements.length; i++)
	{
		//if (id.search("c") > 0 || id.search("d") > 0)
		if(formElements[i].getAttribute("filter") == 'savings')
		{
			var id = formElements[i].id;
			//alert(id);
			id = id.toString();
			var el = new fnGetObj(id); 
			
			//Apply the onBlur events
			el.obj.onblur = function() 
			{
				fnFormatInput(this);
				//fnCalculatePayBal();
			} 
			/*
			//Apply the onKeyUp events
			el.obj.onkeyup = function() 
			{
				//fnCalculatePayBal();
			} 
			*/
			//alert("browser: " + BrowserDetect.browser + "\n" + "version: " + BrowserDetect.version + "\n" + "OS: " + BrowserDetect.OS);
		}
		if(formElements[i].getAttribute("filter") == 'debt')
		{
			var id = formElements[i].id;
			//alert(id);
			id = id.toString();
			var el = new fnGetObj(id); 
			
			//Apply the onBlur events
			el.obj.onblur = function() 
			{
				fnFormatInput(this);
				//fnCalculatePayBal();
			} 
			/*
			//Apply the onKeyUp events
			el.obj.onkeyup = function() 
			{
				//fnCalculatePayBal();
			} 
			*/
		}
	}
	//After page loads and events are added, perform calculations to populate table and graph
	fnCalculatePayBal();
}


function fnCheckKeyUp(e)
{
	var key = window.event ? e.keyCode : e.which; //Determine which key the user pressed
	//alert("key: " + key);
	//var keychar = String.fromCharCode(key);
	
	//If key pressed is one of the following, return true: 'delete', 'backspace', 'tab' 
	//This is a workaround for the MAC not allowing users to delete input once the limit (counter) reached 6.
	
	if(key == 37 || key == 39) return true;
	// delete (win)  backspace   backspace    Left Arrow   Right arrow
	else if(key == 127 || key == 8 || key == 46 /*|| key == 37 || key == 39*/) 
	{
		fnCalculatePayBal();
	}
	
}

function fnCheckLimits(element, dir, value, limit)
{
	if(dir == ">"){
		if(value > limit){ 
			value = limit;
			document.getElementById(element).value = limit;
		}	
	}
	if(dir == "<"){
		if(value < limit) value = limit;
		else if(isNaN(value)) value = limit;
	}
	return value;
}

function fnCalculatePayBal()
{
	var ref;

	//clear old values
	intPaidArr = new Array();
	timeToPayArr = new Array();
	emptyArr = new Array();
	labelArr = new Array();
	
	//Get Current Balance od Debt
	var cBal = new fnGetObj('currBal');
	currBal = fnRemoveCommas(cBal.obj.value);
	currBal = parseFloat(currBal);
	currBal = fnCheckLimits('currBal', '<',  currBal, 0.01);
	
	//Get Current Monthly Payment
	var cPayment = new fnGetObj('currPayment');
	currPayment = fnRemoveCommas(cPayment.obj.value);
	currPayment = parseFloat(currPayment);
	currPayment = fnCheckLimits('currPayment', '<',  currPayment, 0);
		
	//Get Interest Rate
	var iRate = new fnGetObj('intRate');
	intRate = fnRemoveCommas(iRate.obj.value);
	intRate = parseFloat(intRate);
	//if(intRate < 1 || isNaN(intRate)) intRate = 1;
	intRate = fnCheckLimits('intRate', '>',  intRate, 50);
	intRate = fnCheckLimits('intRate', '<',  intRate, 0);
	//intRate = intRate/100;
	
	
	//Get Desired Months to Pay Off
	var mToPay = new fnGetObj('monthsToPay');
	monthsToPay = fnRemoveCommas(mToPay.obj.value);
	monthsToPay = parseFloat(monthsToPay);
	monthsToPay = fnCheckLimits('monthsToPay', '>',  monthsToPay, 120);
	monthsToPay = fnCheckLimits('monthsToPay', '<',  monthsToPay, 1);
		
	//Get Predicted Rate Change
	var rChange = new fnGetObj('rateChange');
	rateChange = parseFloat(rChange.obj.value);
	
	
	//Interest and fees saved if pay off now

	//var totalamount = currBal + (Math.floor((monthsToPay-1)/12)+1) * rateChange; //add in annual fees at beginning
	//AmortizedPayment = (totalamount*((intRate/(1200))/(1-(Math.pow(1+(intRate/(1200)),(monthsToPay-1))))));
	//AmortizedPayment = (totalamount*((intRate/(1200))/(1-(Math.pow(1+(intRate/(1200)),(-monthsToPay))))));
	
			
	clearTimeout(globalTimeout);
		
	fnShowHide('loaderDiv1', 'Show');
	fnShowHide('loaderDiv2', 'Show');


	//Update Results Table
	
	//Row 2
	var monthsItWillTake = 0;
	var noInt = false;
	if(intRate == 0 && rateChange < 0.5){ monthsItWillTake = Math.ceil(currBal/currPayment); noInt = true;}
	else monthsItWillTake = fnCalcMonth(currPayment,currBal,intRate,rateChange, 5000, monthsToPay);
	
	var m = "months"; //Either 'months' or 'month'
	if(monthsItWillTake <= 1) m = "month";
	
	if(currBal <= 0.01){
		option2 = "<br><b>Your Balance is $0.</b><br><br>";
	}
	else if(isNaN(monthsItWillTake) || (noInt == false && monthsItWillTake > 5000) ){
		//option2 = "<br>You are <a class='popup' href=\'javascript:void(0);\'  onClick=\'fnShowNote(pop1,this,90);\'>unable to pay off</a> your balance.<br><br>";
		option2 = "<br>You will be <b>unable to pay off</b> your balance because your monthly interest is greater than your monthly payment.<br><br>";
	}
	else if (currPayment > currBal) {
		option2 = "<br>Given your anticipated payment of <b>" + fnAddDollarSign(Math.abs(currPayment)) + "</b> per month, you will repay your $" + fnAddCommas(currBal) + " balance in <b>" + Math.ceil(monthsItWillTake).toFixed(0) + " " +  m +"</b>.<br><br>";
	}
	else{
		option2 = "<br>Given your anticipated payment of <b>" + fnAddDollarSign(Math.abs(currPayment)) + "</b> per month, you will repay your $" + fnAddCommas(currBal) + " balance in <b>" + Math.ceil(monthsItWillTake).toFixed(0) + " " +  m +"</b>.<br><br>";
	}
	
		
	
	ref = new fnGetObj('option2');
	ref.obj.innerHTML = option2;
	

	//globalTimeout = setTimeout('fnCalcInterestAndPayments(currBal,intRate,rateChange,monthsToPay)', 200);
	fnCalcInterestAndPayments(currBal,intRate,rateChange,monthsToPay);
	
	
	//Update the first and third row (These rows need to be calculated after the graphs update
	fnUpdateTable();
		
	
	//Draw Time to Pay Off vs. Monthly Payment Chart
	globalTimeout = setTimeout("fnDrawGraph('chart2', '2')", 300);
		
	//Draw Interest Paid Chart
	globalTimeout = setTimeout("fnDrawGraph('chart', '1')", 600);
	
	
	/*	
	//Update Term Invested (either 'months' or 'years')
	var t, tOut;
		
	if(monthsToPay <= 23) tOut = "Months";
	else tOut = "Years";
	
	t = new fnGetObj('term1');
	t.obj.innerHTML = tOut;
	
	t = new fnGetObj('term2');
	t.obj.innerHTML = tOut;
	
	t = new fnGetObj('printterm1');
	t.obj.innerHTML = tOut;
	
	t = new fnGetObj('printterm2');
	t.obj.innerHTML = tOut;
	*/

	//Enable Print button (Amount Owed and Monthly savings = 0)
	var btn = new fnGetObj('printBtn');
	
	if(currBal <= 0.01 || currBal-currPayment < 1) btn.obj.disabled = true;
	else btn.obj.disabled = false;
}


function fnUpdateTable()
{
	var ref, intSaved;
	var bal, pay, months;
	
	//ref = new fnGetObj('intSaved');
	
	//Interest saved if you pay off balance now:
	var cBal = new fnGetObj('currBal');
	bal = fnRemoveCommas(cBal.obj.value);
	bal = parseFloat(bal);
	
	var cPayment = new fnGetObj('currPayment');
	pay = fnRemoveCommas(cPayment.obj.value);
	pay = parseFloat(pay);
	
	var iRate = new fnGetObj('intRate');
	int = fnRemoveCommas(iRate.obj.value);
	int = parseFloat(int);
	//alert(int);

	if(bal - pay < 1 || bal <= 0 || isNaN(bal)) intSaved = 0;
	else if(int <= 0 || isNaN(int)) intSaved = 0;
	else intSaved = Math.abs(intPaidArr[monthsToPay]);
	//ref.obj.innerHTML = "<b>" + fnAddDollarSign(intSaved) + "</b>";
	
	/*
	http://www.hughchou.org/calc/formula.html
	n = - (LN(1-(B/m)*(r/q)))/LN(1+(r/q))
	
	q = amount of annual payment periods 
	r = interest rate 
	B = principal 
	m = payment amount 
	n = amount payment periods 
	LN = natural logarithm 
	*/
	
	//Monthly payment if you pay off balance in X months: X
	//ref = new fnGetObj('monthlyBal');
	
	var mToPay = new fnGetObj('monthsToPay');
	months = fnRemoveCommas(mToPay.obj.value);
	months = parseFloat(months);
	if(isNaN(months)) months = 0;
	
	//ref.obj.innerHTML = "<b>" + months + "</b>";
	
	//ref = new fnGetObj('monthlyPayment');
	if(bal <= 0.01 || isNaN(bal))
	{
		option1 = "<br><b>Your Balance is $0.</b><br><br>";
		option3 = "<br><b>Your Balance is $0.</b><br><br>";
	}
	else
	{	
		var m = "months"; //Either 'months' or 'month'
		if(months <= 1) m = "month";
		option1 = "<br>To pay off your $" + fnAddCommas(currBal) + " balance in the desired <b>" + months + "</b> " + m +", your monthly payment will be <b>" + fnAddDollarSign(Math.abs(timeToPayArr[monthsToPay])) + "</b>.<br><br>";
		option3 = "<br>By paying off your $" + fnAddCommas(currBal) + " balance right now, you will save at least <b>" + fnAddDollarSign(intSaved) + "</b> in interest in a " + months + "-month period.<br><br>"; 
		
		
	}
	//else ref.obj.innerHTML = "<b>" + fnAddDollarSign(Math.abs(timeToPayArr[monthsToPay-1])) + "</b>";
	//--------------------------------------------------------------------------------------------------
	
	
	ref = new fnGetObj('option1');
	ref.obj.innerHTML = option1;
	
	ref = new fnGetObj('option3');
	ref.obj.innerHTML = option3;	
}



function fnCalcInterestAndPayments(balance,interest,rateIncrease,maxMonths) {
	var sAccuracy = 0.0001;
	
	for (var calcMonth = 1; calcMonth <= maxMonths;calcMonth++) {
		//binary search to find best result

		var maxVal = balance;
		var minVal = 0;
		var testVal = (maxVal + minVal)/2;
		var testMonth = 0;
		var blnDone = false;
		
		while (!blnDone) {
			testMonth = fnCalcMonth(testVal,balance,interest,rateIncrease, maxMonths, calcMonth);
			//document["loader"].src="Images/ajax-loader.gif"; //Re-assign the source to prevent the image animation to stop while on loop
			if (testMonth>calcMonth) {
				if (minVal > testVal-sAccuracy) {
					blnDone = true;
				} else if (maxVal > testVal+sAccuracy) {
					minVal = testVal;
					testVal = (maxVal + minVal)/2;
				} else {
					blnDone = true;
					testMonth = fnCalcMonth(maxVal,balance,interest,rateIncrease, maxMonths, calcMonth);
				}
			} else if (testMonth <= calcMonth) {
				if (maxVal < testVal+sAccuracy) {
					blnDone = true;
				} else if (minVal < testVal-sAccuracy) {
					maxVal = testVal;
					testVal = (maxVal + minVal)/2;
				} else {
					blnDone = true;
					testMonth = fnCalcMonth(minVal,balance,interest,rateIncrease, maxMonths, calcMonth);
				}
			} else {
				blnDone = true;
			}
		}
	}
	
}


function fnCalcMonth(payment,origBalance,interest,rateIncrease, maxMonths,targetMonth) {
	var origInterest = interest;
	interest = 1 + (interest/1200);
	var balance = origBalance*interest;
	maxMonths = parseFloat(maxMonths);
	for (var currMonth = 1; currMonth <= maxMonths + 1;currMonth++) {
		balance -= payment;
		if (balance > 0) {
			balance *= interest;
			
			if (((currMonth) % 12) == 0)
			{
				interest += rateIncrease/1200;
				if(interest < 1.000000001) interest = 1.000000001;
			}
			
		} else {
			break;
		}	
	}
	
	timeToPayArr[0] = 0;
	intPaidArr[0] = 0;
	timeToPayArr[targetMonth] = payment;
	if (origInterest > 1.000000001 || interest > 1.000000001) {
		intPaidArr[targetMonth] = (payment*targetMonth) - origBalance;
		
	} else {
		intPaidArr[targetMonth] = 0.000000001;
		currMonth = Math.ceil(origBalance/payment);
	}
	
	return currMonth;
}


var step = 0;
var divider = 0;
function fnScaleLabels(range)
{
	step = 0;
	divider = 0;
	if(range == 'months'){//Monthly	
		step = 1; divider = 1;
	}
	else if(range == '2months'){//2-month
		step = 2; divider = 1;
	}
	else if(range == '6months'){//Yearly
		step = 6; divider = 6;
	}
	else if(range == 'yearly'){//Yearly
		step = 12; divider = 6;
	}
	else if(range == '2years'){//2 years
		step = 24; divider = 12;
	}
	else if(range == '5years'){//5 years
		step = 60; divider = 12;
	}
	else{ //10 years	
		step = 120; divider = 12;
	}
}


function fnDrawGraph(divID, chartNum) 
{

	var c = new Chart(document.getElementById(divID));
	
	//var labelArr = new Array();
	labelArr[0] = 0;
	
	var q, density;
	var d = 1;
	

	if(monthsToPay <= 12) fnScaleLabels('months');
	else if(monthsToPay <= 24) fnScaleLabels('2months');
	else if(monthsToPay <= 72) fnScaleLabels('6months');
	else fnScaleLabels('yearly');
	
	
	for(q=0; q <= monthsToPay; q++) 
	{
		if(monthsToPay <= 12) // If 24 months or less, display all labels
		{
			labelArr[q] = q;//Math.floor((q+1)/divider); 
			density = monthsToPay; //Show month 1 - 12	
		}
		else // Else, scale labels
		{
			if((q+1)%step == 1) labelArr[q] = q;//Math.floor((q+1)/divider); 
			else labelArr[q] = "";
			density = monthsToPay; //Add 1 to start labels at zero and display the years properly	; Start on year 0
		}
	}
	
	labelArr[0] = "";
	
	if(chartNum == '1')
	{
		//density++; //Adjust density for a bar chart; for line chart comment out.
		c.setDefaultType(CHART_BAR);
		c.setGridDensity(density, 9);
		//c.setVerticalRange(0, 100);
		c.setHorizontalLabels(labelArr);
		c.setShowLegend(false);
				
		if(monthsToPay < 24){ c.setBarWidth(10); c.setBarDistance(-10);}
		else if(monthsToPay < 48){ c.setBarWidth(6); c.setBarDistance(-6);}
		else if(monthsToPay < 96){ c.setBarWidth(4); c.setBarDistance(-4);}
		else if(monthsToPay < 108){ c.setBarWidth(2); c.setBarDistance(-2);}
		else{ c.setBarWidth(1); c.setBarDistance(-1)};
		
		//c.setPainterFactory(JsGraphicsChartPainterFactory); //SVGChartPainterFactory
		//c.setPainterFactory(CanvasChartPainterFactory);
		c.add('Interest', '#000066', intPaidArr);
		//c.add('0', '#000000', emptyArr);
		
		c.draw();
		globalTimeout = setTimeout("fnShowHide('loaderDiv1', 'Hide')", 50);
	}
	if(chartNum == '2')
	{
		//density++; //Adjust density for a bar chart; for line chart comment out.
		c.setDefaultType(CHART_BAR);
		c.setGridDensity(density, 9);
		//c.setVerticalRange(0, 100);
		c.setHorizontalLabels(labelArr);
		c.setShowLegend(false);
		//c.setBarDistance(0);
   		
		if(monthsToPay < 24){ c.setBarWidth(10); c.setBarDistance(-10);}
		else if(monthsToPay < 48){ c.setBarWidth(6); c.setBarDistance(-6);}
		else if(monthsToPay < 96){ c.setBarWidth(4); c.setBarDistance(-4);}
		else if(monthsToPay < 108){ c.setBarWidth(2); c.setBarDistance(-2);}
		else{ c.setBarWidth(1); c.setBarDistance(-1)};
		//c.setPainterFactory(JsGraphicsChartPainterFactory); //SVGChartPainterFactory
		//c.setPainterFactory(CanvasChartPainterFactory);
		c.add('Time', '#FF6600', timeToPayArr);
		//c.add('0', '#000000', emptyArr);
		
		c.draw();
	
		globalTimeout = setTimeout("fnShowHide('loaderDiv2', 'Hide')", 50);
	}
	
	//window.onload = function() {
	//ieCanvasInit('../JSGraphics/iecanvas.htc');
	//draw(); 
	//};
}



function fnClearAll()
{
	//Clear all textboxes
	var ref;
	
	ref = new fnGetObj('currBal');
	ref.obj.value = "1";
	
	ref = new fnGetObj('currPayment');
	ref.obj.value = "1";
	
	ref = new fnGetObj('intRate');
	ref.obj.value = "1";
	
	ref = new fnGetObj('monthsToPay');
	ref.obj.value = "2";
	
	ref = new fnGetObj('rateChange');
	ref.obj.value = "0";
		 
	fnCalculatePayBal();
		
}

function fnReset()
{
	fnClearAll();
	
	var ref;
	
	ref = new fnGetObj('currBal');
	ref.obj.value = val1;
	
	ref = new fnGetObj('currPayment');
	ref.obj.value = val2;
	
	ref = new fnGetObj('intRate');
	ref.obj.value = val3;
	
	ref = new fnGetObj('monthsToPay');
	ref.obj.value = val4;
	
	ref = new fnGetObj('rateChange');
	ref.obj.value = val5;
	
	
	fnCalculatePayBal();
	scroll(0,0); //Bump the page to the top.
	
	//Enable Print button (Amount Owed and Monthly savings = 0)
	var btn = new fnGetObj('printBtn');
	btn.obj.disabled = false;
}

function fnGeneratePrintPage()
{
	var ref, ref2, val;
	
	//Hide Normal DIVs
	var div = new fnGetObj('normalDIV');
	div.style.display = 'none';
	
	//Show Print DIV
	var div = new fnGetObj('printDIV');
	div.style.display = '';
	
	//Generate Printable charts
	fnDrawGraph('printchart1', '1');
	fnDrawGraph('printchart2', '2');
		
		
	//Generate data for Results Table
	ref = new fnGetObj('printoption1');
	ref.obj.innerHTML = option1;
	
	ref = new fnGetObj('printoption2');
	ref.obj.innerHTML = option2;
	
	ref = new fnGetObj('printoption3');
	ref.obj.innerHTML = option3;
		
	//Generate data for Inputs table
	
	ref = new fnGetObj('printcurrBal');
	ref.obj.innerHTML = "<b>" + fnAddDollarSign(currBal) + "</b>";
	
	ref = new fnGetObj('printcurrPayment');
	ref.obj.innerHTML = "<b>" + fnAddDollarSign(currPayment) + "</b>";
	
	ref = new fnGetObj('printintRate');
	ref.obj.innerHTML = "<b>" + intRate + "%</b>";
	
	ref = new fnGetObj('printmonthsToPay');
	ref.obj.innerHTML = "<b>" + monthsToPay + "</b>";
	
	ref = new fnGetObj('printrateChange');
	ref.obj.innerHTML = "<b>" + rateChange + "%</b>";
	
}

function fnBackToNormal()
{
	//Hide Print DIV
	var div = new fnGetObj('printDIV');
	div.style.display = 'none';
	
	//Show Normal DIV
	var div = new fnGetObj('normalDIV');
	div.style.display = '';
	
	//Enable Print button
	var printbtn = new fnGetObj('printBtn');
	printbtn.obj.disabled = false;
	
	scroll(0,0); //Bump the page to the top.
}


function formatbignums(inputval)
{
	var decimalPlaces = 0;
	//alert("inputval: " + inputval + "\n" + "threshold: " + threshold);
 	//alert("label: " + label + "\n" + "label2: " + label2);
	if(inputval > 0) //If value is positive, do normal scaling
	{
	   if(inputval < threshold) //Add decimal place
	   {
			if(graphDecimalsFlag2)  decimalPlaces = 1;   
			outputstring = fnAddCommas((inputval*ValScaler2*100)/100);
			outputstring = parseFloat(outputstring).toFixed(decimalPlaces) + label2;
			//if(inputval == 1000) outputstring = "1,000" + label2;
	   }
	   else
	   {
		   if(graphDecimalsFlag)  decimalPlaces = 1;
			outputstring = fnAddCommas((inputval*ValScaler*100)/100);
			outputstring = parseFloat(outputstring).toFixed(decimalPlaces) + label;
			if(inputval == 1000 && label == "") outputstring = "1,000";
	   }
	}
	else if(inputval < 0) //If value is negative, reverse scaling
	{
	   if(inputval > -threshold) //Add decimal place
	   {
			if(graphDecimalsFlag2)  decimalPlaces = 1;   
			outputstring = fnAddCommas((inputval*ValScaler2*100)/100);
			outputstring = parseFloat(outputstring).toFixed(decimalPlaces) + label2;
			//if(inputval == -1000) outputstring = "-1,000" + label2;
	   }
	   else
	   {
		   if(graphDecimalsFlag)  decimalPlaces = 1;
			outputstring = fnAddCommas((inputval*ValScaler*100)/100);
			outputstring = parseFloat(outputstring).toFixed(decimalPlaces) + label;
			//if(inputval == -1000) outputstring = "-1,000" + label;
	   }
	}
	else outputstring = 0;


   	return outputstring;
}



