//	"Calendario Perpetuo" in Javascript
//	@2002 Paolo Bonavoglia - Venezia
//	
//	Riproduzione consentita a condizione che venga citata esplicitamente la fonte
//
//	Costanti e alcuni algoritmi sono tratti da J.Meeus - Astronomia con il computer
//

Calendario = new Array(
	'<A HREF="cal_giul_analettico.html">giuliano analettico</A>', 
	'<A HREF="cal_augusto.html">giuliano</A> prima della correzione di Augusto', 
	'<A HREF="cal_augusto.html">giuliano durante la correzione di Augusto</A>', 
	'<A HREF="cal_giuliano.html">giuliano</A>', 
	'<A HREF="cal_gregoriano.html">gregoriano</A>');
TipoCal = 4;
Week   = new Array('Domenica', 'Luned&igrave;', 'Marted&igrave;', 'Mercoled&igrave;',
		'Gioved&igrave;', 'Venerd&igrave;', 'Sabato')
WeekRF = new Array('Primidi', 'Duodi', 'Tridi', 'Quartidi', 'Quintidi', 
		'Sextidi', 'Septidi', 'Octidi', 'Nonidi', 'Decadi')
Mesi      = new Array('Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 
			'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre')

Mesi0 = new Array('Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 
		'Quintile', 'Sestile', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre')
GiorniMese0 = new Array(31,29,31,30,31,30,31,30,31,30,31,30)
Mesi1 = new Array('Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 
		'Luglio', 'Sestile', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre')
GiorniMese = new Array(31,28,31,30,31,30,31,31,30,31,30,31)

MesiIslam = new Array('Muharram', 'Safar', 'Rabi al-Awwali', 'Rabi ath-Thani', 
	'Jumada l-Ula', 'Jumada l-Akhira', 'Rajab', 'Shaban', 'Ramadhan', 'Schawwal', 
	'Zu l-Qada', 'Zu l-Hijja')
GiorniMeseIslam = new Array(30,29,30,29,30,29,30,29,30,29,30,29);
AnniAbbondanti  = new Array(2,5,7,10,13,16,18,21,24,26,29);

MesiEbrei = new Array('Tishri', 'Heshvan', 'Kislev', 'Tevet', 'Shevat', 'Adar', 
		'Adar II', 'Nisan', 'Iyar', 'Sivan', 'Tammuz', 'Av', 'Elul')

GiorniMeseOD = new Array(30,29,29,29,30,29, 0,30,29,30,29,30,29);
GiorniMeseOR = new Array(30,29,30,29,30,29, 0,30,29,30,29,30,29);
GiorniMeseOC = new Array(30,30,30,29,30,29, 0,30,29,30,29,30,29);
GiorniMeseED = new Array(30,29,29,29,30,30,29,30,29,30,29,30,29);
GiorniMeseER = new Array(30,29,30,29,30,30,29,30,29,30,29,30,29);
GiorniMeseEC = new Array(30,30,30,29,30,30,29,30,29,30,29,30,29);
AnniEmbolismici  = new Array(3,6,8,11,14,17,19);

MesiRF    = new Array('Vend&eacute;miaire', 'Brumaire', 'Frimaire', 'Nivose', 'Pluviose', 'Ventose', 
		'Germinal', 'Flor&eacute;al', 'Prairial', 'Messidor', 'Thermidor', 'Fructidor', 'Complement.')
Stagioni = new Array('Autunno', 'Inverno', 'Primavera', 'Estate');


Lunazione  = 29.53058868;	// Durata media del mese lunare 29.53058868
LunaNuova0 = 2415020.75933;	// Prima Luna Nuova del 1900
Secolo     = 36525;		// Durata del secolo giuliano in giorni
Metone	   = 6939.69;		// ciclo 19 anni: 11 comuni; 7 embolismici
Creazione  = 347998;		// Creazione del mondo secondo gli ebrei
Egira      = 1948440;		// Inizio Calendario Islam (Egira)
Trentennio = 10631;		// 19 anni comuni (354g); 11 abbondanti (355g)
InizioRF   = 2375839.85		// Inizio Calendario Rivoluzionario

AnnoRF	   = 365.242198842	// Anno tropico

AnnoRifGiuliana = -45;
AnnoCorrAugusto = -6;
AnnoGiulianoRegime = 8;

JDRiformaGiuliana   = 1704622; // 1/1/-45
JDRiformaAugusto0   = 1718870; // 1/1/-6
JDRiformaAugusto1   = 1723980; // 1/1/8
JDRiformaGregoriana = 2299161; // 15/10/1582

function NomeCalendario(){
	return(Calendario[TipoCal]);
}

function SelezionaCalendarioDalGiorno(xd, xm, xy){
   	if (xy < AnnoRifGiuliana) {
		TipoCal = 0;
	} else if (xy < AnnoCorrAugusto) {
		TipoCal = 1;
	} else if (xy < AnnoGiulianoRegime) {
		TipoCal = 2;
	} else if ((xy < 1582) || ((xy == 1582) && (xm < 10)) || ((xy == 1582) && (xm == 10) && (xd < 5))){
		TipoCal = 3;		
	} else {
		TipoCal = 4;
	}
}

function SelezionaCalendarioDaJD(jd){
   	if (jd < JDRiformaGiuliana) {
		TipoCal = 0;
	} else if (jd < JDRiformaAugusto0) {
		TipoCal = 1;
	} else if (jd < JDRiformaAugusto1) {
		TipoCal = 2;
	} else if (jd < JDRiformaGregoriana){
		TipoCal = 3;		
	} else {
		TipoCal = 4;
	}
}



function RecEclisse(jd, gamma, cono){
	this.JD = jd
	this.Gamma = gamma
	this.Cono = cono
	this.value = ''
}

function Numero(val){
	this.value = val
}

function Stringa(val){
	this.value = val
}

function AnomaliaSole(sc, kappa){
	return -0.013540264+0.50798429*kappa - (5.81e-7)*sc*sc - (6.056e-8)*sc*sc*sc
}

function AnomaliaLuna(sc, kappa){
	return 5.341149+6.7337755*kappa+(1.87284e-4)*sc*sc+(2.157e-7)*sc*sc*sc
}

function LatitudineLuna(sc, kappa){
	return 0.3716923 + 6.8184866*kappa - (2.8846e-5)*sc*sc - (4.171e-8)*sc*sc*sc
}

function LunaMedia(jd, kappa){
	return LunaNuova0 + Lunazione * kappa 
		+ 0.0001178*jd*jd
		- 0.000000155*jd*jd*jd
		+ 0.00033*Math.sin(2.90702 + 2.319019*jd - (1.60099e-4)*jd*jd)
		- 0.000281817 - 0.000837*jd - 0.00034663*jd*jd // TE -> TU
}

function Luna(jd, kappa){
	var	AS = AnomaliaSole(jd, kappa)
	var	AL = AnomaliaLuna(jd, kappa)
	var	FL = LatitudineLuna(jd, kappa); 
	return LunaMedia(jd, kappa)
		+ (0.1734-0.000393*jd)*Math.sin(AS)
		- 0.4068 * Math.sin(AL)
		+ 0.0161 * Math.sin(AL+AL)
		+ 0.0104 * Math.sin(FL+FL)
		- 0.0074 * Math.sin(AS-AL)
		- 0.0051 * Math.sin(AS+AL)
		+ 0.0021 * Math.sin(AS+AS)
		+ 0.0010 * Math.sin(FL+FL-AL)
		- 0.0006 * Math.sin(FL+FL+AL)
		- 0.0004 * Math.sin(FL+FL-AS)
		+ 0.0004 * Math.sin(FL+FL+AS)
		+ 0.0005 * Math.sin(AS+AL+AL)
		- 0.0004 * Math.sin(AL+AL+AL)
}

function QuartoLuna(jd, kappa){
	var	AS = AnomaliaSole(jd, kappa)
	var	AL = AnomaliaLuna(jd, kappa)
	var	FL = LatitudineLuna(jd, kappa); 
	return LunaMedia(jd, kappa)
		+ (0.1721-0.0004*jd)*Math.sin(AS)
		- 0.6280 * Math.sin(AL)
		+ 0.0089 * Math.sin(AL+AL)
		+ 0.0079 * Math.sin(FL+FL)
		- 0.0047 * Math.sin(AS-AL)
		- 0.0119 * Math.sin(AS+AL)
		+ 0.0021 * Math.sin(AS+AS)
		+ 0.0004 * Math.sin(FL+FL-AL)
		- 0.0006 * Math.sin(FL+FL+AL)
		- 0.0004 * Math.sin(FL+FL-AS)
		+ 0.0003 * Math.sin(FL+FL+AS)
		+ 0.0004 * Math.sin(AS+AL+AL)
		- 0.0004 * Math.sin(AL+AL+AL)
}

function Eclisse(ns, kappa, AS, AL, FL){
//	var	AS = AnomaliaSole(ns, kappa)
//	var	AL = AnomaliaLuna(ns, kappa)
//	var	FL = LatitudineLuna(ns, kappa); 
	return LunaMedia(ns, kappa)
		+ (0.1734-0.000393*ns)*Math.sin(AS)
		- 0.4068 * Math.sin(AL)
		+ 0.0161 * Math.sin(AL+AL)
		- 0.0104 * Math.sin(FL+FL)
		- 0.0074 * Math.sin(AS-AL)
		- 0.0051 * Math.sin(AS+AL)
		+ 0.0021 * Math.sin(AS+AS)
		+ 0.0010 * Math.sin(FL+FL-AL)
}

function UltimaLunaNuova(jd){
	var ts = jd - LunaNuova0;
	var tenta = Math.floor(ts/Lunazione);
	ts = ts/Secolo;
	return Luna(ts, tenta)
}

function ProssimaLuna(fase, jd){
	var ts = jd - LunaNuova0;
	var tenta = fase + Math.floor(ts/Lunazione);
	ts = ts/Secolo;
	do {
		full = Luna(ts, tenta)
		++tenta
	} while (full < jd)
	return full
}

function ProssimoQuarto(fase, jd){
	var ts = jd - LunaNuova0;
	var tenta = fase + Math.floor(ts/Lunazione)
	ts = ts/Secolo;
	do {
		full = QuartoLuna(ts, tenta)
		++tenta
	} while (full < jd)
	return full
}

function ProssimaFase(jd, fase){
	var ts = jd - LunaNuova0;
	var tenta = Math.floor(ts/Lunazione)
	ts = ts/Secolo;
	fase.value = "XX";
	do {
		full = Luna(ts, tenta);
		if (full >= jd) {fase.value = "lunanuova"; break}
		full = QuartoLuna(ts, tenta+0.25)
		if (full >= jd) {fase.value = "primoquarto"; break}
		full = Luna(ts, tenta+0.5)
		if (full >= jd) {fase.value = 'lunapiena'; break}
		full = QuartoLuna(ts, tenta+0.75)
		if (full >= jd) {fase.value = 'ultimoquarto'; break}
		++tenta
	} while (fase.value == "XX");
	return full
}

function ShowMoon(JD, fase, ore){
	if ((fase == 0.5) || (fase == 0)){
   		Moon = new Numero(ProssimaLuna(fase, JD.value) + 0.5);
	} else {
   		Moon = new Numero(ProssimoQuarto(fase, JD.value) + 0.5);
	}
	return JD2GiornoOra(Moon.value, ore)
}

function ProssimaEclisse(sole, jd, ecl){
	var ts = jd - LunaNuova0;
	var tenta = sole + Math.floor(ts/Lunazione)
	ts = ts/Secolo;
	do {
		full = LunaMedia(ts, tenta)
		ns = (full-LunaNuova0)/Secolo;
		Fase = LatitudineLuna(ns, tenta); 
//		if ((Math.abs(Math.sin(Fase)) < 0.24)&&(full>=jd)){return full}
		if ((Math.abs(Math.sin(Fase)) < 0.36)&&(full>=jd)){
			AS = AnomaliaSole(ns, tenta)
			AL = AnomaliaLuna(ns, tenta)
			CS = 5.19595 - 0.0048 * Math.cos(AS) + 0.002*Math.cos(AS+AS)
					-0.3283*Math.cos(AL) -0.006*Math.cos(AS+AL)
					+0.0041*Math.cos(AS-AL)
			CC = 0.202*Math.sin(AS) +0.024*Math.sin(AS+AS) - 0.039*Math.sin(AL)
					+ 0.0115*Math.sin(AL+AL) -0.0073*Math.sin(AS+AL)
					-0.0067*Math.sin(AS-AL) + 0.0117*Math.sin(Fase +Fase);
			ecl.Gamma   = CS*Math.sin(Fase)+CC*Math.cos(Fase);
			ecl.Cono	= 0.0059 + 0.0046*Math.cos(AS) - 0.0182*Math.cos(AL)
					+0.0004*Math.cos(AL+AL) - 0.0005*Math.cos(AS+AL);
			if (Math.abs(ecl.Gamma) < Math.abs(ecl.Cono) + 1.5432) {
				ecl.JD = Eclisse(ns, tenta, AS, AL, Fase);
				return 0
			}
		}
		++tenta
	} while (1)
	return -1
}

function TipoEclisse(fase, StrEc){
	StrEc.value = 'Eclisse ';
	if (fase == 0) {
		if (Math.abs(StrEc.Gamma) < 0.9972) {
			if (StrEc.Cono < 0) {
				StrEc.value += 'totale '
			} else if (StrEc.Cono <= 0.0047) {
				StrEc.value += 'anulare-totale '
			} else {
				StrEc.value += 'anulare '
			}
		} else {
			StrEc.value += 'parziale '
		}
		StrEc.value += 'di Sole '
		if (StrEc.Gamma > 0.9) {
			StrEc.value += '(area artica)'
		} else if (StrEc.Gamma > 0.2){
			StrEc.value += '(emisfero Nord)'
		} else if (StrEc.Gamma > -0.2){
			StrEc.value += '(area equatoriale)'
		} else if (StrEc.Gamma > -0.9) {
			StrEc.value += '(emisfero Sud)'
		} else {
			StrEc.value += '(area antartica)'
		}
	} else if (fase == 0.5) {
		var magn = (1.0129 - Math.abs(StrEc.Gamma) - StrEc.Cono);
		if (magn > 0.545) {
			StrEc.value += 'totale di Luna'
		} else if (magn > 0) {
			StrEc.value += 'parziale di Luna'
		} else if (Math.abs(StrEc.Gamma) - StrEc.Cono < 1.5572) {
			StrEc.value += 'di penombra di Luna'
		} else {
			StrEc.value += 'dubbia di Luna'
		}
	}
}

function JDNextEclisse(JD, fase, ore){
	StrEc = new RecEclisse(0, 0, 0);
	ProssimaEclisse(fase, JD.value, StrEc);
	return StrEc;
}

function ShowNextEclisse(StrEc, fase, ore){
	TipoEclisse(fase, StrEc);
	return StrEc.value + '<DIV>' + JD2GiornoOra(StrEc.JD + 0.5, ore) + '</DIV>';
}

function ShowEclisse(JD, fase, ore){
	StrEc = new RecEclisse(0, 0, 0);
	ProssimaEclisse(fase, JD.value, StrEc);
	TipoEclisse(fase, StrEc);
	return StrEc.value + '<DIV>' + JD2GiornoOra(StrEc.JD + 0.5, ore) + '</DIV>'
}


function Bisestile(anno) {
	switch(TipoCal){
	case 1:	return (anno % 3 == 0);
	case 2:	return (0);
	case 4: return (((anno % 4 == 0) && (anno % 100 != 0)) || (anno % 400 == 0));
	default: return (anno % 4 == 0);
	}
}

function NomeMese(xm, anno) {
	if (anno < -43){
		return (Mesi0[xm])
	} else if (anno < -7){
		return (Mesi1[xm])
	} else {
		return (Mesi[xm]);
	}
}

function GiornidelMese0(mese, anno) {
//	if ((anno == 1582) && (mese == 9)) {
//	  return (GiorniMese[mese]-9)
//	}
	switch(TipoCal){
	case 0: return (GiorniMese[mese]);
	case 1: return (GiorniMese0[mese]);
	default: return (GiorniMese[mese]); 
	}
}

function GiornidelMese(mese, anno) {
	if (Bisestile(anno) && (mese == 1)) {
		return (1 + GiornidelMese0(mese, anno))
	} else {
		return (GiornidelMese0(mese, anno))
	}
}

function AnnoCompleto(anno){
	if (anno.value > 0) {
		return anno.value;
	} else {
		return anno.value + ' (' + (1-anno.value) + 'AC)'
	}
}

function MeseCompleto(mese, anno){
	return NomeMese(mese.value-1, anno.value)+ ' ' + AnnoCompleto(anno);
}

function DataCompleta(jd, di, mese, anno){
	var gio = parseInt(jd) + 2;
	return Week[(gio-1)%7] + ' ' + di.value + ' ' + MeseCompleto(mese, anno);
}

function DataCompletaIslam(jd, di, mese, anno){
	var gio = parseInt(jd) + 2
	return Week[(gio-1)%7] + ' ' + di.value + ' ' + MesiIslam[mese.value-1] + ' ' + anno.value;
}

function DataCompletaEbrea(jd, di, mese, anno){
	var gio = parseInt(jd) + 2
	return Week[(gio-1)%7] + ' ' + di.value + ' ' + MesiEbrei[mese.value-1] + ' ' + anno.value;
}

function DataCompletaRF(di, mese, anno){
	return WeekRF[(di.value-1)%10] + ' ' + di.value + ' ' + MesiRF[mese.value-1] + ' ' + anno.value;
}

function MyJDay(xd, xm, xy){
	xm = 1 + ((xm-1) % 12)
	var bisestili = 0
	SelezionaCalendarioDalGiorno(xd, xm, xy);
	switch(TipoCal){
	case 0: bisestili = Math.floor((xy+4711)/4); break;
	case 1: bisestili = 1166 + Math.floor((xy + 47)/3); break;
	case 2: bisestili = 1179; break;
	case 3: bisestili = Math.floor((xy+4711)/4); break;
	case 4: bisestili = Math.floor((xy+4711)/4) - 10;
		secoli = Math.floor((xy-1) / 100);
		while (secoli > 16) {
			if ((secoli % 4) != 0) { bisestili--; }
			secoli--
		};
	};
	var xb = xd;
	xm--;
	while (xm > 0) {
		xb += GiornidelMese(xm-1, xy);
		xm--;
	}
	xy += 4712
	return (xb + xy*365 + bisestili)
}

function GiornoGiuliano(Day, Month, Year, JD){
	var xd = parseInt(Day.value);
	var xm = parseInt(Month.value);
	var xy = parseInt(Year.value);
	SelezionaCalendarioDalGiorno(xd, xm, xy);
	JD.value = MyJDay(xd, xm, xy);
	if ((xm < 1) || (xm > 12)) {
		return -1
	} else if ((xd < 1) || (xd > GiornidelMese(xm-1, xy))) {
		return -2
	} else {
		return 0
	}
}

function CesareJD2GAG(xj, aDay, aYear){
	var xYear = 4664;
	xj = xj - 1703526;
	var xDay  = xj % 1096 - 1;
	xYear += 3*Math.floor(xj/1096)
	if (xDay >= 0) {
		xOlim = Math.floor(xDay/365)
		xYear += xOlim
 		xDay  = xDay % 365 - (xOlim != 0)
	}
	aDay.value = 2 + xDay
	aYear.value = xYear
}

function AugustoJD2GAG(xj, aDay, aYear){
	xj = xj - JDRiformaAugusto0;
	aDay.value   = 1 + xj%365;
	aYear.value = 4706 + Math.floor(xj/365)
}

function GiulianoJD2GAG(xj, aDay, aYear){
	var xDay  = xj % 1461 - 1;
	var xYear = 4*Math.floor(xj/1461)
	if (xDay >= 0) {
		xOlim = Math.floor(xDay/365)
		xYear += xOlim
 		xDay  = xDay % 365 - (xOlim != 0)
	}
	aDay.value = 2 + xDay
	aYear.value = xYear
}

function GregorianoJD2GAG(xj, aDay, aYear){
	xj = xj - 2159351;
	var xDay  = xj % 146097 - 1;
	var xYear = 5912 + 400*Math.floor(xj/146097)
	if (xDay > 364) {
		xj   = xDay
		xDay = 1 + xDay % 36524
	} else { // anno quadrisecolare
		aDay.value = xDay + 2; aYear.value = xYear; return
	}
	xYear += 100*Math.floor(xj/36524)
	if (xDay > 365) {
		xj   = xDay
		xDay = xDay % 1461 - 1
	} else { // anno secolare
		aDay.value = xDay; aYear.value = xYear; return
//	} else {
//		aDay.value = 1; aYear.value = xYear; return
	}
	xYear += 4*Math.floor(xj/1461)
	if (xDay >= 0) {
		xOlim  = Math.floor(xDay/365)
		xYear += xOlim
 		xDay   = xDay % 365 - (xOlim != 0)
		aDay.value = 2 + xDay
	} else {
		aDay.value = 1
	}
	aYear.value = xYear
}

function JD2DayYear(xj, aDay, aYear){
	if (xj < JDRiformaGiuliana) {
		GiulianoJD2GAG(xj, aDay, aYear)
	} else if (xj < JDRiformaAugusto0) {
		CesareJD2GAG(xj, aDay, aYear)
	} else if (xj < JDRiformaAugusto1) {
		AugustoJD2GAG(xj, aDay, aYear)
	} else if (xj < JDRiformaGregoriana) {
		GiulianoJD2GAG(xj, aDay, aYear)
	} else {
		GregorianoJD2GAG(xj, aDay, aYear)
	}
}

function JD2Day(xj){
	aDay  = new String()
	aYear = new String()
	JD2DayYear(xj, aDay, aYear)
	var xDay   = aDay.value
	var xYear  = aYear.value - 4712
	xmonth = 0;
	lmonth = GiornidelMese(xmonth, xYear);
	while (xDay > lmonth) {
		xDay -= lmonth;
		xmonth++
		lmonth = GiornidelMese(xmonth, xYear);
	}
	return xDay
}

function JD2GiornoInt(xj, aDay, aMonth, aYear){
	JD2DayYear(xj, aDay, aYear)
	xDay   = aDay.value
	xYear  = aYear.value - 4712
	xmonth = 0;
	lmonth = GiornidelMese(xmonth, xYear);
	while (xDay > lmonth) {
		xDay -= lmonth;
		xmonth++
		lmonth = GiornidelMese(xmonth, xYear);
	}
	aDay.value = xDay;
	if (xmonth > 11) {xmonth -= 12}
	aMonth.value = xmonth+1;
	aYear.value  = xYear
}

function JD2Giorno(jd, aDay, aMonth, aYear){
	xj  = parseInt(jd.value);
	SelezionaCalendarioDaJD(xj);
	JD2GiornoInt(xj, aDay, aMonth, aYear);
}

function JD2GiornoOra(jd, ore){ 
// ore = 0 solo ore; ore = 1 fino ai minuti; ore = 2 fino ai secondi
	xh     = parseFloat(jd);
	xj     = Math.floor(xh);
	aDay   = new Numero(0); 
	aMonth = new Numero(0); 
	aYear  = new Numero(0);
	JD2GiornoInt(xj, aDay, aMonth, aYear);
	aString = new String()
	aString = DataCompleta(jd, aDay, aMonth, aYear)
//	aString = aDay.value + '/' + aMonth.value + '/' + aYear.value;
	xh     = 24*(xh - xj);
	if (ore == 'h') {return aString + '  ' + Math.round(xh) + 'h'}
	else {
		var aHour= Math.floor(xh);
		aString += '  ' + aHour + '.';
		xh     = 60*(xh - aHour);
		if (ore == 'm') {return aString + Math.round(xh) + "'"}
		else {
			aHour  = Math.floor(xh);
			aString += aHour + "'";
			aHour  = Math.round(60*(xh - aHour));
			return aString + aHour + '"';
		}
	}
}

function Embolismico(anno) {
	ranno = anno % 19;
	return ((ranno == 3)||(ranno == 6)||(ranno == 8)||(ranno == 11)||(ranno == 14)||(ranno == 17)||(ranno == 0));
}

function GiorniMeseEbreo(mese, anno) {
	if (Embolismico(anno)){
		return (GiorniMeseER[mese]);
	} else  {
		return (GiorniMeseOR[mese]);
	}
}

function JD2Ebraico(jd, gio, mes, ann){
	var jis = jd.value - Creazione;
	jis += 0.5
	var trent = Math.floor(jis/Metone);
	var resto = jis % Metone;
	ann.value = trent*19;
	com  = 0;
	nabb = 0;
	abb = AnniEmbolismici[nabb];
	isEmb = 0;
	while (resto > 0){
		isEmb = ++com == abb;
		if (isEmb) {
			ganno = 384; abb = AnniEmbolismici[++nabb];
		} else {
			ganno = 354
		}
		resto -= ganno;
		++ann.value;
	}
	resto += ganno;
	bmese = 0;
	gmese = GiorniMeseEbreo(bmese, ann.value);
	while (resto > gmese) {
		resto -= gmese;
		bmese++;
		gmese = GiorniMeseEbreo(bmese, ann.value);
	}

//	window.alert('mese2='+bmese);
	mes.value = 1 + bmese;
	gio.value = 1 + Math.floor(resto); 
}

function Ebraico2JD(jd, gio, mes, ann){
	anno30 = ann.value % 19;
	var jis = Creazione + Math.floor(ann.value/19)*Metone;
	com  = 0;
	nabb = 0;
	abb = AnniEmbolismici[nabb];
	while (com < anno30){
		if (++com == abb) {ganno = 384; abb = AnniEmbolismici[++nabb];}
		else {ganno = 354}
		jis += ganno;
	} 
	jis -= ganno;
	var xm  = mes.value;
	var xb  = parseInt(gio.value);
	xm--;
	while (xm > 0) {
		xb += GiorniMeseEbreo(xm-1, ann.value);
		xm--;
	}
	jis += xb;
	jd.value = Math.floor(jis-0.5)
//	window.alert('JD4='+jd.value);
}

function JD2Islam(jd, gio, mes, ann){
	var jis = jd.value - Egira;
	jis += 0.5
	var trent = Math.floor(jis/Trentennio);
	var resto = jis % Trentennio;
	ann.value = trent*30;
	com  = 0;
	nabb = 0;
	abb = AnniAbbondanti[nabb];
	while (resto > 0){
		if (++com == abb) {
			ganno = 355; abb = AnniAbbondanti[++nabb];
		} else {
			ganno = 354
		}
		resto -= ganno;
		++ann.value;
	}
	resto += ganno;
	bmese = 2*Math.floor(resto / 59);
	var gior = Math.floor(resto % 59); 
//	window.alert('giorno1='+gior);
	bmese += Math.floor(gior/30);
//	window.alert('mese2='+bmese);
	mes.value = 1 + bmese;
	gio.value = 1 + gior % 30; 
}

function Islam2JD(jd, gio, mes, ann){
	anno30 = ann.value % 30;
	var jis = Egira + Math.floor(ann.value/30)*Trentennio;
	com  = 0;
	nabb = 0;
	abb = AnniAbbondanti[nabb];
	while (com < anno30){
		if (++com == abb) {ganno = 355; abb = AnniAbbondanti[++nabb];}
		else {ganno = 354}
		jis += ganno;
	} 
	jis -= ganno;
	var umese  = mes.value - 1;
	var bimesi = Math.floor(umese/2);
	var umese  = umese % 2;
	jis += bimesi*59;
	jis += umese*30;
	jis += parseInt(gio.value);
	jd.value = Math.floor(jis-0.5)
//	window.alert('JD4='+jd.value);
}

function JD2Rivoluzione(jd, gio, mes, ann){
	var jr = jd.value - InizioRF
	jr += 0.5
	ann.value = parseInt(jr/AnnoRF)
	jr  = jr - ann.value * AnnoRF;
	++ann.value
	gio.value = 1 + parseInt(jr % 30)
	mes.value = 1 + parseInt(jr/30);
}

function Rivoluzione2JD(jd, gio, mes, ann){
	var jr = (ann.value-1)*AnnoRF + InizioRF;
	jr += (mes.value-1)*30
	jr += gio.value-1
	jd.value = parseInt(jr+0.5)
}

function NomiMesi(Tabella, Year) {
	riga = Tabella.insertRow()
	var anno  = parseInt(Year.value);
	var cella = riga.insertCell()
	cella.width = "4%"
	for (ms=0; ms<12;ms++){
		var cella = riga.insertCell()
		cella.width = "8%"
		cella.align = "Center"
		cella.font  = "Arial Narrow"
		cella.style.background = "#EEEE77"
		cella.style.color = "#7777EE"
		cella.innerHTML = '<B>' + NomeMese(ms, anno) + '</B>';
	}
}

function TitoloMese(Tabella, Month, Year) {
	riga = Tabella.insertRow();
	var cella = riga.insertCell();
	cella.colSpan = "8";
	cella.style.background = "#99BBEE";
	cella.style.color = "#000077";
	cella.align = "Center";
	cella.innerHTML = '<B>' + MeseCompleto(Month, Year) + '</B>';
}

function NomiSettimana(Tabella) {
	riga = Tabella.insertRow()
	for (di=0;di<Week.length;di++){
		var cella = riga.insertCell()
		cella.width = "14.28%"
		cella.align = "Center"
		cella.style.background = "#99BBEE";
		cella.style.color = "#000077";
		cella.innerHTML = '<B>' + Week[di] + '</B>';
	}
}

function SettimanaDelMese(Tabella, testa, ultimo, gm) {
	riga = Tabella.insertRow()
	di = 0;
	while (di < testa) {
		cella = riga.insertCell()
		++di
	}
	var prossimo = JD2Day(gm);
	var fase = new Stringa("XX");
	var faseluna = ProssimaFase(gm-0.5, fase);
	faseluna = Math.floor(JD2Day(faseluna)+0.5);
	do {
		cella = riga.insertCell()
		cella.align = "Right"
		if (di == 0) {
			cella.style.color = "Red"
			cella.bgColor = 16768477
		} else {
			cella.style.color = "Navy"
			cella.bgColor = 16777215
		}
		primo = prossimo;
		if (faseluna == primo){
			cella.innerHTML = '<IMG SRC="' +fase.value + '.png" ALIGN="Left">'
		}
		cella.innerHTML += primo.toString();
		++gm
		prossimo = JD2Day(gm);
		++di
	} while ((di < Week.length)&&(primo < prossimo))
	return gm
}

var NumeroRighe = 0;

function TabellaMese(Tabella, Month, Year){
	for (conta=0; conta < NumeroRighe; conta++){
		Tabella.deleteRow(0);
	}
	TitoloMese(Tabella, Month, Year);
	NomiSettimana(Tabella);
	
	var anno  = parseInt(Year.value);
	var mese  = parseInt(Month.value);
	var primo = MyJDay(1, mese, anno);
	var gsett = (primo+1) % 7;
	var ultimo = primo + GiornidelMese(mese-1, anno)
	if ((anno == 1582) && (mese == 10)) {ultimo -= 10}
	var gm = primo;
	NumeroRighe = 2;
	while (gm < ultimo) {
		gm = SettimanaDelMese(Tabella, gsett, ultimo, gm)
		gsett = 0;
		NumeroRighe++
	}
	return primo;
}

function TabellaAnno(Tabella, Year){
	for (conta=0; conta <NumeroRighe; conta++){
		Tabella.deleteRow(0);
	}
	NomiMesi(Tabella, Year);
	NumeroRighe = 1;
	var anno  = parseInt(Year.value);
	var primo = MyJDay(1, 1, anno);
	for (conta=0; conta <31; conta++){
		row  = Tabella.insertRow();
		NumeroRighe++
		cell = row.insertCell();
		cell.innerHTML = conta+1;
		var gio = primo + conta;
		for(ms=0; ms<12; ms++){
			cell = row.insertCell();
			var giosett = (gio+1)%7;
			if (conta < GiornidelMese(ms, Year.value)){
				cell.innerHTML = Week[giosett].substr(0, 3);
				if (giosett == 0) {cell.style.color = "Red"}
			}
			gio += GiornidelMese(ms, Year.value)
		}
	}
}

function QuestoMese(Tabella, Month, Year){
	oggi = new Date()
	Month.value = oggi.getMonth()+1
	Year.value = oggi.getYear()
	return TabellaMese(Tabella, Month, Year);
}

function QuestAnno(Tabella, Month, Year, Titolo){
	oggi = new Date()
	Year.value = oggi.getYear()
	TabellaAnno(Tabella, Year);
}


function IncMese(mese, anno){
	mese.value++
	if (mese.value > 12) {
		mese.value = 1
		++anno.value
	}
}

function DecMese(mese, anno){
	mese.value--
	if (mese.value < 1) {
		mese.value = 12
		--anno.value
	}
}
