// BEGIN sidereal time calculations
//
function zeroPad(val, digits) {
    s = new String('000000000000000000000000000000000000' + val);
    return s.substring(s.length - digits);
}

function numberSuffix(val) {
    s = new String(val);
    if((val > 11) && (val <= 13)) { return "th" }
    else if(s.substring(s.length - 1) == 1) { return "st" }
    else if(s.substring(s.length - 1) == 2) { return "nd" }
    return "th"
}

function lunarPhase(jd) { // returns values 0 .. 1
    var cy = (jd - 2454119.667361111)/29.530588853;
    var lp = cy - Math.round(cy);
    if(lp < 0) { lp++ }
    return lp
}

function dateTime() {
    var phase = new Array("Waxing crescent", "First quarter", "Waxing gibbous",
    	    "Full", "Waning gibbous", "Last quarter", "Waning crescent", "New");
    var days = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday',
	    'Thursday', 'Friday', 'Saturday');
    var months = new Array('January', 'February', 'March', 'April', 'May', 'June',
	    'July', 'August', 'September', 'October', 'November', 'December');
    var now = new Date();
    var yr = 1900 + now.getYear();
    var mo = now.getMonth(); // RETURNS 0 .. 11, not 1 .. 12 !
    var dy = now.getDate();
    var hr = now.getHours();
    var mi = now.getMinutes();
    var se = now.getSeconds();

    var date = new Date();
    var offset = date.getTimezoneOffset();
    var longitude = -88.15;

    var st = calcSiderealTime(longitude, yr, mo + 1, dy, hr, mi, se, offset);
    var jd = calcJulianDate(yr, mo + 1, dy, hr, mi, se, offset);
    var phasepct = lunarPhase(jd);
    var lunarcycle = Math.round(100*phasepct);
    var iphase = Math.floor(8*(phasepct + 0.935)) % 8;

    var imgno = 10*Math.round(36*phasepct);
    var imgtxt = "images/m";
    if(imgno < 10) { imgtxt += "00" }
    else if(imgno < 100) { imgtxt += "0" }
    imgtxt += imgno + ".gif";

    var txt = "Lunar phase: " + phase[iphase] + " (" + lunarcycle + "% of lunar cycle)<br/>" +
	    hr + ":" + zeroPad(mi, 2) +
		// ":" + zeroPad(se, 2) +
	    " (GMT " + -now.getTimezoneOffset()/60 + " hours) " +
	    days[now.getDay()] + " " + months[mo] + " " + dy + numberSuffix(dy) + " " +
	    yr + "<br />" +
	    st + " - sidereal time for Champaign, Illinois, longitude " + longitude;

    return '<table><tr>' +
	    '<td valign="middle"><img src="' + imgtxt + '">&nbsp;&nbsp;</td>' +
	    '<td valign="middle">' + txt + '</td><td>&nbsp;&nbsp;</td>' +
	    '</tr></table>';
}

function tick() {
    document.getElementById("timedisplay").innerHTML = dateTime();
    //setTimeout('tick()', 1000);
    setTimeout('tick()', 60000);
}

function doDisplay() {
    document.getElementById("timedisplay").innerHTML = dateTime();
}

function calcJulianDate(yr, mo, dy, hr, mi, se, offset) {
    with(Math) {
	var hrdec = hr + mi/60 + se/3600;
	var moddy = dy + hrdec/24 + offset/1440;
	if (mo < 3) {
	    yr--;
	    mo += 12;
	}

	var gr = (yr + mo/100 + floor(moddy)/10000 >= 1582.1015) ?
		2 - floor(yr/100) + floor(floor(yr/100)/4) : 0;

	return floor(365.25* yr) + floor(30.6001*(mo + 1)) + floor(moddy) + 1720994.5 + gr; 
    }
}

function calcSiderealTime(longitude, yr, mo, dy, hr, mi, se, offset) {
    // offset is number of minutes to add to get GMT from local time

    with(Math) {
	// Julian Day 
	var hrdec = hr + mi/60 + se/3600;
	var moddy = dy + hrdec/24 + offset/1440;
	var jd = calcJulianDate(yr, mo, dy, hr, mi, se, offset);
	
	// time sidereal 0h
	var t = (jd - 2415020)/36525;
	var ss = 6.6460656 + 2400.051*t + 0.00002581*t*t;
	var st = (ss/24 - floor(ss/24))*24;
	var gsth = floor(st);
	var gstm = floor((st - floor(st))*60);
	var gsts = ((st - floor(st))*60 - gstm)*60;

	// time sidereal local
	var sa = st + (moddy - floor(moddy))*24*1.002737908;
	sa += longitude/15;
	if(sa < 0) { sa += 24 }
	if(sa > 24) { sa -= 24 }

	var tsh = floor(sa);
	var tsm = floor((sa - floor(sa)) * 60);
	var tss = ((sa - floor(sa)) * 60 - tsm) * 60;
	//return zeroPad(tsh, 2) + ":" + zeroPad(tsm, 2) + ":" + zeroPad(round(tss), 2);
	return zeroPad(tsh, 2) + ":" + zeroPad(tsm, 2);
    }
}

function setPrecision(val, places) {
    var fac = Math.pow(10, places);
    var n = (val < 0) ? -1 : 1;
    return n*Math.round(n*fac*val)/fac;
}

// END sidereal time calculations

