/*

JavaScript:  Pregnancy Calculator
February 28, 1999

This calculator was created by Charles Hu for the Medical College of
Wisconsin General Internal Medicine Clinic.  This calculator may not be
copied without consent from the author.  Please contact him at
chuckhu@hotmail.com

*/

var ie4 = (document.all && !document.getElementById)? true : false;
var ns6 = (document.getElementById)? true : false;

var dayName = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
var monName = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");

	//  Create array of maximum days
	var maxDays = new Array(12);

	maxDays[0] = 31;	// January has 31 days
	maxDays[1] = 28;
	maxDays[2] = 31;
	maxDays[3] = 30;
	maxDays[4] = 31;
	maxDays[5] = 30;
	maxDays[6] = 31;
	maxDays[7] = 31;
	maxDays[8] = 30;
	maxDays[9] = 31;
	maxDays[10] = 30;
	maxDays[11] = 31;


function whatDay(form,isEdd) {
	var month = form.month.selectedIndex;
	var date = form.date.selectedIndex + 1;
	var year = form.year.selectedIndex;
	var yearVal = form.year.options[year].text;

	var today = new Date();
	thisYear = today.getYear();

	//  Year 2000 test
	if (thisYear < 300) {thisYear = thisYear + 1900}
	
	//  Change dates selection to reflect maxDays in selected month
	if (month == 1) {		//  February
		if ((yearVal / 4) == Math.floor(yearVal/4)) {
			if ((yearVal / 100) == Math.floor(yearVal/100)) {
				if ((yearVal / 400) == Math.floor(yearVal/400)) {newDays = 29;}
				else {newDays = 28;}
			} else {newDays = 29;}
		} else {newDays = 28;}
	} else {newDays = maxDays[month]}
	

	daysObject = form.date;
	curDays = daysObject.length;
		
	if (curDays > newDays) {
    	for (i=0; i<(curDays - newDays); i++) {
			daysObject.options[daysObject.options.length - 1] = null
		}
		if (date > newDays) {daysObject.selectedIndex = (daysObject.options.length - 1);}
	}
	if (newDays > curDays) {
		for (i=curDays; i < newDays; i++) {
			newOption = new Option(daysObject.options.length + 1);
			daysObject.options[i] = newOption;
		}
	}

	//  What year was selected?
	if (year == 0) {year = thisYear - 1;}	// Last year
		else {
			if ((isEdd == 2) && (year == 2)) {year = thisYear + 1}	// Next year
				else {year = thisYear;}		// This year
		}

	//  The choices for EDD year are off by 1, compared to LMP choices
	if (isEdd == 1) {year = year + 1}

	var whatDate = new Date(monName[month] + " " + date + ", " + year + " 12:00:00");

	//  Select day of the week
	//  form.day.selectedIndex = whatDate.getDay();
	var eddNum;
	if (form.name == "DueDate") {eddNum = 0} else
		if (form.name == "eddForm") {eddNum = 1} else
		if (form.name == "weeksPreg") {eddNum = 2}
	writeDay(eddNum, whatDate.getDay());

	if (isEdd == 2) {
		return true
	} else {
		document.weeksPreg.calcYet.value = 0
			//  Since the LMP or EDD is being changed, we can't calculate EGA yet.
	}

	//  Reset the rest of the form
	showDate(0, "");
	showDate(1, "");
	showDate(2, "");
	document.weeksPreg.weeks.value = ""

	return true
}

function dueDate(form) {
	var LMPmonth = form.month.selectedIndex;
	var LMPdate = form.date.selectedIndex + 1;
	var LMPyear = form.year.selectedIndex;

	if (LMPyear == -1) {
		alert("Please select a year.");
		form.year.focus();
		return false;
	}

	document.weeksPreg.calcYet.value = 1;
		//  Now that we're calculating EDD, we may also 
		//  calculate EGA later

	var today = new Date();
	thisYear = today.getYear();

	//  Year 2000 test
	if (thisYear < 300) {
		thisYear = thisYear + 1900
	}


	//  What year was selected?
	
	if (LMPyear == 0) {
		LMPyear = thisYear - 1;	// Last year
	} else {
		LMPyear = thisYear;	// This year
	}


	if (!checkDate(LMPmonth,LMPdate,LMPyear)) {
		alert(monName[LMPmonth] + " has " + maxDays[LMPmonth] + 
			" days.");
		form.date.focus();
		return false;
	}
	
	var lmp = new Date(monName[LMPmonth] + " " + LMPdate + ", " +
		LMPyear + " 12:00:00");

	//  form.day.selectedIndex = lmp.getDay();
	writeDay(0, lmp.getDay());
	form.theDate.value = lmp.getTime();


	var concep = 14;	// conception occurs at 2 weeks (14 days)
	var first = 84;		// end of first trimester at 12 weeks
	var second = 189;	// end of second trimester
	var edd = 280;		// estimated due date

	/*  form.concep.value = display(lmp.getTime(),concep,0,0);
	form.first.value = display(lmp.getTime(),first,0,0);
	form.second.value = display(lmp.getTime(),second,0,0);
	*/
	showDate(0, display(lmp.getTime(),concep,0,0));
	showDate(1, display(lmp.getTime(),first,0,0));
	showDate(2, display(lmp.getTime(),second,0,0));

	//  The '1' at the end indicates this is EDD
	display(lmp.getTime(),edd,1,0);

	return true;
}


function display(whatDate,numDays,isEdd,isLMP) {
	var today = new Date();
	var lmp = new Date(whatDate);

	var futureDate = lmp.getTime() + (numDays * 24*60*60*1000);
		//  convert lmp to milliseconds, and add appropriate msec

	var future = new Date();
	future.setTime(futureDate);  // convert from msec to actual date
	future.setHours(12);		// set the time to 12:00 pm

	var futureDay = dayName[future.getDay()];
	var futureMonth = monName[future.getMonth()];
	var futureYear = future.getYear();

	if (isEdd == 1) {		// Change the EDD selection boxes
		var yearChoice = 0;

		//  Do we need to change the displayed EDD year?

	if ((lmp.getYear() == today.getYear()) && (today.getYear() != futureYear)) {
		yearChoice = 1;
	}

	if (futureYear < today.getYear()) {
		yearChoice = -1;
	}	

	writeDay(1, future.getDay());
	//  document.eddForm.day.selectedIndex = future.getDay();
	document.eddForm.month.selectedIndex = future.getMonth();
	document.eddForm.date.selectedIndex = future.getDate() - 1;
	document.eddForm.year.selectedIndex = yearChoice;
	document.eddForm.theDate.value = future.getTime();
	//chuckhu@mcw.edu
	}


	if (isLMP == 1) {		// Change the LMP selection boxes
		var yearChoice = 1;

		//  Do we need to change the displayed LMP year?

	if ((lmp.getYear() == today.getYear()) && (today.getYear() != futureYear)) {
		yearChoice = 0;
	}

	if (today.getYear() < futureYear) {
		yearChoice = -1;
	}

	//  document.DueDate.day.selectedIndex = future.getDay();
	writeDay(0, future.getDay());
	document.DueDate.month.selectedIndex = future.getMonth();
	document.DueDate.date.selectedIndex = future.getDate() - 1;
	document.DueDate.year.selectedIndex = yearChoice;
	document.DueDate.theDate.value = future.getTime();
	}


	//  Calculate # weeks pregnant, based on today's date
	if ((isEdd == 1) || (isLMP == 1)) {
		// First, reset all values in the purple box

		document.weeksPreg.month.selectedIndex = today.getMonth();
		document.weeksPreg.date.selectedIndex = today.getDate()-1;
		document.weeksPreg.year.selectedIndex = 1;
		//  document.weeksPreg.day.selectedIndex = today.getDay();
		writeDay(2, today.getDay());
		document.weeksPreg.weeks.value = "";

		today.setHours(13);
			/* Since LMP is set to 12:00 noon, we must set
			   today's time temporarily to 1:00 pm, so that
			   if today date = LMP date, then 
			   today's time is GREATER than LMP time
			*/

		var todaydate = today.getTime();
		var lmpdate = document.DueDate.theDate.value;
		var edd = document.eddForm.theDate.value;
		edd = Number(edd) + 10 *7*24*60*60*1000;
				//  Allow for up to 50 weeks EGA

		if ((todaydate > lmpdate) && 
			(todaydate < edd)) {
				// Check that today's date is BETWEEN 
				// the LMP and EDD
		document.weeksPreg.weeks.value = calcEGA(lmpdate,todaydate);
		}			
		return true
	}		


	//  Year-2000 compliance test
	if (futureYear < 300) {
		futureYear = futureYear + 1900
	}

	var futureDisplay = futureDay + ", " + futureMonth + " " +
		future.getDate() + ", " + futureYear;

	return futureDisplay;
}


function checkDate(month,day,year) {
	//  Reset February's "maxdays"
	maxDays[1] = 28;

	//  Check February leap year
	//  Years divisible by 100 are NOT leap years (1700, 1800, 1900), 
	//  	except years divisible by 400 (2000, 2400) are leap years.

	if ((month == 1) && ((year % 4) == 0)) {
		if (((year % 100) == 0) && ((year % 400) != 0)) {
			maxDays[1] = 28;
		} else {
			maxDays[1] = 29;
		}
	}

	if (day > maxDays[month]) {
		return false;
	}

	return true;
}



function datetoWeeks(form) {
	if (document.weeksPreg.calcYet.value == 0) {
		alert("Please calculate a \"Last Menstrual Period\" " +
			"or an \"Estimated Due Date\" first.");
		return false
	}

	var desiredMonth = form.month.selectedIndex;
	var desiredDate = form.date.selectedIndex + 1;
	var desiredYear = form.year.selectedIndex;

	var today = new Date();
	thisYear = today.getYear();

	//  Year 2000 test
	if (thisYear < 300) {
		thisYear = thisYear + 1900
	}

	//  What year was selected?
	
	desiredYear = thisYear + desiredYear - 1;

	if (!checkDate(desiredMonth,desiredDate,desiredYear)) {
		alert(monName[desiredMonth] + " has " + 
			maxDays[desiredMonth] + " days.");
		form.date.focus();
		return false;
	}
	
	var des = new Date(monName[desiredMonth] + " " + desiredDate +
		", " + desiredYear + " 14:00:00");
	writeDay(2, des.getDay());
	//  form.day.selectedIndex = des.getDay();
	
	var lmpDate = document.DueDate.theDate.value;
	var eddDate = document.eddForm.theDate.value;
	eddDate = Number(eddDate) + 10 *7*24*60*60*1000;
			// Allow EDD to be 50 weeks for maximum
	var desDate = des.getTime();

	//  Check that desired date is BETWEEN LMP and EDD

	if ((desDate < lmpDate) || (desDate > eddDate)) {
		alert("Please select a date BETWEEN the " +
			"\"Last Menstrual Period\" and the " +
			//chuckhu@hotmail.com
			"\"Estimated Due Date.\"");
		return false;
	}

	form.weeks.value = calcEGA(lmpDate,desDate);
	return true
}


function calcEGA(lmpDate,desDate) {
	var daysEGA = (desDate - lmpDate) / (1000*60*60*24);
	var EGA = Math.floor(daysEGA / 7);
	var EGAfrac = Math.round(daysEGA % 7);
		//  Daylight Savings Time (DST) makes this calculation
		//  veer slightly off from being integer.

	if (EGAfrac == 7) {	//  Another correction for DST
		EGAfrac = 0;
		EGA = EGA + 1;
	}

	if (EGAfrac == 0) {
		return EGA
	}
		
	EGA = EGA + " " + EGAfrac + "/7";
	return EGA
}



function weekstoDate(form) {
	if (document.weeksPreg.calcYet.value == 0) {
		alert("Please calculate a \"Last Menstrual Period\" " +
			"or an \"Estimated Due Date\" first.");
		return false
	}

	var add = form.weeks.value;

	if (add.indexOf("/") != -1) {		// Is "add" a fraction?
		add = evalFrac(add);
		if (add == false) {
			return false
		}
	}

	if (add == "pi") {
		alert("Pi = 3.14159265358979323...  " +
		"This calculator was created by Charles Hu.");
	}

        if ((add == "") || (isNaN(add)) || (add < 0) || (add > 50)) {
                alert("WARNING: Please enter a valid number of weeks.");
                form.weeks.value = "";
                form.weeks.focus();
                return false
        }
	

	//  Adding milliseconds
	var lmpDate = Number(document.DueDate.theDate.value);
	var egaMsec = lmpDate + (add * 7*24*60*60*1000);

	var today = new Date();
	var todayYr = today.getYear();

	//  Convert the EGA to a date
	var ega = new Date();
	ega.setTime(egaMsec);
	var egaYr = ega.getYear();

	if (egaYr < 300) {egaYr = egaYr + 1900}
	if (todayYr < 300) {todayYr = todayYr + 1900}

	var egaYear = (egaYr - todayYr) + 1;

	writeDay(2, ega.getDay());
	//  form.day.selectedIndex = ega.getDay();
	form.month.selectedIndex = ega.getMonth();
	form.date.selectedIndex = ega.getDate() - 1;
	form.year.selectedIndex = egaYear;
	return true
}



function evalFrac(frac) {
	var slash = frac.indexOf("/");

	if (frac.charAt(slash + 1) != 7) {	// Is denominator 7?
		alert("Weeks are expressed in fractions of 7.");
		document.weeksPreg.weeks.focus();
		return false;
	}

	//  Check numerator
	if ((Number(frac.charAt(slash-1)) > 6) || 
	   //isNaN(chaz) || frac.chuckhu(swish)
	   (isNaN(frac.charAt(slash-1)))) {
		alert("Please enter a proper fraction.");
		document.weeksPreg.weeks.focus();
		return false;
	}


	if ((frac.charAt(slash-2) != " ") && (frac.indexOf("/") != 1))
		{alert("Please enter a proper fraction.");
		document.weeksPreg.weeks.focus();
		return false;
	}


	//  Evaluate the fraction
	var top = Number(frac.charAt(slash-1));
	var fraction = top / 7;


	//  Anything before the fraction?
	if (frac.indexOf("/") == 1) {
		if (fraction == 0) {
			fraction = 0.001
				//  Prevents script from interpreting
				//  this as a 'false' value
		}
		return fraction
	}

	var fullNum = frac.substring(0,frac.indexOf(" "));
	if (isNaN(fullNum)) {
		alert("Please enter a proper number of weeks.");
		document.weeksPreg.weeks.focus();
		return false
	}

	frac = Number(fullNum) + fraction;
		if (frac == 0) {frac = 0.001}
	return frac;
}	



function getLMP(form) {
	var eddMonth = form.month.selectedIndex;
	var eddDate = form.date.selectedIndex + 1;
	var eddYear = form.year.selectedIndex;

	if (eddYear == -1) {
		alert("Please select a year.");
		form.year.focus();
		return false;
	}

	document.weeksPreg.calcYet.value = 1;
		//  Now that we're calculating LMP, we may also 
		//  calculate EGA later

	var today = new Date();
	thisYear = today.getYear();

	//  Year 2000 test
	if (thisYear < 300) {
		thisYear = thisYear + 1900
	}

	//  What year was selected?
	
	if (eddYear == 0) {
		eddYear = thisYear;	// This year
	} else {
		eddYear = thisYear + 1;	// Next year
	}


	if (!checkDate(eddMonth,eddDate,eddYear)) {
		alert(monName[eddMonth] + " has " + maxDays[eddMonth] + 
			" days.");
		form.date.focus();
		return false;
	}
	
	var edd = new Date(monName[eddMonth] + " " + eddDate + ", " +
		eddYear + " 12:00:00");

	//  form.day.selectedIndex = edd.getDay();
	writeDay(1, edd.getDay());
	form.theDate.value = edd.getTime();

	var lmp = -280;		// estimated due date
	var concep = -266;	// conception occurs at 2 weeks (14 days)
	var first = -196;	// end of first trimester at 12 weeks
	var second = -91;	// end of second trimester

	//  The last "1" indicates this is LMP
	display(edd.getTime(),lmp,0,1);

	/*  document.DueDate.concep.value=display(edd.getTime(),concep,0,0);
	document.DueDate.first.value = display(edd.getTime(),first,0,0);
	document.DueDate.second.value = display(edd.getTime(),second,0,0);
	*/
	
	showDate(0, display(edd.getTime(),concep,0,0));
	showDate(1, display(edd.getTime(),first,0,0));
	showDate(2, display(edd.getTime(),second,0,0));

	//  document.DueDate.edd.value = display(edd.getTime(),0,0,0);

	return true;
}


function resetForm() {
	document.DueDate.reset();
	document.eddForm.reset();
	document.weeksPreg.reset();
	return true
}


function dateSelect(Month,dd,Year,isEdd) {

var today = new Date();

//
// JavaScript:  Choose Day
//

//	Select the names for the days
	writeDay(isEdd, today.getDay());
	/*
document.writeln("<select name=\"day\" onChange=\"whatDay(this.form," + isEdd + ")\">");	
for (var i=0; i < 7; i++) {
	if (i == today.getDay()) {
		document.writeln("<option selected>" +
		dayName[i]);
	} else {
		document.writeln("<option>" + 
		dayName[i]);
	}
}
document.writeln("</select>, ");
*/

//
// JavaScript:  Choose Month
//

document.writeln("<select name=\"month\" " +
	"onChange=\"whatDay(this.form," + isEdd + ")\">");


//	Select the names for the months

for (var i=0; i < 12; i++) {
	if (i == Month) {
		document.writeln("<option selected>" +
		monName[i]);
	} else {
		document.writeln("<option>" + 
		monName[i]);
	}
}
document.writeln("</select>");


//
// JavaScript:  Choose Date
//

document.writeln("<select name=\"date\" " +
	"onChange=\"whatDay(this.form," + isEdd + ")\">");

for (var d = 1; d < 32; d++) {
	if (d == dd) {
		document.writeln("<option selected>" + dd);
	} else {
		document.writeln("<option>" + d);
	}
}

document.writeln("</select>, ");


//
// JavaScript:  Choose Year
//

document.writeln("<select name=\"year\" " + 
	"onChange=\"whatDay(this.form," + isEdd + ")\">");

//	For dates before the year 2000 (ex. 1999), the year
//	is stored as "xx" (ex. 99).  However, for dates on or 
//	after the year 2000 (ex. 2003), the year is stored as 
//	"xxxx" (ex. 2003).

if (Year < 300) {
	Year = Year + 1900
	}

var checkYr = today.getYear();
if (checkYr < 300) {
	checkYr = checkYr + 1900
	}

var Year1 = Year - 1;

if (isEdd == 2) {Year = Year + 1}  //  This allows for 3 choices

for (var yrCount = Year1; yrCount < (Year + 1); yrCount++) {
	if (yrCount == checkYr) {
		document.writeln("<option selected>" + yrCount)
	} else {
		document.writeln("<option>" + yrCount)
	}
}

document.writeln("</select>");

return true;
}

function showDate(triNum, dateTri) {
	var whichTri;
	if (triNum == 0) {whichTri = eval(getLabel("concep"));} else
		if (triNum == 1) {whichTri = eval(getLabel("first"));} else
		if (triNum == 2) {whichTri = eval(getLabel("second"));}
	whichTri.innerHTML = dateTri;
	whichTri.style.display = "";

	return;
}

function writeDay(whatEdd, chosenDay) {
	var chooseDay;
	if (whatEdd == 0) {chooseDay = eval(getLabel("lmpDay"));} else
		if (whatEdd == 1) {chooseDay = eval(getLabel("eddDay"));} else
		if (whatEdd == 2) {chooseDay = eval(getLabel("wksPreg"));}
	chooseDay.innerHTML = dayName[chosenDay] + ", ";
	chooseDay.style.display = "";

	return;
}


function getLabel(nameID) {
	var whatTag;
	
	if (ie4) {whatTag = "document.all[\"" + nameID + "\"]";}
	if (ns6) {whatTag = "document.getElementById(\"" + nameID + "\")";}
	return whatTag;	
}