
var F, LIMIT, CATCHUPLIMIT, TOTALCONTLIMIT, POLICEORFIREADJ, GENERALADJ, APPLYCATCHUPMIN, APPLYCATCHUPMAX;
// These "CONSTANTS" are loaded when chgYear is called from PreparePage()
function chgYear(chgToYear) {
	// if you change the default year (by changing the selected year in the <option> tag), then also change:
	//      the 2 hard-coded cont. limits in the html
	//      the default years in the over50 options
	//      the show/hide status of idMidYearContChange
	 if (chgToYear=="2009") {
		 //Updated per Diane Kaiser PR17687 - Edgar Correa 1/21/2009
		LIMIT = 16500;
		CATCHUPLIMIT = 5500;
		TOTALCONTLIMIT = 49000;
		POLICEORFIREADJ = 0.9235; // no average this may change
		GENERALADJ = 0.9377; // no average this may change
	} 
	 else if (chgToYear=="2008") {
		 //Updated per Diane Kaiser PR13335 - Edgar Correa 1/23/2008
		LIMIT = 15500;
		CATCHUPLIMIT = 5000;
		TOTALCONTLIMIT = 45000;
		POLICEORFIREADJ = 0.9235; // no average this may change
		GENERALADJ = 0.9377; // no average this may change
	} 
	else {
		alert("Unexpected Error.. values not set for requested year.");
		return false;
	}
	APPLYCATCHUPMIN = LIMIT;
	APPLYCATCHUPMAX = (LIMIT*2)+(CATCHUPLIMIT*3);

	//NOTE: specifying document.all allows this to work in IE and NS (thanks to NS_patches.js)
	//document.all.idMidYearContChange.className = (chgToYear=="2004")?"Show":"Hide";
	document.all.idMidYearContChange.className = (chgToYear=="2009")?"Show":"Hide";
	F.Over50.options[0].text=(chgToYear-49)+" or after";
	F.Over50.options[1].text=(chgToYear-50)+" or before";
	Calculate();
}


function ServiceQuestionChange(objRef) {
	if (objRef.selectedIndex) {
		document.all.idRepurchase.style.display="";
	} else {
		document.all.idRepurchase.style.display="none";
		F.AmtRepurchased.value = "0";
		Calculate();
	}
}

function chgPlan(plantype,show) {
	var aFields = ["Cont401","ERCont401","GainSharing401"];
	var Msg = "You have entered contribution values for 401(k).\nDo you want to set these to zero?";
	if (plantype == "457") {
		aFields = ["Cont457"];
		Msg = "You have entered a contribution value for 457.\nDo you want to set this to zero?";
	} else if (plantype == "403b") {
		aFields = ["Cont403","ERCont403"];
		Msg = "You have entered contribution values for 403(b).\nDo you want to set these to zero?";
	}
	if (HasPositiveValues(aFields) && !show) {
		if (confirm(Msg)) {
			SetToZero(aFields,false);
			Calculate();
		} else {
			F["chk"+plantype].checked=true;
			return false;
		}
	}
	document.all["id"+plantype].className = (show)?"Show":"Hide";
	if (plantype == "401k" || plantype == "403b") {
		RequireNumber40x();
		document.all.id401or403.className = (F.chk403b.checked || F.chk401k.checked)?"Show":"Hide";
	}
}

function Calculate() {
	// Stop if no Gross Compensation was entered
	RequireNumber(F.GrossComp,150000);
	if (HasInvalidValues(["GrossComp"])) {
		alert("A whole dollar amount is required for Gross Compensation. No characters allowed.");
		return false;
	}
	// Turn field red and stop if no Service Repurchased was entered (0 is entered by default when page loads)
	//if (F.ServiceRepurchase.selectedIndex && (isNaN(v("AmtRepurchased")))) {
	RequireNumber(F.AmtRepurchased);
	if (HasInvalidValues(["AmtRepurchased"])) {
		alert("A whole dollar amount is required for the Amount of Service Repurchased.");
		return false;
	}

	// Enter Zeros if any Contribution Fields are left blank
	// Commented out because blank means zero thanks to the v() function
	//SetToZero(["Cont401","ERCont401","GainSharing401","Cont457","Cont403","ERCont403"],true);

	// Turn fields red and stop if Contribution values are not zero or positive numbers
	RequireNumber(F.Cont401);
	RequireNumber(F.Cont457);
	RequireNumber(F.Cont403);
	RequireNumber(F.ERCont401);
	RequireNumber(F.ERCont403);
	RequireNumber(F.GainSharing401);
	if (HasInvalidValues(["Cont401","ERCont401","GainSharing401","Cont457","Cont403","ERCont403"])) {
		alert("All of the contribution fields must be 0 or a positive number. No characters allowed.");
		return false;
	}

	// Calculate limits
	F.CatchUp.value = Math.min( v("GrossComp")-( v("Cont401")+v("Cont457")+v("Cont403") ) , CATCHUPLIMIT );
	F.CatchUp.value = DollarFormat(Math.max(F.CatchUp.value,0));
	var ApplyCatchup = (F.Over50.selectedIndex && v("GrossComp") > APPLYCATCHUPMIN);
	if (ApplyCatchup) F.EDLimit40x.value = F.EDLimit457.value = DollarFormat(LIMIT +v("CatchUp"));
	else F.EDLimit40x.value = F.EDLimit457.value = DollarFormat(LIMIT);
	
	if (ApplyCatchup && v("GrossComp") < APPLYCATCHUPMAX) {
		F.CatchupLimit.value = DollarFormat(v("GrossComp")-CATCHUPLIMIT);
		document.all.idCatchupMsg.className = "Show";
	} else {
		//Don't need to recalculate F.CatchupLimit.value here because it's not going to be displayed anyway
		document.all.idCatchupMsg.className = "Hide";	
	}
	
	// Now apply the limits
	if (F.PoliceOrFire.selectedIndex)
		var AdjGrossComp = (v("GrossComp")*POLICEORFIREADJ)-v("AmtRepurchased");
	else
		var AdjGrossComp = (v("GrossComp")*GENERALADJ)-v("AmtRepurchased");
	
	F.EDRefundDue401.value = DollarFormat(Math.max(v("Cont401")-v("EDLimit40x"),0));
	F.EECont401.value = DollarFormat(v("Cont401")-v("EDRefundDue401"));
	F.EDRefundDue457.value = DollarFormat(Math.max(v("Cont457")-v("EDLimit457"),0));
	F.EDRefundDue403.value = DollarFormat(Math.max(v("EECont401")+v("Cont403")-v("EDLimit40x"),0));
	F.EECont403.value = DollarFormat(v("Cont403")-v("EDRefundDue403"));
	if (ApplyCatchup)
		F.AALimit401.value = F.AALimit403.value = DollarFormat(Math.min(AdjGrossComp,TOTALCONTLIMIT)+v("CatchUp"));
	else
		F.AALimit401.value = F.AALimit403.value = DollarFormat(Math.min(AdjGrossComp,TOTALCONTLIMIT));
	
	var TotalAA401 = v("EECont401") + v("ERCont401") + v("GainSharing401");
	F.AARefundDue401.value = DollarFormat(Math.max(TotalAA401-v("AALimit401"),0));
	var TotalAA403 = v("EECont403") + v("ERCont403");
	F.AARefundDue403.value = DollarFormat(Math.max(TotalAA403-v("AALimit403"),0));

	// refresh red backgrounds that may have changed when calculating
	RequireNumber40x();
	RequireNumber(F.Cont457,v('EDLimit457'));
	RequireNumber(F.EDRefundDue401,0);
	RequireNumber(F.EDRefundDue457,0);
	RequireNumber(F.EDRefundDue403,0);
	RequireNumber(F.AARefundDue401,0);
	RequireNumber(F.AARefundDue403,0);
}

function v(formfield) { // "v" for "Value of"
	var FieldVal = F[formfield].value;
	if (Trim(FieldVal)=="") return 0;
	else return parseFloat(RemoveDollar(FieldVal)); // will return "NaN" if there are invalid characters
}

function RequireNumber(objRef,MaxVal) {
	var val = RemoveDollar(objRef.value), TooBig = (MaxVal!=null && val > MaxVal);
	objRef.parentNode.parentNode.bgColor=(isNaN(val) || val < 0 || TooBig)?'#ff3333':'#ffffff';
}

function RequireNumber40x() {
	//if the plan type is hidden then don't enforce max value.
	RequireNumber(F.Cont401,(document.all.id401k.className=="Hide")?null:v("EDLimit40x")-v("Cont403"));
	RequireNumber(F.Cont403,(document.all.id403b.className=="Hide")?null:v("EDLimit40x")-v("Cont401"));
}

function Trim(val) {
	return(val.replace(/^\s*|\s*$/g, ""));
}

function RemoveChar(str,chr) {
	return(str.split(chr).join(""));
}

function RemoveDollar(str) {
	return RemoveChar( RemoveChar( RemoveChar( str ," ") ,"$") ,",");
}

function DollarFormat(val) {
	if (val==0 || val=="") return "$0";
	if (isNaN(val)) return "ERR";
	val = Math.round(val*100)/100; //fix floating point errors
	val = val+""; //change datatype to string
	//add commas to whole dollar amount
	var aVal = val.split("."), amt=aVal[0]+"", l=amt.length;
	if (l > 6) {
		amt = amt.substr(0,l-6) + "," + amt.substr(l-6,3) + "," + amt.substr(l-3);
	} else if (l > 3) {
		amt = amt.substr(0,l-3) + "," + amt.substr(l-3);
	}
	if (aVal.length > 1) { //put back the pennies
		amt+="."+aVal[1];
		if (amt.indexOf(".") == amt.length-2) amt += "0"; // Turn "$9.2" into "$9.20"
	}
	return "$" + amt;
}

function HasPositiveValues(aFields) {
	for (var x=0; x<aFields.length; x++) {
		if (RemoveDollar(F[aFields[x]].value) > 0) return true;
	}
	return false;
}

function SetToZero(aFields,OnlyIfBlank) {
	for (var x=0; x<aFields.length; x++) {
		if (!OnlyIfBlank || Trim(F[aFields[x]].value)=="") F[aFields[x]].value=0;
	}
}

function HasInvalidValues(aFields) {
	var testval;
	for (var x=0; x<aFields.length; x++) {
		testval = RemoveDollar(F[aFields[x]].value);
		if (isNaN(testval) || testval<0) return true;
	}
	return false;
}

function PreparePage() {
	F = document.inputform;
	chgPlan("401k",F.chk401k.checked);
	chgPlan("457",F.chk457.checked);
	chgPlan("403b",F.chk403b.checked);
	chgYear(F.Year.value);
	ServiceQuestionChange(F.ServiceRepurchase);
}
