function calcPV(inPMT, inFV, inNR, inNP, inC) {
	var outPV = inFV*Math.pow((1 + inNR/(100*inC)),(-inNP));
 	if (inNR == 0) {
 		outPV = outPV + inPMT*inNP;
 	} else {
 		outPV = outPV + inPMT*((1-(Math.pow((1 + inNR/(100*inC)),(-inNP))))/(inNR/(100*inC)));
 	}
 	return outPV;
}

function calcFV(inPMT, inPV, inNR, inNP, inC) {
	var outFV = inPV*Math.pow((1 + inNR/(100*inC)),(inNP));
 	if (inNR == 0) {
 		outFV = outFV + inPMT*inNP;
 	} else {
 		outFV = outFV + inPMT*((Math.pow((1 + inNR/(100*inC)),(inNP)) - 1)/(inNR/(100*inC)));
 	}
 	return outFV;
}

function calcPMT(inPV, inFV, inNR, inNP, inC) {
	var outPMT = 0;
 	if (inPV != 0 && inFV != 0) {
 		inPV *= -1;
 	}
	if ((inNR > 0) && (inNP > 0)) {
		outPMT = (inPV - inFV*Math.pow(1+(inNR/(100*inC)),-inNP))/((1 - Math.pow(1+(inNR/(100*inC)),-inNP))/(inNR/(100*inC)));
		if (inFV != 0) {
			outPMT *= -1;
		}		 
	} else if ((inNR == 0) && (inNP > 0)) {
		outPMT = (inPV - inFV)/inNP;
		if (inFV != 0) {
			outPMT *= -1;
		}		 
	} else {
		alert("The number of periods must be greater than 0.");
		outPMT = "";
	}
	return outPMT;
}

function calcNR(inPMT, inPV, inFV, inNP, inC) {
	var	outNR = 0.1; // initial guess
	var	thePV1, thePV2, theDeriv;
	var	theH = 0.00001;
	var	i = 1;
	var	theZeros = 0;
	var lastNR = outNR;
	//alert("PV " + inPV + " PMT " + inPMT + " FV " + inFV + " NP " + inNP);
	if (inNP <= 0) { // should throw an exception
		alert("The Nominal Rate cannot be computed.");
		return outNR = "";
	}
	if (inFV == 0) {
		theZeros++;
	}	
	if (inPMT == 0) {
		theZeros++;
	}	
	if (inPV == 0) {
		theZeros++;
		// inFV *= -1;
	}
	if (theZeros >= 2) { // should throw an exception
		alert("The Nominal Rate cannot be computed.");
		return outNR = "";
	}
	if ((inPV > 0) && (inPMT >= 0) && (inFV >= 0)) {
		alert("The Nominal Rate cannot be computed.");
		return outNR = "";
	}
	if ((inPV == 0) && (inPMT >= 0) && (inFV >= 0)) {
		alert("The Nominal Rate cannot be computed.");
		return outNR = "";
	}
	inPV *= -1;
	//thePV1 = calcPV(inPMT,inFV,outNR*100,inNP,inC);
	//alert("thePV1 " + thePV1 + " " + inPV);
	do {
		thePV1 = calcPV(inPMT,inFV,(outNR*100),inNP,inC) - inPV;
		theDeriv = ((calcPV(inPMT,inFV,((outNR+theH)*100),inNP,inC) - inPV) - thePV1)/theH;
		thePV2 = thePV1;
		//if ((theDeriv == 0) && (Math.abs(thePV2) > 0)) { // should throw an exception
		//	alert("The Nominal Rate cannot be computed. 5");
		//	return outNR = "";
		//}
		lastNR = outNR;
		outNR = outNR - thePV1/theDeriv;
		if (i > 200) { // should throw an exception
			alert("The Nominal Rate cannot be computed.");
			return outNR = "";
		}
		i++;
		if (thePV2 < 0) thePV2 *= -1;
	} while (thePV2 > 0.0001);
	return (lastNR*100); // maybe should change to give the previous rate	
}

function calcNP(inPMT, inPV, inFV, inNR, inC) {
	var	outNP = 5; // initial guess
	var lastNP = outNP;
	var	thePV1, thePV2, theDeriv;
	var	theH = 0.001;
	var	i = 1;
	var	theZeros = 0;
	
	if (inNR <= 0) { // should throw an exception
		alert("The Number of Periods cannot be computed.");
		return outNP = "";
	}
	if (inFV == 0) {
		theZeros++;
	}	
	if (inPMT == 0) {
		theZeros++;
	}	
	if (inPV == 0) {
		theZeros++;
	}
	if (theZeros >= 2) { // should throw an exception
		alert("The Number of Periods cannot be computed.");
		return outNP = "";
	}
	if ((inPV > 0) && (inPMT >= 0) && (inFV >= 0)) {
		alert("The Number of Periodscannot be computed.");
		return outNP = "";
	}
	if ((inPV == 0) && (inPMT >= 0) && (inFV >= 0)) {
		alert("The Number of Periods cannot be computed.");
		return outNP = "";
	}
	inPV *= -1;
	if ((inPV == inFV) && ((inNR/(100*inC))*inFV == inPMT)) { // should throw an exception
		alert("The Number of Periods is not unique.");
		return outNP = "";// outNP can be any number
	}
	do {
		thePV1 = calcPV(inPMT,inFV,inNR,outNP,inC) - inPV;
		theDeriv = ((calcPV(inPMT,inFV,inNR,outNP+theH,inC) - inPV) - thePV1)/theH;
		thePV2 = thePV1;
		//if (theDeriv == 0) { // should throw an exception
		//	return outN;
		//}
		lastNP = outNP;
		outNP = outNP - thePV1/theDeriv;
		if (i > 200) { // should throw an exception
			alert("The Number of Periods cannot be computed.");
			return outNP = "";
		}
		i++;
	} while (Math.abs(thePV2) > 0.0001);
	return lastNP;	
}

function findPV(form) {
 	var theFV = form.FVInput.value;
 	if (!isNumber(theFV)) {
 		return false;
 	}
 	if (theFV == "") theFV = 0;
 	var thePMT = form.PMTInput.value;
 	if (!isNumber(thePMT)) {
 		return false;
 	}
 	if (thePMT == "") thePMT = 0;
 	var theNP = form.NPInput.value;
 	if (!isPositiveNumber(theNP)) {
 		return false;
 	}
 	if (theNP == "") theNP = 0;
 	var theNR = form.NRInput.value;
 	if (!isPositiveNumber(theNR)) {
 		return false;
 	}
 	if (theNR == "") theNR = 0;
 	var theC;
 	var theCompounding = form.CInput.selectedIndex;
 	if (theCompounding == 0) {
 		theC = 1;
 	} else if (theCompounding == 1) {
 		theC = 2;
 	} else if (theCompounding == 2) {
 		theC = 4;
 	} else if (theCompounding == 3) {
 		theC = 12;
 	} else if (theCompounding == 4) {
 		theC = 52;
 	} else if (theCompounding == 5) {
 		theC = 365;
 	}
 	var thePV = calcPV(thePMT, theFV, theNR, theNP, theC);
 	form.PVInput.value = "" + Math.round(-thePV*100)/100;
 	return true;
}
 
function findPMT(form) {
	var thePV = form.PVInput.value;
 	if (!isNumber(thePV)) {
 		return false;
 	}
 	if (thePV == "") thePV = 0;
 	var theFV = form.FVInput.value;
 	if (!isNumber(theFV)) {
 		return false;
 	}
 	if (theFV == "") theFV = 0;	
 	var theNP = form.NPInput.value;
 	if (!isPositiveNumber(theNP)) {
 		return false;
 	}
 	if (theNP == "") theNP = 0;
 	var theNR = form.NRInput.value;
 	if (!isPositiveNumber(theNR)) {
 		return false;
 	}
 	if (theNR == "") theNR = 0;
 	var theC;
 	var theCompounding = form.CInput.selectedIndex;
 	if (theCompounding == 0) {
 		theC = 1;
 	} else if (theCompounding == 1) {
 		theC = 2;
 	} else if (theCompounding == 2) {
 		theC = 4;
 	} else if (theCompounding == 3) {
 		theC = 12;
 	} else if (theCompounding == 4) {
 		theC = 52;
 	} else if (theCompounding == 5) {
 		theC = 365;
 	}
 	var thePMT = calcPMT(thePV, theFV, theNR, theNP, theC);
	if (thePMT == "") {
		form.PMTInput.value = "";
	} else {
		form.PMTInput.value = "" + Math.round(-thePMT*100)/100;
	}
	return true;
}

function findFV(form) {
 	var thePV = form.PVInput.value;
 	if (!isNumber(thePV)) {
 		return false;
 	}
 	if (thePV == "") thePV = 0;
 	var thePMT = form.PMTInput.value;
 	if (!isNumber(thePMT)) {
 		return false;
 	}
 	if (thePMT == "") thePMT = 0;
 	var theNP = form.NPInput.value;
 	if (!isPositiveNumber(theNP)) {
 		return false;
 	}
 	if (theNP == "") theNP = 0;
 	var theNR = form.NRInput.value;
 	if (!isPositiveNumber(theNR)) {
 		return false;
 	}
 	if (theNR == "") theNR = 0;
 	var theC;
 	var theCompounding = form.CInput.selectedIndex;
 	if (theCompounding == 0) {
 		theC = 1;
 	} else if (theCompounding == 1) {
 		theC = 2;
 	} else if (theCompounding == 2) {
 		theC = 4;
 	} else if (theCompounding == 3) {
 		theC = 12;
 	} else if (theCompounding == 4) {
 		theC = 52;
 	} else if (theCompounding == 5) {
 		theC = 365;
 	}
 	var theFV = calcFV(thePMT, thePV, theNR, theNP, theC);
 	form.FVInput.value = "" + Math.round(-theFV*100)/100;
 	return true;
 }
 
 function findNR(form) {
 	var theFV = form.FVInput.value;
 	if (!isNumber(theFV)) {
 		return false;
 	}
 	if (theFV == "") theFV = 0;
 	var thePMT = form.PMTInput.value;
 	if (!isNumber(thePMT)) {
 		return false;
 	}
 	if (thePMT == "") thePMT = 0;
 	var theNP = form.NPInput.value;
 	if (!isPositiveNumber(theNP)) {
 		return false;
 	}
 	if (theNP == "") theNP = 0;
 	var thePV = form.PVInput.value;
 	if (!isNumber(thePV)) {
 		return false;
 	}
 	if (thePV == "") thePV = 0;
 	var theC;
 	var theCompounding = form.CInput.selectedIndex;
 	if (theCompounding == 0) {
 		theC = 1;
 	} else if (theCompounding == 1) {
 		theC = 2;
 	} else if (theCompounding == 2) {
 		theC = 4;
 	} else if (theCompounding == 3) {
 		theC = 12;
 	} else if (theCompounding == 4) {
 		theC = 52;
 	} else if (theCompounding == 5) {
 		theC = 365;
 	}
 	var theNR = calcNR(thePMT, thePV, theFV, theNP, theC);
 	if (theNR == "") {
		form.NRInput.value = "";
	} else {
		form.NRInput.value = "" + Math.round(theNR*100)/100;
	}
 	return true;
}

function findNP(form) {
 	var theFV = form.FVInput.value;
 	if (!isNumber(theFV)) {
 		return false;
 	}
 	if (theFV == "") theFV = 0;
 	var thePMT = form.PMTInput.value;
 	if (!isNumber(thePMT)) {
 		return false;
 	}
 	if (thePMT == "") thePMT = 0;
 	var theNR = form.NRInput.value;
 	if (!isPositiveNumber(theNR)) {
 		return false;
 	}
 	if (theNR == "") theNR = 0;
 	var thePV = form.PVInput.value;
 	if (!isNumber(thePV)) {
 		return false;
 	}
 	if (thePV == "") thePV = 0;
 	var theC;
 	var theCompounding = form.CInput.selectedIndex;
 	if (theCompounding == 0) {
 		theC = 1;
 	} else if (theCompounding == 1) {
 		theC = 2;
 	} else if (theCompounding == 2) {
 		theC = 4;
 	} else if (theCompounding == 3) {
 		theC = 12;
 	} else if (theCompounding == 4) {
 		theC = 52;
 	} else if (theCompounding == 5) {
 		theC = 365;
 	}
 	var theNP = calcNP(thePMT, thePV, theFV, theNR, theC);
 	if (theNP == "") {
		form.NPInput.value = "";
	} else {
		form.NPInput.value = "" + Math.round(theNP*100)/100;
	}
 	return true;
}
 
 function isPositiveNumber(inputStr) {
 	var decFlag = false;
 	if (inputStr == ".") {
 		alert("Please make sure that only numbers are input.");
 		return false;
 	}
 	for (var i = 0; i < inputStr.length; i++) {
 		var oneChar = inputStr.substring(i,i+1);
 		if (((oneChar >= "0") && (oneChar <= "9")) || ((oneChar == ".") && (decFlag == false))) {
 		
 		} else {
 			alert("Please make sure that only numbers are input.");
 			return false;
 		}
 		if (oneChar == ".") {
	 		decFlag = true;
	 	}
 	}
	return true;
 }
 
 function isNumber(inputStr) {
 	var decFlag = false;
 	if (inputStr == ".") {
 		alert("Please make sure that only numbers are input.");
 		return false;
 	}
 	for (var i = 0; i < inputStr.length; i++) {
 		var oneChar = inputStr.substring(i,i+1);
 		if ((i == 0) && (inputStr.length > 1)) {
	 		if (((oneChar >= "0") && (oneChar <= "9")) || ((oneChar == ".") && (decFlag == false)) || (oneChar == "-")) {
	 		
	 		} else {
	 			alert("Please make sure that only numbers are input.");
	 			return false;
	 		}
	 	} else {
	 		if (((oneChar >= "0") && (oneChar <= "9")) || ((oneChar == ".") && (decFlag == false))) {
	 		
	 		} else {
	 			alert("Please make sure that only numbers are input.");
	 			return false;
	 		}
	 	}
	 	if (oneChar == ".") {
	 		decFlag = true;
	 	}	
 	}
	return true;
 }
 
function launchTVMCalc() {
    window.open("TVMCalcWindow.html","Win2","menubar,resizable,height=205,width=315");
}

function scriptPV(inPV,inPMT,inFV,inNR,inNP,inCP) {
	document.TVMCalc.PVInput.value = inPV;
	document.TVMCalc.PMTInput.value = inPMT;
	document.TVMCalc.FVInput.value = inFV;
	document.TVMCalc.NRInput.value = inNR;
	document.TVMCalc.NPInput.value = inNP;
	document.TVMCalc.CInput.selectedIndex = inCP;
	findPV(document.TVMCalc);	
}

function scriptFV(inPV,inPMT,inFV,inNR,inNP,inCP) {
	document.TVMCalc.PVInput.value = inPV;
	document.TVMCalc.PMTInput.value = inPMT;
	document.TVMCalc.FVInput.value = inFV;
	document.TVMCalc.NRInput.value = inNR;
	document.TVMCalc.NPInput.value = inNP;
	document.TVMCalc.CInput.selectedIndex = inCP;
	findFV(document.TVMCalc);	
}

var gPV = 0;
var gPMT = 0;
var gFV = 0;
var gNR = 10;
var gNP = 1;
var gCP = 1;
var gPR = "PV Button";
var gCPString = "Annually";
var gCPStringA = "Annual";
var gCPStringB = "year";
var gYears = 1;
var gType = 0; // PV =1, FV =2, PVA =3, FVA =4, NR =5, NP =6, if 0 => no problem
var gAnnualOnly = true;

function myAlert(thePV,thePMT,theFV,theNR,theNP,theCP,thePR) { 
  var ETF = "\nEnter the Following:\n"; 
  var PV = "PV= "; 
  var PMT = "; PMT = "; 
  var FV = "; FV = "; 
  var NR = "; Rate = "; 
  var NP = "\nPeriods = "; 
  var PR = "\n\nThen Press the "; 
  var CP = "; Compounding = ";
  if (gType == 0) {
     alert("Please click the New Problem button.");
  } else {      
     alert(ETF+PV+thePV+PMT+thePMT+FV+theFV+NR+theNR+NP+theNP+CP+theCP+PR+thePR); 
  } 
}

function newProblem(form) {
  gType = Math.round(Math.random()*3)+1;
  if (form.AnnualBox.checked) {
    gAnnualOnly = true;
  } else {
        gAnnualOnly = false;
  }
   if (gType == 1) {
     randomPVProblem(form);
  } else if (gType == 2) {
     randomFVProblem(form);
  } else if (gType == 3) {
     randomPVAProblem(form);
  } else if (gType == 4) {
     randomFVAProblem(form);
  }  
}

function doProblem() {
  if (gType == 0) {
     alert("Please click the New Problem button.");
  } else if (gType == 1) {
     scriptPV(gPV,gPMT,gFV,gNR,gNP,gCP);
  } else if (gType == 2) {
     scriptFV(gPV,gPMT,gFV,gNR,gNP,gCP);
  } else if (gType == 3) {
     scriptPV(gPV,gPMT,gFV,gNR,gNP,gCP);
  } else if (gType == 4) {
     scriptFV(gPV,gPMT,gFV,gNR,gNP,gCP);
  }
}

function randomPVProblem(form) {
  gFV = Math.round(Math.random()*1000); 
  gNR = Math.round(Math.random()*2000)/100; 
  gYears = Math.round(Math.random()*25);
  if (gAnnualOnly) {
        gCP = 0;
  } else {
    gCP = Math.round(Math.random()*5);
  }
  if (gCP == 0) {
     gCPString = "Annually";
     gCPStringA = "Annual";
     gCPStringB = "year";
     gNP = gYears;
  } else if (gCP == 1) {
     gCPString = "Semiannually";
     gCPStringA = "Semiannual";
     gCPStringB = "six months";
     gNP = gYears*2;
  } else if (gCP == 2) {
     gCPString = "Quarterly";
     gCPStringA = "Quarterly";
     gCPStringB = "quarter";
     gNP = gYears*4;
  } else if (gCP == 3) {
     gCPString = "Monthly";
     gCPStringA = "Monthly";
     gCPStringB = "month";
     gNP = gYears*12;
  } else if (gCP == 4) {
     gCPString = "Weekly";
     gCPStringA = "Weekly";
     gCPStringB = "week";
     gNP = gYears*52;
  } else {
     gCPString = "Daily";
     gCPStringA = "Daily";
     gCPStringB = "day";
     gNP = gYears*365;
  } 
  gPMT = 0; 
  gPV = 0; 
  gPR = "PV Button";
  form.RandomProb.value="Find the Present Value of $" + gFV +
      " to be received " + gYears + " year(s) from now if the interest rate is " +
      gNR + "% compounded " + gCPString + ".";
 }
 
 function randomPVAProblem(form) {
  gPMT = Math.round(Math.random()*1000); 
  gNR = Math.round(Math.random()*2000)/100; 
  gYears = Math.round(Math.random()*25); 
  if (gAnnualOnly) {
        gCP = 0;
  } else {
    gCP = Math.round(Math.random()*5);
  }
  if (gCP == 0) {
     gCPString = "Annually";
     gCPStringA = "Annual";
     gCPStringB = "year";
     gNP = gYears;
  } else if (gCP == 1) {
     gCPString = "Semiannually";
     gCPStringA = "Semiannual";
     gCPStringB = "six months";
     gNP = gYears*2;
  } else if (gCP == 2) {
     gCPString = "Quarterly";
     gCPStringA = "Quarterly";
     gCPStringB = "quarter";
     gNP = gYears*4;
  } else if (gCP == 3) {
     gCPString = "Monthly";
     gCPStringA = "Monthly";
     gCPStringB = "month";
     gNP = gYears*12;
  } else if (gCP == 4) {
     gCPString = "Weekly";
     gCPStringA = "Weekly";
     gCPStringB = "week";
     gNP = gYears*52;
  } else {
     gCPString = "Daily";
     gCPStringA = "Daily";
     gCPStringB = "day";
     gNP = gYears*365;
  }  
  gFV = 0; 
  gPV = 0; 
  gPR = "PV Button";
  form.RandomProb.value="Find the Present Value of a " + gYears + " year annuity of $" + gPMT +
      " per " + gCPStringB + " if the interest rate is " +
      gNR + "% compounded " + gCPString + ".";
 }
 
function randomFVProblem(form) {
  gPV = Math.round(Math.random()*1000); 
  gNR = Math.round(Math.random()*2000)/100; 
  gYears = Math.round(Math.random()*25); 
  if (gAnnualOnly) {
        gCP = 0;
  } else {
    gCP = Math.round(Math.random()*5);
  }
  if (gCP == 0) {
     gCPString = "Annually";
     gCPStringA = "Annual";
     gCPStringB = "year";
     gNP = gYears;
  } else if (gCP == 1) {
     gCPString = "Semiannually";
     gCPStringA = "Semiannual";
     gCPStringB = "six months";
     gNP = gYears*2;
  } else if (gCP == 2) {
     gCPString = "Quarterly";
     gCPStringA = "Quarterly";
     gCPStringB = "quarter";
     gNP = gYears*4;
  } else if (gCP == 3) {
     gCPString = "Monthly";
     gCPStringA = "Monthly";
     gCPStringB = "month";
     gNP = gYears*12;
  } else if (gCP == 4) {
     gCPString = "Weekly";
     gCPStringA = "Weekly";
     gCPStringB = "week";
     gNP = gYears*52;
  } else {
     gCPString = "Daily";
     gCPStringA = "Daily";
     gCPStringB = "day";
     gNP = gYears*365;
  } 
  gPMT = 0; 
  gFV = 0; 
  gPR = "FV Button";
  form.RandomProb.value="Find the Future Value " + gYears + " year(s) from now of an investment of $"
      + gPV + " today if the interest rate is " +
      gNR + "% compounded " + gCPString + ".";
 }
 
function randomFVAProblem(form) {
  gPMT = Math.round(Math.random()*1000); 
  gNR = Math.round(Math.random()*2000)/100; 
  gYears = Math.round(Math.random()*25); 
  if (gAnnualOnly) {
        gCP = 0;
  } else {
    gCP = Math.round(Math.random()*5);
  }
  if (gCP == 0) {
     gCPString = "Annually";
     gCPStringA = "Annual";
     gCPStringB = "year";
     gNP = gYears;
  } else if (gCP == 1) {
     gCPString = "Semiannually";
     gCPStringA = "Semiannual";
     gCPStringB = "six months";
     gNP = gYears*2;
  } else if (gCP == 2) {
     gCPString = "Quarterly";
     gCPStringA = "Quarterly";
     gCPStringB = "quarter";
     gNP = gYears*4;
  } else if (gCP == 3) {
     gCPString = "Monthly";
     gCPStringA = "Monthly";
     gCPStringB = "month";
     gNP = gYears*12;
  } else if (gCP == 4) {
     gCPString = "Weekly";
     gCPStringA = "Weekly";
     gCPStringB = "week";
     gNP = gYears*52;
  } else {
     gCPString = "Daily";
     gCPStringA = "Daily";
     gCPStringB = "day";
     gNP = gYears*365;
  }  
  gFV = 0; 
  gPV = 0; 
  gPR = "FV Button";
  form.RandomProb.value="Find the Future Value of a " + gYears + " year annuity of $" + gPMT +
      " per " + gCPStringB + " if the interest rate is " +
      gNR + "% compounded " + gCPString + ".";
 }


