// JavaScript Document - Savings Calculator Functions


//Build an array to keep the last calculated value.
anchor = new Array(0,0,0,0,0);


function calculateSavings()
{
//Validate incoming fields 

pv = document.getElementById("PRESENT_VALUE").value;
fv = document.getElementById("SAVINGS_GOAL").value;
np = document.getElementById("SAVINGS_PERIOD").value;
pmt = document.getElementById("DEPOSIT_AMT").value;
ir = document.getElementById("INTEREST_RATE").value;
paymentperiod = 12;
durationperiod = document.getElementById("SAVINGS_PERIOD_FREQ").options[document.getElementById("SAVINGS_PERIOD_FREQ").selectedIndex].value;


if ((pv.length > 0) && (pv < 0))
{
   alert('Initial Investment must be a positive number');
   return;
}

if ((pmt.length > 0) && (pmt < 0))
{
   alert('Monthly Deposit must be a positive number');
   return;
}


if ((np.length > 0) && (np < 0))
{
   alert('Saving Period must be a positive number');
   return;
}

if ((ir.length > 0) && (ir < 0))
{
   alert('Interest Rate must be a positive number');
   return;
}

if ((fv.length > 0) && (fv < 0))
{
   alert('Savings Goal must be a positive number');
   return;
}


if ((pv.length > 0) && (isNumeric(pv) == false))
{
   alert('Initial Investment must be numeric');
   return;
}

if ((pmt.length > 0) && (isNumeric(pmt) == false))
{
   alert('Monthly Deposit must be numeric');
   return;
}


if ((np.length > 0) && (isNumeric(np) == false))
{
   alert('Saving Period must be numeric');
   return;
}

if ((ir.length > 0) && (isNumeric(ir) == false))
{
   alert('Interest Rate must be numeric');
   return;
}

if ((fv.length > 0) && (isNumeric(fv) == false))
{
   alert('Savings Goal must be a numeric');
   return;
}

//Store incoming values in an array

tmpInValues = new Array(pv, pmt, ir, np, fv);

m = 0;
blankCount=0;
var blankIndex;
for(m=0;m<tmpInValues.length;m++) 
{
	if(tmpInValues[m] == '') 
	{
		blankCount++;
		blankIndex = m;
	}
}

//Determine how many of the fields are blank

if(blankCount > 1)
{
alert('Please fill in all but one entry');
} 
else 
{
if(!(blankIndex >= 0)) 
{
	//find the last value calculated from anchor
	var y;
	for(y=0;y<anchor.length;y++) 
	{
	if(anchor[y] == 1) 
	{
		blankIndex = y;
	}
	}
}

for(w=0;w<anchor.length;w++) 
{
	anchor[w] = 0;
	if(w==blankIndex) 
	{
	anchor[w] = 1;
	}		
}

if (np != "") 
{
   np = np * paymentperiod * durationperiod;
} 
else
{
	np = 0;
} 

if(ir != "") 
{
	ir = (ir / paymentperiod ) / 100 ;
}

ir = parseFloat(ir);
np = parseFloat(np);
fv = parseFloat(fv);
pmt = parseFloat(pmt);
pv = parseFloat(pv);
	
switch(blankIndex.toString()) 
{
	case "0":
	document.getElementById("PRESENT_VALUE").value = PresentValue();
	break;
	case "1":
	document.getElementById("DEPOSIT_AMT").value = DepositAmount();
	break;
	case "2":
	document.getElementById("INTEREST_RATE").value = InterestRate();
	break;
	case "3":
	document.getElementById("SAVINGS_PERIOD").value = SavingsPeriod();
	break;
	case "4":
	document.getElementById("SAVINGS_GOAL").value = FutureValue();
	break;
}	
}	
}		

function PresentValue() 
{
	pmt = pmt * -1;

	if(ir == 0) 
	{
		pv = (fv + (pmt * np));
	}
	else {
		q1 = Math.pow(1 + ir,-np);
		q2 = Math.pow(1 + ir,np);
		pv = (q1 * (fv * ir - pmt + q2 * pmt))/ir;
	}
	return RoundToHundreths(pv);
}  // End of Present Value

function FutureValue()
{
if(ir == 0) 
{
  fv = (pv + (pmt * np));
}
else 
{
	q = Math.pow(1+ir,np);
	fv = (-pmt + q * pmt + ir * q * pv)/ir;
}
return RoundToHundreths(fv);
}  // End of FutureValue


function SavingsPeriod()
{
pmt = pmt * -1;
pv = pv * -1;

if(ir == 0)
{
	if(pmt != 0) 
	{
		np = - (fv + pv)/pmt;
	}
	else 
	{
		alert("Divide by zero error.");
	}
}
else 
{
	np = Math.log((-fv * ir + pmt)/(pmt + ir * pv))/ Math.log(1 + ir);
}
if(np == 0) 
{
	alert("Can't compute Number of Periods for the present values.");
}
else 
{
	var durationmult = 0;
	if (durationperiod == 1){durationmult = .08333333333;}
	if (durationperiod == .25){durationmult = .3333333333;}
	if (durationperiod == .083333333333){durationmult = 1;}
	if (durationperiod == .019165364791){durationmult = 4.3480;}								
	return RoundToHundreths(np * durationmult);
}
} //End of Savings Period


function DepositAmount()
{	
pv = pv * -1;

if(ir == 0.0) 
{
	if(np != 0) 
	{
		pmt =  (fv + pv)/np;
	}
	else 
	{
		alert("Divide by zero error.");
	}
}
else 
{
	q = Math.pow(1 + ir,np);
	pmt = ((ir * (fv + q * pv))/(-1 + q));		
}

return RoundToHundreths(pmt);

}//End of Deposit Amount


function DepositAmountIntCalc(pv, ir)
{

ir = parseFloat(ir/paymentperiod/100);

	
if(ir == 0.0) 
{
	if(np != 0) 
	{
		pmt = - (fv + pv)/np;
	}
	else 
	{
		alert("Divide by zero error.");
	}
}
else 
{
	q = Math.pow(1 + ir,np);
	pmt = ((ir * (fv + q * pv))/(-1 + q));		
}

return RoundToHundreths(pmt);

}//End of Deposit Amount for Interest  Calc	

function InterestRate()
{	
initialInterest = 10000;
var paymentTmp = 0;
var low = 0;
var high = 10000;	
var realPayment = parseFloat(pmt);	

low = parseFloat(low);
high = parseFloat(high);
paymentperiod = parseFloat(paymentperiod);

pv = pv * -1;

if ((fv - (-pv + (np * realPayment))) < 0) 
{
	alert('This calculation resulted in negative interest.  Please increase the Savings Goal, or reduce the Savings Period, Initial Investment or Monthly Deposit.');
	return 'Error';
}
else
{

	for( i = 0; i < 200; i++) 
	{
		paymentTmp = DepositAmountIntCalc(pv, initialInterest);	
	
		   if ( paymentTmp < realPayment) {
			   high = initialInterest
		   } else if(paymentTmp > realPayment) {
		   low = initialInterest;
			  } else {
			  break;
			}

	   initialInterest = low + ((high - low) /2);
	}   
}

return RoundToHundreths(initialInterest);

} //End of  InterestRate	


function isNumeric(strString)
//  check for valid numeric strings	
{
var strValidChars = "0123456789.-";
var strChar;
var blnResult = true;

//  test strString consists of valid characters listed above
for (i = 0; i < strString.length && blnResult == true; i++)
  {
  strChar = strString.charAt(i);
  if (strValidChars.indexOf(strChar) == -1)
	 {
	 blnResult = false;
	 }
  }
return blnResult;
}

function RoundToHundreths(iValue) {

// Round the value to Hundreths
iValue = Math.round(iValue*100);
iValue = iValue / 100;

//Give me two decimal places

iValue = iValue.toString();

var posDecimalPoint=  iValue.indexOf('.');
if (posDecimalPoint == -1) {
	iValue += ".00";
} else if ( length - posDecimalPoint == 2) {
	iValue += "0";
} else if (length - posDecimalPoint == 1) {
	iValue += "00";
} 

return iValue;

}


function replace_punct(element) { //v2.0
var c= element.value; 
c=c.replace(/[|,|\$]| /g, '');
element.value = c;
return true;
}