// ======= constants =======
// var synodic = 29.530588858;		// the synodic period
var synodic = 29.5305891203704;		// 29d 12h 44m 2.9s
var msPerDay = 24 * 60 * 60 * 1000;	// milliseconds per day

// =======================================================
function rnd(val, prec) {
  // general function for rounding to specified precision
  with (Math) {
    val *= pow(10, prec);
    val = round(val);
    val /= pow(10, prec);
  }
  return val;
}

// =======================================================
function dateAddDays(dte, days) {
  var tmp = new Date(dte.valueOf() + (days * msPerDay));
  return tmp;
}

// =======================================================
function formatDate(dte) {
  var astrMth = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
  var astrDay = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
  with (dte) {
    var strDay  = astrDay[getDay()];
    var strMth  = astrMth[getMonth()];
    var intDate = getDate();
    var intYr   = getFullYear();
  }
  switch (intDate % 10) {
 	case 1:
		var strDate = intDate + "st";
		break;
	case 2:
		var strDate = intDate + "nd"; 
		break;
	case 3:
		var strDate = intDate + "rd"; 
		break;
	default:
		var strDate = intDate + "th"; 
		break;
  }
  return strDay + ", " + strMth + " " + strDate + ", " + intYr;  
}

// =======================================================
function daysTillNext(phaseNext, phaseCurr) {
  var days = synodic * (phaseNext - phaseCurr) / 100;
  while (days <= 0) {
    days += synodic;
  }
  return days;
}

// =======================================================
function moonPhPer(anyDate) {
  // calculate the moon phase as a percent
  // base New Moon date was Jan 13, 2002 at 13:29 UT
  // refer to http://aa.usno.navy.mil/data/docs/MoonPhase.html
  var baseDate = new Date();
  with (baseDate) {
    setUTCFullYear(2002);
    setUTCMonth(0);
    setUTCDate(13);
    setUTCHours(13);
    setUTCMinutes(29);
    setUTCSeconds(0);
  }

  var diff = Math.abs(anyDate - baseDate);       // the difference in milliseconds
  var phase = 100 * diff / (synodic * msPerDay); // phase percent
  while (phase > 100) {
    phase -= 100;
  }
  return phase; 
}

// =======================================================
function moonPhase(phase) {
  // convert moon phase percent to nice words
  if ((phase >= 0) && (phase < 2.5)) {
    var phaseName = "New Moon";
  } else if ((phase >= 2.5) && (phase < 22.5)) {
    var phaseName = "Waxing Crescent";
  } else if ((phase >= 22.5) && (phase < 27.5)) {
    var phaseName = "1st Quarter Moon";
  } else if ((phase >= 27.5) && (phase < 47.5)) {
    var phaseName = "Waxing Gibbous";
  } else if ((phase >= 47.5) && (phase < 52.5)) {
    var phaseName = "Full Moon";
  } else if ((phase >= 52.5) && (phase < 73.5)) {
    var phaseName = "Waning Gibbous";
  } else if ((phase >= 73.5) && (phase < 77.5)) {
    var phaseName = "3rd Quarter Moon";
  } else if ((phase >= 77.5) && (phase < 97.5)) {
    var phaseName = "Waning Crescent";
  } else {
    var phaseName = "New Moon";
  }
  return phaseName;
}

// =======================================================
function writePage() {
  // outputs the moon phase data to the web page
  var today = new Date();
  var phasePercent = moonPhPer(today);
  var moonAge = synodic * phasePercent / 100;

  var daysTillNew  = daysTillNext( 0, phasePercent);
  var daysTillQtr1 = daysTillNext(25, phasePercent);
  var daysTillFull = daysTillNext(50, phasePercent);
  var daysTillQtr3 = daysTillNext(75, phasePercent);

  var newDate  = dateAddDays(today, daysTillNew);
  var qtr1Date = dateAddDays(today, daysTillQtr1);
  var fullDate = dateAddDays(today, daysTillFull);
  var qtr3Date = dateAddDays(today, daysTillQtr3);

  // create some strings to display
  var strIntro = "<P>The calculations performed on this page have been checked";
      strIntro += " against <A HREF='http://aa.usno.navy.mil/data/docs/MoonPhase.html'";
      strIntro += " TARGET='_blank'>published tables</A> and occasional differences";
      strIntro += " (no more than a day either way) have been found. If you&#39;re";
      strIntro += " planning a space mission, then I wouldn&#39;t rely on this data,";
      strIntro += " but if you&#39;re planning a fishing trip then these are okay.</P>";

  var strHW = "HEIGHT='100' WIDTH='100'";
  var strQtr1 = "<TR><TD>";
      strQtr1 += "<IMG SRC='img/firstqtr.gif' " + strHW + " ALT='1st Quarter' TITLE='1st Quarter'>";
      strQtr1 += "</TD><TD>";
      strQtr1 += "Next first quarter is in " + rnd(daysTillQtr1, 1) + " days<BR>";
      strQtr1 += "(on " + formatDate(qtr1Date) + ")";
      strQtr1 += "</TD></TR>";

  var strFull = "<TR><TD>";
      strFull += "<IMG SRC='img/fullmoon.gif' " + strHW + " ALT='Full Moon' TITLE='Full Moon'>";
      strFull += "</TD><TD>";
      strFull += "Next full moon is in " + rnd(daysTillFull, 1) + " days<BR>";
      strFull += "(on " + formatDate(fullDate) + ")";
      strFull += "</TD></TR>";

  var strQtr3 = "<TR><TD>";
      strQtr3 += "<IMG SRC='img/lastqtr.gif' " + strHW + " ALT='Last Quarter' TITLE='Last Quarter'>";
      strQtr3 += "</TD><TD>";
      strQtr3 += "Next last quarter is in " + rnd(daysTillQtr3, 1) + " days<BR>";
      strQtr3 += "(on " + formatDate(qtr3Date) + ")";
      strQtr3 += "</TD></TR>";

  var strNew = "<TR><TD>";
      strNew += "<IMG SRC='img/newmoon.gif' " + strHW + " ALT='New Moon' TITLE='New Moon'>";
      strNew += "</TD><TD>";
      strNew += "Next new moon is in " + rnd(daysTillNew, 1) + " days<BR>";
      strNew += "(on " + formatDate(newDate) + ")";
      strNew += "</TD></TR>";

  // juggle the strings around so they will appear in chronological order
  if ((phasePercent < 25) || (phasePercent == 100)) {
    var strTblBody = strQtr1 + strFull + strQtr3 + strNew;
  } else if (phasePercent < 50) {
    var strTblBody = strFull + strQtr3 + strNew + strQtr1;
  } else if (phasePercent < 75) {
    var strTblBody = strQtr3 + strNew + strQtr1 + strFull;
  } else {
    var strTblBody = strNew + strQtr1 + strFull + strQtr3;
  }
	
  // now write the page
  with (document) {
    write(strIntro);
    write("<HR><P>");
    write("Today is " + formatDate(today) + ".<BR>");
    write("The current moon is a &quot;" + moonPhase(phasePercent) + "&quot;");
    write(", " + rnd(moonAge, 1) + " days old.");
    write("</P>");
    write("<TABLE><TBODY>");
    write(strTblBody);
    write("</TBODY></TABLE>");
  }
}

// =======================================================

