/* kzman.js - Kaluach halachic times Javascript routines
 * Copyright (C) 5760,5761 (2000 CE), by Abu Mami and Yisrael Hersch.
 *   All Rights Reserved.
 *   All copyright notices in this script must be left intact.
 * Acknowledgment given to scripts by:
 *   - P. Lutus <lutusp@arachnoid.com>
 *     available under the www.arachnoid.com CareWare program
 *	 - Tomer and Yehuda Shiran (docjs.com)
 *   - irt.org
 *   - javascripter.net
 * website: http://www.kaluach.net
 * email: abumami@kaluach.org
 */



var month = 0, day = 0, year = 0;
////////////////var latt = 0, lngg = 0;	// sun's location
var latd = -1, latm = 0;// latitude
var lngd = -1, lngm = 0;// longitude
var ns = 'N', ew = 'W';	// hemisphere
var dst = 0;
var ampm = 1;
var tz = 0;

function checkDST(m,d,y) {
	var gmt = new Date(y,m-1,d-1);
	var lsm = new Date;
	var lso = new Date;
	lsm.setMonth(2); // March
	lsm.setDate(1);
	var day = lsm.getDay();
	lsm.setDate(15-day); // second sunday in march
	lsm.setHours(2);
	lsm.setMinutes(0);
	lsm.setSeconds(0);

	///lso.setMonth(9); // October
	///lso.setDate(31);
	///day = lso.getDay();
	///lso.setDate(31-day);

	lso.setMonth(10); // November
	lso.setDate(1);
	var day = lso.getDay();
	lso.setDate(7-day); // first sunday in november
	lso.setHours(2);
	lso.setMinutes(0);
	lso.setSeconds(0);

	if (gmt <= lsm || gmt >= lso) { dst = 0 } else { dst = 1 }
}

function leap(y) {
	return ((y % 400 == 0) || (y % 100 != 0 && y % 4 == 0));
}

function civMonthLength(month, year) {
	if(month == 2)
		return 28 + leap(year);
	else if(month == 4 || month == 6 || month == 9 || month == 11)
		return 30;
	else
		return 31;
}

function list_pos(s) {
	var i;
	var str = s;

	i = str.indexOf(",");
	ns = str.substring(0, i);
	str = str.substring(i+1, str.length);

	i = str.indexOf(",");
	latd = Math.abs(eval(str.substring(0, i)));
	str = str.substring(i+1, str.length);

	i = str.indexOf(",");
	latm = Math.abs(eval(str.substring(0, i)));
	str = str.substring(i+1, str.length);

	i = str.indexOf(",");
	ew = str.substring(0, i);
	str = str.substring(i+1, str.length);

	i = str.indexOf(",");
	lngd = Math.abs(eval(str.substring(0, i)));
	str = str.substring(i+1, str.length);

	i = str.indexOf(",");
	lngm = Math.abs(eval(str.substring(0, i)));

	tz = (eval(str.substring(i+1, str.length)));
}

function getZman(month,day,year,tx) { 

var pos = " N, 40, 51, W,  73.25,  28, -05";
list_pos(pos);

	var d, m, y;
	var nsi, ewi;
	var i;

	i = ns.indexOf("N");
	nsi = (i != -1) ? 0 : 1;
	i = ew.indexOf("W");
	ewi = (i != -1) ? 0 : 1;

	d = day + 1;
	m = month + 1;
	y = year;

	checkDST(m,d,y) ;
	var adj = tz;
	adj += dst;

	var time;
	var sunrise, sunset;
	var shaa_zmanit;

	time = suntime(d, m, y, 90, 50, lngd, lngm, ewi, latd, latm, nsi, adj);
	if(time[1] == 0) {
		sunrise = time[2];
		sunset  = time[3];
		shaa_zmanit = (sunset - sunrise) / 12;
	}
	if (tx == "hanetz") { 
		return timeadj(sunrise);
	}
	if (tx == "shkia") { 
		return timeadj(sunset);
	}
	if (tx == "alot") {
		time = suntime(d, m, y, 106, 6, lngd, lngm, ewi, latd, latm, nsi, adj);
		if(time[1] == 0)
			return timeadj(time[2]);
	}
	if (tx == "misheyakir") {
		time = suntime(d, m, y, 101, 0, lngd, lngm, ewi, latd, latm, nsi, adj);
		if(time[1] == 0)
			return timeadj(time[2]);
	}
	if (tx == "taanisstart") {
		time = suntime(d, m, y, 102, 40, lngd, lngm, ewi, latd, latm, nsi, adj);
		if(time[1] == 0)
			return timeadj(time[2]);
	}
	if (tx == "tzeit") {
		time = suntime(d, m, y, 96, 0, lngd, lngm, ewi, latd, latm, nsi, adj);
		if(time[1] == 0)
			return timeadj(time[3]);
	}
	if (tx == "shema") {
		return timeadj(sunrise + shaa_zmanit * 3);
	}
	if (tx == "tefillah") {
		return timeadj(sunrise + shaa_zmanit * 4);
	}
	if (tx == "eatchometz") {
		return timeadj(sunrise + shaa_zmanit * 3.58);
	}
	if (tx == "burnchometz") {
		return timeadj(sunrise + shaa_zmanit * 4.82);
	}
	if (tx == "chatzot") {
		return timeadj(sunrise + shaa_zmanit * 6);
	}
	if (tx == "minchag") {
		return timeadj(sunrise + shaa_zmanit * 6.5);
	}
	if (tx == "minchak") {
		return timeadj(sunrise + shaa_zmanit * 9.5);
	}
	if (tx == "plag") {
		return timeadj(sunrise + shaa_zmanit * 10.75);
	}
	if (tx == "plagmincha") {
		return timeadj(sunrise + shaa_zmanit * 10.77 - 10.0/60.0);
	}
	if (tx == "motzeishabbat") {
		time = suntime(d, m, y, 98.5, 30, lngd, lngm, ewi, latd, latm, nsi, adj);
		if(time[1] == 0)
			return timeadj(time[3] + 9.0/60.0);
	}
	if (tx == "yomtovcandles") {
		time = suntime(d, m, y, 98.5, 30, lngd, lngm, ewi, latd, latm, nsi, adj);
		if(time[1] == 0)
			return timeadj(time[3] + 3.0/60.0);
	}
	if (tx == "knissatshabbat") {
		time = suntime(d, m, y, 90.77, 50, lngd, lngm, ewi, latd, latm, nsi, adj);
		return timeadj(time[3] - 15.0/60.0);
	}
	if (tx == "fridaymincha") {
		time = suntime(d, m, y, 90, 50, lngd, lngm, ewi, latd, latm, nsi, adj);
		return timeadj(time[3] - 13.0/60.0, 5);
	}
	if (tx == "shabbosmincha") {
		time = suntime(d, m, y, 90, 50, lngd, lngm, ewi, latd, latm, nsi, adj);
		return timeadj(time[3] - 12.5/60.0, 5);
	}
	if (tx == "yomtovmincha") {
		time = suntime(d, m, y, 90, 50, lngd, lngm, ewi, latd, latm, nsi, adj);
		return timeadj(time[3] - 16.0/60.0, 5);
	}
	if (tx == "yomtovmaariv") {
		time = suntime(d, m, y, 98, 30, lngd, lngm, ewi, latd, latm, nsi, adj);
		return timeadj(time[3] + 3.0/60.0, 5);
	}
	if (tx == "rabbisshiur") {
		time = suntime(d, m, y, 90, 50, lngd, lngm, ewi, latd, latm, nsi, adj);
		return timeadj(time[3] - 85.0/60.0, 15);
	}
	if (tx == "dailymincha") {
		if (m < 11 && m > 3) {
			time = suntime(d, m, y, 92, 50, lngd, lngm, ewi, latd, latm, nsi, adj);
			return timeadj(time[3] - 22.5/60.0, 5);
		} else {
			time = suntime(d + 5, m, y, 90, 50, lngd, lngm, ewi, latd, latm, nsi, adj);
			return timeadj(time[3] - 15.0/60.0, 5);
		}
	}
	if (tx == "maariv") {
		time = suntime(d, m, y, 98, 30, lngd, lngm, ewi, latd, latm, nsi, adj);
		return timeadj(time[3], 5);
	}
	if (tx == "taanismincha") {
		time = suntime(d, m, y, 90, 50, lngd, lngm, ewi, latd, latm, nsi, adj);
		return timeadj(time[3] - 25.0/60.0, 5);
	}
	if (tx == "purimseuda") {
		return timeadj((sunrise + shaa_zmanit * 6) - 30.0/60.0, 5);
	}
	if (tx == "eicha") {
		time = suntime(d, m, y, 98, 30, lngd, lngm, ewi, latd, latm, nsi, adj);
		if(time[1] == 0)
			return timeadj(time[3] - 20.0/60.0, 5);
	}
}

///////////////from ksun.js
var monCount = new makeArray(1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366);
function makeArray() {
	this[0] = makeArray.arguments.length;
	for (i = 0; i < makeArray.arguments.length; i = i + 1)
		this[i+1] = makeArray.arguments[i];
}
function doy(d, m, y) {
	return monCount[m] + d + (m > 2 && leap(y));
}
function suntime(dy, mn, yr, sundeg, sunmin, londeg, lonmin, ew, latdeg, latmin, ns, timezone) {
	var invalid = 0;	// start out as OK
//status= dy+" "+mn+" "+yr+" "+sundeg+" "+sunmin+" "+londeg+" "+lonmin+" "+ew+" "+latdeg+" "+latmin+" "+ns+" "+timezone ;
//status= ns;
	longitude = (londeg + lonmin/60.0) * ((ew == 0) ? -1 : 1);
	latitude  = (latdeg + latmin/60.0) * ((ns == 0) ? 1 : -1);

	var yday = doy(dy, mn, yr);

	var Aa = 1.5708; 
	var Bb = 3.14159; 
	var Cc = 4.71239; 
	var Dd = 6.28319;      
	var Ee = 0.0174533 * latitude; 
	var Ff = 0.0174533 * longitude; 
	var Gg = 0.261799 * timezone; 

	var Rr = Math.cos(0.01745 * (sundeg + sunmin/60.0));

	var Jj;

	// two times through the loop
	//    i=0 is for sunrise
	//    i=1 is for sunset
	for (i = 0; i < 2; i++) { 

		if(!i)
			Jj =  Aa;	// sunrise 
		else
			Jj = Cc;	// sunset

		var Kk = yday + ((Jj - Ff) / Dd); 
		var Ll = (Kk * .017202) - .0574039;              // Solar Mean Anomoly 
		var Mm = Ll + .0334405 * Math.sin(Ll);            // Solar True Longitude 
		Mm += 4.93289 + (3.49066E-04) * Math.sin(2 * Ll); 
		
		// Quadrant Determination 
		if (Dd == 0) {
			alert("Trying to normalize with zero offset...");
			exit;
		} 

		while(Mm < 0)
			Mm = (Mm + Dd);

		while(Mm >= Dd)
			Mm = (Mm - Dd);

		if ((Mm / Aa) - Math.floor(Mm / Aa) == 0)
			Mm += 4.84814E-06;

		var Pp = Math.sin(Mm) / Math.cos(Mm);                   // Solar Right Ascension 
		Pp = Math.atan2(.91746 * Pp, 1); 

		// Quadrant Adjustment 
		if (Mm > Cc)
			Pp += Dd;
		else {
			if (Mm > Aa)
				Pp += Bb;
		} 

		var Qq = .39782 * Math.sin(Mm);      // Solar Declination 
		Qq = Qq / Math.sqrt(-Qq * Qq + 1);     // This is how the original author wrote it! 
		Qq = Math.atan2(Qq, 1); 

		var Ss = Rr - (Math.sin(Qq) * Math.sin(Ee)); 
		Ss = Ss / (Math.cos(Qq) * Math.cos(Ee)); 

		if(Math.abs(Ss) > 1)
			invalid = 1;	// uh oh! no sunrise/sunset

		Ss = Ss / Math.sqrt(-Ss * Ss + 1); 
		Ss = Aa - Math.atan2(Ss, 1); 

		if(!i)
			Ss = Dd - Ss;	// sunrise

		var Tt = Ss + Pp - 0.0172028 * Kk - 1.73364;  // Local apparent time 
		var Uu = Tt - Ff;                            // Universal timer 
		var Vv = Uu + Gg;                            // Wall clock time 

		// Quadrant Determination 
		if(Dd == 0) {
			alert("Trying to normalize with zero offset...");
			exit;
		} 
		while(Vv < 0)
			Vv = Vv + Dd;
		while(Vv >= Dd)
			Vv = Vv - Dd;
		Vv = Vv * 3.81972; 
		if(!i)
			sr = Vv;	// sunrise
		else
			ss = Vv;	// sunset
	}
	var ret = new Object();
	ret[1] = invalid;
	ret[2] = sr;
	ret[3] = ss;
	return ret;
}
function timeadj(tx,r) {
	var hour;
	var min;
	var time = tx;
	var hour = Math.floor(time);
	var min  = Math.floor((time - hour) * 60.0 + 0.5);
	if (r > 0) { min = Math.round(min / r) * r; }

	if(min >= 60) {
		hour += 1;
		min  -= 60;
	}
	if(hour < 0)
		hour += 24;

		ampm_str = (hour > 11) ? 'pm' : 'am';
		hour %= 12;
		hour = (hour < 1) ? 12 : hour;

	var str = hour + ':' + ((min < 10) ? '0' : '') + min + ampm_str;
	return str;
}



