/*
 JavaScript Sun Table Calculator
 2002 Juergen Giesen
 http://www.GeoAstro.de
*/


var doy, eqtime, declin, time_offset, tst, ha, Phi, Phi1, Theta, hars;
var sun_rise, sun_set, snoon;
var date, month, hours, minutes, offset, lat, longitude;



	function calcDayOfYear(mn, dy, lpyr) 
	{
		var k = (lpyr ? 1 : 2);
		var doy = Math.floor((275 * mn)/9) - k * Math.floor((mn + 9)/12) + dy -30;
		return doy;
	}

function daysInM(m, y) {
	var n=31
	m=m-1
	if ((m==0) || (m==2) || (m==4) || (m==6) || (m==7) || (m==9) || (m==11))  n=31
	if ((m==3) || (m==5) || (m==8) || (m==10))  n=30;
	if (m==1) {
		n=28;
		if ((y % 4) == 0) n=29
		if ((y % 100) == 0) n=28
		if ((y % 400) == 0) n=29
		}
	return n;	
}

function frac(X) {
 X = X - Math.floor(X);
 if (X<0) X = X + 1.0;
 return X;		
}

function HoursMinutesSeconds(time) {

 var h = Math.floor(time);
 var min = Math.round(60.0*frac(time));
 var str=h+":";
 if (min>=10) str=str+min;
 else  str=str+"0"+min;
 return " " + str;
}

// calculate the fractional day of the year
function dayOfYear() {
 var sum=0;
 for (var i=1; i<month; i++) sum=sum+daysInM(i,2002);
 sum=sum+date;
 var h=hours + offset + minutes/60;
 doy=sum-1+(h-12)/24;
}


// equation of time (in minutes)
function equationTime() {
 var x=doy*2*Math.PI/365;
 eqtime = 229.18*(0.000075+0.001868*Math.cos(x)-0.032077*Math.sin(x)-0.014615*Math.cos(2*x)-0.040849*Math.sin(2*x));
}

// declination (in degrees)
function declination() {
 var x=doy*2*Math.PI/365; // fractional year in radians
 declin=0.006918-0.399912*Math.cos(x)+0.070257*Math.sin(x)-0.006758*Math.cos(2*x);
 declin=declin+0.000907*Math.sin(2*x)-0.002697*Math.cos(3*x)+0.00148*Math.sin(3*x);
 declin=declin*180/Math.PI;
}

// time offset (in minutes)
function tzo() {
 var K=Math.PI/180;
//time_offset = eqtime - 4*longitude + 60*offset;
 time_offset = eqtime - 4*longitude - 60*offset;
}

// true solar time (in hours)
function solarTime() {
 tst = hours*60 + minutes + time_offset;
}

// solar hour angle (in degrees)
function hourAngle() {
 ha = tst/4 - 180;
}

// solar zenith angle (in degrees)
function zenithAngle() {
 var K=Math.PI/180;
 Phi = Math.sin(K*lat)*Math.sin(K*declin)+Math.cos(K*lat)*Math.cos(K*declin)*Math.cos(K*ha);
 Phi = Math.acos(Phi)/K;
 Phi1=90-Phi;// altitude
}

// solar azimuth angle (in degrees, clockwise from north)
function azimuthAngle() {
 var K=Math.PI/180;
 Theta=-(Math.sin(K*lat)*Math.cos(K*Phi)-Math.sin(K*declin))/(Math.cos(K*lat)*Math.sin(K*Phi));
 Theta = Math.acos(Theta)/K;
 if (ha<0) Theta=Theta;
 else Theta=360-Theta;
}

// solar azimuth angle for sunrise and sunset corrected for atmospheric refraction (in degrees),
function hourAngleRiseSet() {
 var K=Math.PI/180;
 hars = Math.cos(K*90.833)/(Math.cos(K*lat)*Math.cos(K*declin)) - Math.tan(K*lat)*Math.tan(K*declin);
 hars = Math.acos(hars)/K;
}

// sunrise and sunset (local time)
function RiseSet() {
 sun_rise = 720 + 4*(longitude-hars) - eqtime;
 sun_rise = sun_rise/60 + offset;
 sun_set = 720 + 4*(longitude+hars) - eqtime;
 sun_set = sun_set/60 + offset;
}

// solar noon (local time)
function noon() {
 snoon = 720 + 4*longitude - eqtime;
 snoon = snoon/60 + offset
}



function getInput() {
 month = Number(document.myform.month.value);
 date = Number(document.myform.date.value);
 hours = Number(document.myform.hours.value);
 minutes = Number(document.myform.minutes.value);
 offset = Number(document.myform.timezone.value);
 lat = Number(document.myform.latitude.value);
 longitude = -Number(document.myform.longitude.value);
}

function writeForm() {
 document.myform.dayofyear.value=" "+Math.round(1000*doy)/1000;
 document.myform.eqt.value=" "+Math.round(100*eqtime)/100;
 document.myform.decl.value=" "+Math.round(100*declin)/100;
 if (time_offset<0) document.myform.sto.value=" -"+Math.round(1000*Math.abs(time_offset))/1000;
 else document.myform.sto.value=" "+Math.round(1000*time_offset)/1000;
 document.myform.st.value=" "+Math.round(1000*tst/60)/1000;
 document.myform.sha.value=" "+Math.round(100*ha)/100;
 document.myform.za.value=" "+Math.round(100*Phi1)/100;
 document.myform.aza.value=" "+Math.round(100*Theta)/100;

 document.myform.hars.value=" "+Math.round(1000*hars)/1000;
 if (document.myform.hars.value.toString().lastIndexOf('N')>0) document.myform.hars.value=" --:--";

 document.myform.sunrise.value=HoursMinutesSeconds(sun_rise);
 if (document.myform.sunrise.value.toString().lastIndexOf('N')>0) document.myform.sunrise.value=" --:--";

 document.myform.sunset.value=HoursMinutesSeconds(sun_set);
 if (document.myform.sunset.value.toString().lastIndexOf('N')>0)  document.myform.sunset.value=" --:--";

 document.myform.snoon.value=HoursMinutesSeconds(snoon);
}


function calculate() {
 getInput();
 dayOfYear();
 equationTime();
 declination();
 tzo();
 solarTime();
 hourAngle();
 zenithAngle();
 azimuthAngle();
 hourAngleRiseSet();
 RiseSet();
 noon();
 writeForm();
}




