﻿
///////////////////////////////////////////////////////////////////
// Start of hdate.js (you can copy this section to a separate file
///////////////////////////////////////////////////////////////////
// All rights reserved to Elyasaf Movshovitz and Amos Shapir.
// Code may be used freely with keeping copitight messages.
 
 
// General functions
// -----------------
 
 function div( a, b )
 {
 	return Math.floor(a/b) ;
 }
 
function Gimatria(n)
{
	var p = '' ;
	var quf = 'קרש' ;
	var yud = 'יכלמנסעפצ' ;
	var alef = 'אבגדהוזחט' ;
 
	if ( n > 1000 )
	{
		p += Gimatria( div(n,1000)) ;
		n %= 1000 ;
	}
 
	while (n >= 400)
	{
		p += 'ת' ;
		n -= 400 ;
	}
 
	if (n >= 100)
	{
		p += quf.charAt( div(n,100) - 1 ) ;
		n %= 100 ;
	}
 
	if ( n >= 10 )
	{
		switch( n )
		{
			case 15:
				p += 'טו' ; n = 0 ;
				break ;
			case 16:
				p += 'טז' ; n = 0 ;
				break ;
			default:
				p += yud.charAt ( div(n,10) - 1 ) ;
				break ;
		}
		n %= 10 ;
	}
 
	if (n > 0)  p += alef.charAt(n-1) ;
 
	if ( p.length == 1 )
		p += "'" ;
	else
		p = p.slice( 0, p.length - 1) + '"' + p.charAt( p.length-1 ) ;
 
	return p ;
}
 
// Holidays functions
// ------------------
	function HolidayToString()
	{
		return this.description ;
	}
 
	// Holiday object Constructor
	function Holiday(day,month,condition,description,type)
	{
		this.day = day ;
		this.month = month ;
		this.condition = condition ;
		this.description = description ;
		this.holiday_type= type ? type : 'holiday' ;
		this.toString = HolidayToString ;
	}
 
	function CheckHanuka(gg)
	{
		var g = new Date(gg) ;
		g.setDate( g.getDate()-3 ) ;
		var h = new HebrewDate ;
		h.convertGregorian(g) ;
		return h.hd_day == 28 ;
	}
 
	// Day, Month, Condition, Description, Style
	var Holidays = Array(
		// תשרי
		new Holiday( 1,1,1,'ראש השנה','yomtov' ),
		new Holiday( 2,1,1,'ראש השנה','yomtov' ),
		new Holiday( 3,1,'dow!=7','צום גדליה','sadday'),
		new Holiday( 4,1,'dow==1','צום גדליה (נדחה)','sadday'),
		new Holiday( 10,1,1,'יום כיפור','yomtov'),
		new Holiday( 15,1,1,'סוכות','yomtov'),
		new Holiday( 16,1,1,'א דחוה"מ'),
		new Holiday( 17,1,1,'ב דחוה"מ'),
		new Holiday( 18,1,1,'ג דחוה"מ'),
		new Holiday( 19,1,1,'ד דחוה"מ'),
		new Holiday( 20,1,1,'ה דחוה"מ'),
		new Holiday( 21,1,1,'הושענא רבה'),
		new Holiday( 22,1,1,'שמחת תורה','yomtov'),
		// כסליו
		new Holiday( 25,3,1,'חנוכה'),
		new Holiday( 26,3,1,'חנוכה'),
		new Holiday( 27,3,1,'חנוכה'),
		new Holiday( 28,3,1,'חנוכה'),
		new Holiday( 29,3,1,'חנוכה'),
		new Holiday( 30,3,1,'חנוכה'),
		// טבת
		new Holiday( 1,4,1,'חנוכה'),
		new Holiday( 2,4,1,'חנוכה'),
		new Holiday( 3,4,'CheckHanuka(g)','חנוכה'),
		new Holiday( 10,4,1,'צום עשרה בטבת','sadday'),
		// שבט
		new Holiday( 15,5,1,'ראש השנה לאילנות'),
		// אדר
		new Holiday( 11,6,'dow==5','תענית אסתר (מוקדם)','sadday'),
		new Holiday( 13,6,'dow!=7','תענית אסתר','sadday'),
		new Holiday( 14,6,1,'פורים'),
		new Holiday( 15,6,1,'שושן פורים'),
		new Holiday( 16,6,'dow==1','שושן פורים (משולש)'),
		// ניסן
		new Holiday( 15,7,1,'פסח','yomtov'),
		new Holiday( 16,7,1,'א דחוה"מ'),
		new Holiday( 17,7,1,'ב דחוה"מ'),
		new Holiday( 18,7,1,'ג דחוה"מ'),
		new Holiday( 19,7,1,'ד דחוה"מ'),
		new Holiday( 20,7,1,'ה דחוה"מ'),
		new Holiday( 21,7,1,'שביעי של פסח','yomtov'),
		new Holiday( 26,7,'(year>1958)&&(dow=5)','יום השואה (מוקדם)','sadday'),
		new Holiday( 27,7,'(year>1958)&&(dow<6)&&(dow>1)','יום השואה','sadday'),
		new Holiday( 28,7,'(year>1958)&&(dow==2)','יום השואה (נדחה)','sadday'),
		// אייר
		new Holiday( 2,8,'(year>1948)&&(dow==4)','יום הזכרון (מוקדם)','sadday'),
		new Holiday( 3,8,'(year>1948)&&(dow==4)','יום הזכרון (מוקדם)','sadday'),
		new Holiday( 3,8,'(year>1948)&&(dow==5)','יום העצמאות (מוקדם)'),
		new Holiday( 4,8,'((year>1948)&&(year<2004)&&(dow<5))||((year>2003)&&(dow==3))','יום הזכרון','sadday'),
		new Holiday( 4,8,'year>1948&&dow==5','יום העצמאות (מוקדם)'),
		new Holiday( 5,8,'(year>1948&&year<2004&&dow<6)||(year>2003&&dow==4)','יום העצמאות'),
		new Holiday( 5,8,'year>2003&&dow==2','יום הזכרון (נדחה)','sadday'),
		new Holiday( 6,8,'year>2003&&dow==3','יום העצמאות (נדחה)'),
		new Holiday( 18,8,1,'ל"ג בעומר'),
		new Holiday( 28,8,'year>1966','יום שחרור ירושלים'),
		// סיוון
		new Holiday( 6,9,1,'שבועות','yomtov'),
		// תמוז
		new Holiday( 17,10,'dow!=7','צום י"ז בתמוז','sadday'),
		new Holiday( 18,10,'dow==1','צום י"ז בתמוז (נדחה)','sadday'),
		// אב
		new Holiday( 9,11,'dow!=7','תשעה באב','sadday'),
		new Holiday( 10,11,'dow==1','תשעה באב (נדחה)','sadday'),
		// אדר א
		new Holiday( 14,13,1,'פורים קטן'),
		new Holiday( 15,13,1,'שושן פורים קטן'),
		// אדר ב
		new Holiday( 11,14,'dow==5','תענית אסתר (מוקדם)','sadday'),
		new Holiday( 13,14,'dow!=7','תענית אסתר','sadday'),
		new Holiday( 14,14,1,'פורים'),
		new Holiday( 15,14,1,'שושן פורים'),
		new Holiday( 16,14,'dow==1','שושן פורים (משולש)')
	) ;
 
// Computing Hebrew Date
// ---------------------
 
 /* constants, in 1/18th of minute */
 var HOUR = 1080 ;
 var DAY  = (24*HOUR) ;
 var WEEK = (7*DAY) ;
 function M(h,p) {return ((h)*HOUR+p) ; }
 var MONTH = (DAY+M(12,793)) ;
 
 /* no. of days in y years */
 function dysiz( y )
 {
	var m, nm, dw, s, l ;
 
	l = y*7+1;	/* no. of leap months */
	m = y*12+ div(l,19);	/* total no. of months */
	l %= 19 ;
	nm = m*MONTH+M(1+6,779); /* molad new year 3744 (16BC) + 6 hours */
	s = m*28+div(nm,DAY)-2;
 
	nm %= WEEK;
	dw = div(nm,DAY);
	nm %= DAY;
 
	/* special cases of Molad Zaken */
	if(l < 12 && dw==3 && nm>=M(9+6,204) ||
	 l < 7 && dw==2 && nm>=M(15+6,589))
		s++,dw++;
	/* ADU */
	if(dw == 1 || dw == 4 || dw == 6)
		s++;
	return s;
 }
 
 /*
  | compute date structure from no. of days since 1 Tishrei 3744
  */
function hdate ( d, m, y )
 {
	var h = new HebrewDate ;
	var s;
 
	if((m -= 2) <= 0)
	{
		m += 12;
		y--;
	}
	/* no. of days, Julian calendar */
	d += (365*y) + div(y,4) + div(367*m,12) + 5968 ;
	/* Gregorian calendar */
	d -= div(y,100)-div(y,400)-2;
	h.hd_dw = (d+1)%7;
 
	/* compute the year */
	y += 16;
	s = dysiz(y);
	m = dysiz(y+1);
	while(d >= m) /* computed year was underestimated */
	{
		s = m;
		y++;
		m = dysiz(y+1);
	}
	d -= s;
	s = m-s;	/* size of current year */
	y += 3744;
 
	h.hd_flg = s%10-4;
 
	/* compute day and month */
	if(d >= s-236) {	/* last 8 months are regular */
		d -= s-236;
		m = div(d*2,59) ;
		d -= div((m*59+1),2);
		m += 4;
		if(s>365 && m<=5)	/* Adar of Meuberet */
			m += 8;
	} else {
		/* first 4 months have 117-119 days */
		s = 114+s%10;
		m = div(d*4,s);
		d -= div((m*s+3),4) ;
	}
 
	h.hd_day = d;
	h.hd_mon = m;
	h.hd_year = y;
	h.hd_leap = ( s > 365 ) ;
	return h ;
 }
 
// HebrewDate object
// -----------------
 
function HDHoliday()
{
	var dow = this.hd_dw + 1 ;
	var year = this.gregorian.getFullYear() ;
	var g = this.gregorian ;
 
	var i ;
	for ( i = 0 ; i < Holidays.length ; i++ )
	{
		if ( Holidays[i].month == this.hd_mon+1 && Holidays[i].day == this.hd_day+1 && eval(Holidays[i].condition))
			return Holidays[i] ;
	}
	return null ;
}
 
function HDToString()
{
	var monthes = new Array( 'תשרי','חשון','כסליו','טבת','שבט','אדר','ניסן','אייר','סיון','תמוז','אב','אלול','אדר א\'' , 'אדר ב\'') ;
	var s = this.format ;
	s = s.replace ( 'DD', Gimatria(this.hd_day+1) ) ;
	s = s.replace ( 'MM', monthes[this.hd_mon] ) ;
	s = s.replace ( 'YYYY', Gimatria(this.hd_year) ) ;
	return s ;
}
 
function HDGtoH(d)
{
	var h = hdate( d.getDate(), d.getMonth()+1, d.getFullYear() ) ;
	this.hd_day = h.hd_day ;
	this.hd_mon = h.hd_mon ;
	this.hd_year = h.hd_year ;
	this.hd_leap = h.hd_leap ;
	this.hd_dw = h.hd_dw ;
	this.hd_flg = h.hd_flg ;
	this.gregorian = d ;
}
 
function HDSetDate(n)
{
	this.gregorian.setDate( n + (this.gregorian.getDate() - this.hd_day ) ) ;
	this.convertGregorian( this.gregorian ) ;
}
 
// HebrewDate constructor
function HebrewDate()
{
	this.hd_day = 0 ;
	this.hd_mon = 0 ;
	this.hd_year = 0 ;
	this.hd_leap = 0 ;
	this.hd_dw = 0 ;
	this.hd_flg = 0 ;
	this.format = 'DD MM YYYY' ;
	this.toString = HDToString ;
	this.convertGregorian = HDGtoH ;
	this.getHoliday = HDHoliday ;
	this.gregorian = new Date() ;
	this.setDate = HDSetDate ;
}
 
////////////////////////////////////////////////////////////////////////////////////////////////////
// End of hdate.js
////////////////////////////////////////////////////////////////////////////////////////////////////
 
 
// This calendar specific functions
// --------------------------------
 
function DisplayHoliday( h )
{
	if (!h) return '&nbsp;' ;
	return '<span class="' + h.holiday_type + '">' + h + '</span>' ;
	return '' ;
}
 
function init()
{
	var arrMonthes = Array( "ינואר", "פברואר", "מרץ", "אפריל", "מאי", "יוני", "יולי", "אוגוסט", "ספטמבר", "אוקטובר", "נובמבר", "דצמבר" ) ;
	var t = document.getElementById('grid') ;
	var myNewRow = t.insertRow(0) ;
 
	var td = myNewRow.insertCell(0) ;
	for ( i = 0 ; i < 37 ; i++ )
	{
		td = myNewRow.insertCell(i+1) ;
		td.align='center' ;
		td.className = 'daytitle' ;
		td.innerHTML = 'אבגדהוש'.charAt(i%7) ;
	}
 
	//--------------------------------------------------------------
	for ( i = 0 ; i < 13 ; i++ )
	{
		myNewRow = t.insertRow(i+1) ;
		var td = myNewRow.insertCell(0) ;
		td.className= 'monthtitle' ;
		td.align='center' ;
		for ( j = 0 ; j < 37 ; j++ )
		{
			td = myNewRow.insertCell(j+1) ;
			td.align='center' ;
			td.valign='center' ;
			td.width=27 ;
			if ( (j+1) % 7 == 0 ) td.className = 'saturday' ;
			td.innerHTML="&nbsp;" ;
		}
	}
	for ( i = 0 ; i < myNewRow.cells.length ; i++ )
	{
		myNewRow.cells[i].style.borderBottom = '1pt solid navy' ;
	}
	//--------------------------------------------------------------
 
	var themonth ;
	var h = new HebrewDate ;
	var d = new Date ;
	var theyear = d.getFullYear() ;
	h.convertGregorian(d) ;
	if ( h.hd_year - theyear == 3760 ) theyear-- ;
 
	// Read command line (query string)
	var sLocation = String(location) ;
	var yStart = sLocation.indexOf("year=")
	if ( yStart >= 0 )
	{
		var tmp = sLocation.slice(yStart+5,yStart+9)
		theyear = Number(tmp) ;
		theyear-- ;
	}
 
	if ( theyear < 100 )
	{
		alert ( "לא ניתן לצפות בשנים מתחת למאה לספירה" )
		theyear = 100 ;
	}
 
	d.setYear( theyear ) ;
	d.setMonth(10) ;
	h.convertGregorian(d) ;
	h.format = 'YYYY' ;
	document.getElementById('title').innerHTML = 'לוח שנה לשנת ' + h ;
 
	document.forms[0].year.value = theyear+1 ;
 
	for ( row = 0 ; row < 13 ; row++ )
	{
		themonth = (row+8) % 12  ;
		if ( themonth == 0 ) theyear++ ;
		d.setDate(1) ;
		d.setMonth(themonth) ;
		d.setYear(theyear) ;
 
		h.format = 'MM - ' ;
		h.convertGregorian(d) ;
		// Can be two Hebrew monthes
		var nFirstHebrewMonth = h.hd_mon ;
		var sFirstHebrewMonth = h.toString() ;
		h.format = 'MM' ;
		d.setMonth( themonth + 1 ) ; // means next month!
		d.setDate(-1) ; // Last day in this month
		h.convertGregorian(d) ;
 
		t.rows[row+1].cells[0].innerHTML = arrMonthes[themonth]
			+ '<br>\n<span class="hebrewmonthtitle"><nobr>'
			+ ((h.hd_mon == nFirstHebrewMonth) ? h : (sFirstHebrewMonth + h )) + '</nobr></span>' ;
 
		d.setDate(1) ;
		d.setMonth(themonth) ;
 
		h.format = 'DD' ;
 
		var col = d.getDay() + 1 ;
 
		while ( d.getMonth() == themonth )
		{
			h.convertGregorian(d) ;
			t.rows[row+1].cells[col++].innerHTML =
				 '<span class="number">' + d.getDate() + '</span><br>' + h + '<br>' + DisplayHoliday(h.getHoliday()) ;
			//if (d.getDay() == 6) week++ ;
			d.setDate( d.getDate()+1 ) ;
		}
	}
 
	for ( i = 0 ; i < 200 ; i++ )
	{
		var hy = document.getElementById('hyearselect') ;
		var elm = document.createElement( 'OPTION' ) ;
		hy.options.add(elm) ;
		elm.value = (1900 + i) ;
		elm.innerHTML  = Gimatria ( 5660 + i ) ;
		if ( theyear == 1900+i ) elm.selected=true ;
	}
}