///////////////////////////////////////////////////////////////////
// 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
// -----------------

var weekday=new Array(7)
weekday[0]="ראשון";
weekday[1]="שני";
weekday[2]="שלישי";
weekday[3]="רביעי"
weekday[4]="חמישי";
weekday[5]="ששי";
weekday[6]="שבת";

 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,'year<2005&&dow==1','צום גדליה (נדחה)','sadday'),
		new Holiday( 4,1,'year>2004&&dow==1','צום גדליה (נדחה)<br><span class="info">שעון חורף</span>','sadday'),
		new Holiday( 6,1,'year>2004&&dow==1','שעון חורף','info'),
		new Holiday( 7,1,'year>2004&&dow==1','שעון חורף','info'),
		new Holiday( 9,1,'year>2004&&dow==1','שעון חורף','info'),
		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( 12,11,'year>2004','גירוש יהודי קטיף','katif'),
		// אדר א
		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 ;

	// Summer time
	var sSummer = ( dow==6 && year>2004 && ((g.getMonth()==3 && g.getDate()==1)||(g.getMonth()==2 && g.getDate() >25)) ) ?
		'<span class="info">שעון קיץ</span>' : '' ;

	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))
		{
			if(sSummer) Holidays[i].description += '<br>' + sSummer ;
			return Holidays[i] ;
		}
	}
	return sSummer ;
}

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 ;
}