﻿/* he_kdate.js based on kdate.js of kaluach
 *
 * kdate.js - Kaluach Javascript Hebrew date routines
 *   Version 1.00
 * 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.
 * Based on the formula by Gauss
 * Terms of use:
 *   - Permission will be granted to use this script on personal
 *     web pages. All that's required is that you please ask.
 *     (Of course if you want to send a few dollars, that's OK too :-)
 *   - Use on commercial web sites requires a $50 payment.
 * website: http://www.kaluach.net
 * email: abumami@kaluach.net
 */

function makeArray() {
	this[0] = makeArray.arguments.length;
	for (i = 0; i < makeArray.arguments.length; i = i + 1)
		this[i+1] = makeArray.arguments[i];
}

var civMonth = new makeArray('ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני',
	'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר');

var weekDay = new makeArray('ראשון', 'שני', 'שלישי', 'רביעי', 'חמישי', 'שישי', 'שבת');

var hebMonth = new makeArray(
			'ניסן', 'אייר', 'סיון', 'תמוז', 'אב', 'אלול',
			'תשרי', 'חשון', 'כסלו', 'טבת', 'שבט',
			'אדר', 'אדר א', 'אדר ב');

var hHebDay = new makeArray(
			'א\'', 'ב\'', 'ג\'', 'ד\'', 'ה\'', 'ו\'', 'ז\'', 'ח\'', 'ט\'', 'י\'',
			'י"א', 'י"ב', 'י"ג', 'י"ד', 'ט"ו', 'ט"ז', 'י"ז', 'י"ח', 'י"ט', 'כ\'',
			'כ"א', 'כ"ב', 'כ"ג', 'כ"ד', 'כ"ה', 'כ"ו', 'כ"ז', 'כ"ח', 'כ"ט', 'ל\'');

var hLinkM = ' ב';

function getHebABC(charNum){
	var curChar = "";
	
	switch(charNum){
		case 1:
			curChar = "א";
			break;
		case 2:
			curChar = "ב";
			break;
		case 3:
			curChar = "ג";
			break;
		case 4:
			curChar = "ד";
			break;
		case 5:
			curChar = "ה";
			break;
		case 6:
			curChar = "ו";
			break;
		case 7:
			curChar = "ז";
			break;
		case 8:
			curChar = "ח";
			break;
		case 9:
			curChar = "ט";
			break;
		case 10:
			curChar = "י";
			break;
		case 20:
			curChar = "כ";
			break;
		case 30:
			curChar = "ל";
			break;
		case 40:
			curChar = "מ";
			break;
		case 50:
			curChar = "נ";
			break;
		case 60:
			curChar = "ס";
			break;
		case 70:
			curChar = "ע";
			break;
		case 80:
			curChar = "פ";
			break;
		case 90:
			curChar = "צ";
			break;
		case 100:
			curChar = "ק";
			break;
		case 200:
			curChar = "ר";
			break;
		case 300:
			curChar = "ש";
			break;
		case 400:
			curChar = "ת";
			break;
		case 500:
			curChar = "תק";
			break;
		case 600:
			curChar = "תר";
			break;
		case 700:
			curChar = "תש";
			break;
		case 800:
			curChar = "תת";
			break;
		case 900:
			curChar = "תתק";
			break;
		default:
			curChar = "";
	}
	return(curChar);
}

function setLastChar(curChar){
	var lastChar = "";
	
	switch(curChar){
		case "כ":
			lastChar = "ך";
			break;
		case "מ":
			lastChar = "ם";
			break;
		case "נ":
			lastChar = "ן";
			break;
		case "פ":
			lastChar = "ף";
			break;
		case "צ":
			lastChar = "ץ";
			break;
		default:
			lastChar = curChar;
	}
	return(lastChar);
}

function hHebYear(year){
	var curChar, curNum, hebYr = "", curDiv = 100;
	
	curNum = (year - (year % 1000)) / 1000;
	year = year % 1000;
	hebYr = hebYr + getHebABC(curNum);
	curNum = 0;
	while(year != 0){
		hebYr = hebYr + getHebABC(curNum);
		curNum = (year - (year % curDiv));
		year = year % curDiv;
		curDiv = curDiv / 10;
	}
	curChar = getHebABC(curNum);
	hebYr = hebYr + '"' + setLastChar(curChar);
	return(hebYr);
}

function Gauss(year) {
	var a,b,c;
	var m;
	var	Mar;	// "day in March" on which Pesach falls (return value)

	a = Math.floor((12 * year + 17) % 19);
	b = Math.floor(year % 4);
	m = 32.044093161144 + 1.5542417966212 * a +  b / 4.0 - 0.0031777940220923 * year;
	if (m < 0)
		m -= 1;
	Mar = Math.floor(m);
	if (m < 0)
		m++;
	m -= Mar;

	c = Math.floor((Mar + 3 * year + 5 * b + 5) % 7);
	if(c == 0 && a > 11 && m >= 0.89772376543210 )
		Mar++;
	else if(c == 1 && a > 6 && m >= 0.63287037037037)
		Mar += 2;
	else if(c == 2 || c == 4 || c == 6)
		Mar++;

	Mar += Math.floor((year - 3760) / 100) - Math.floor((year - 3760) / 400) - 2;
	return Mar;
}

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 civ2heb(day, month, year) {
	var d = day;
	var	m = month;
	var y = year;
	var hy;
	var pesach;
	var anchor;
	var adarType;

	m -= 2;
	if (m <= 0) { // Jan or Feb
		m += 12;
		y -= 1;
	}

	d += Math.floor(7 * m / 12 + 30 * (m - 1)); // day in March
	hy = y + 3760;	// get Hebrew year
	pesach = Gauss(hy);
	if (d <= pesach - 15) { // before 1 Nisan
		anchor = pesach;
		d += 365;
		if(leap(y))
			d++;
		y -= 1;
		hy -= 1;
		pesach = Gauss(hy);
	}
	else
		anchor = Gauss(hy + 1);

	d -= pesach - 15;
	anchor -= pesach - 12;
	y++;
	if(leap(y))
		anchor++;

	for(m = 0; m < 11; m++) {
		var days;
		if(m == 7 && anchor % 30 == 2)
			days = 30; // Cheshvan
		else if(m == 8 && anchor % 30 == 0)
			days = 29; // Kislev
		else
			days = 30 - m % 2;
		if(d <= days)
			break;
		d -= days;
	}

	adarType = 0;			// plain old Adar
	if (m == 11 && anchor >= 30) {
		if (d > 30) {
			adarType = 2;	// Adar 2
			d -= 30;
		}
		else
			adarType = 1;	// Adar 1
	}

	if(m >= 6)		// Tishrei or after?
		hy++;		// then bump up year

	if(m == 11)			// Adar?
		m += adarType;	// adjust for Adars

	return (d + ' ' + m + ' ' + hy);
}


function Easter(Y) {
	// based on the algorithm of Oudin
    var C = Math.floor(Y / 100);
    var N = Y - 19 * Math.floor(Y / 19);
    var K = Math.floor((C - 17) / 25);
    var I = C - Math.floor(C / 4) - Math.floor((C - K) / 3) + 19 * N + 15;
    I = I - 30*Math.floor((I / 30));
    I = I - Math.floor(I / 28) * (1 - Math.floor(I / 28) * Math.floor(29 / (I + 1)) * Math.floor((21 - N) / 11));
    var J = Y + Math.floor(Y / 4) + I + 2 - C + Math.floor(C / 4);
    J = J - 7 * Math.floor(J / 7);
    var L = I - J;
    var M = 3 + Math.floor((L + 40) / 44);
    var D = L + 28 - 31 * Math.floor(M / 4);

	var ret = new Object();
	ret[1] = M;
	ret[2] = D;
	return ret;
}

function DOW(day,month,year) {
	var a = Math.floor((14 - month)/12);
	var y = year - a;
	var m = month + 12*a - 2;
	var d = (day + y + Math.floor(y/4) - Math.floor(y/100) +
			Math.floor(y/400) + Math.floor((31*m)/12)) % 7;
	return d + 1;
}

function NthDOW(nth,weekday,month,year) {
	if (nth > 0)
		return (nth - 1) * 7 + 1 + (7 + weekday - DOW((nth - 1) * 7 + 1, month, year)) % 7;
	var days = civMonthLength(month, year);
	return days - (DOW(days, month, year) - weekday + 7) % 7;
}

function holidays(cday, cmonth, cyear) {
	// American civil holidays and some major religious holiday
	if (cmonth == 1 && cday == 1)
		return "ראש השנה האזרחית";
	else if (cmonth == 2 && cday == 12)
		return "הולדת לינקולן";
	else if (cmonth == 2 && cday == 14)
		return "חג האהבה";
	else if (cmonth == 2 && cday == NthDOW(3, 2, 2, cyear))
		return "יום הנשיא";
	else if (cmonth == 3 && cday == 17)
		return "יום סט. פטריק";
	else if (cmonth == 3 || cmonth == 4) {
		var e = Easter(cyear);
	    if (cmonth == e[1] && cday == e[2])
			return "חג הפסחא";
	}
	else if (cmonth == 5 && cday == NthDOW(2, 1, 5, cyear))
		return "יום האם";
	else if (cmonth == 5 && cday == NthDOW(3, 7, 5, cyear))
		return "Armed Forces Day";
	else if (cmonth == 5 && cday == NthDOW(0, 2, 5, cyear))
		return "יום הזכרון (ארה\"ב)";
	else if (cmonth == 6 && cday == 14)
		return "יום הדגל";
	else if (cmonth == 6 && cday == NthDOW(3, 1, 6, cyear))
		return "יום האב והמשפחה";
	else if (cmonth == 7 && cday == 4)
		return "יום העצמאות (ארה\"ב)";
	else if (cmonth == 9 && cday == NthDOW(1, 2, 9, cyear))
		return "חג העבודה";
	else if (cmonth == 10 && cday == NthDOW(2, 2, 10, cyear))
		return "יום קולומבוס";
	else if (cmonth == 10 && cday == 31)
		return "יום קולומבוס";
	else if (cmonth == 11 && cday == 11)
		return "Veterans' Day";
	else if (cmonth == 11 && cday == NthDOW(4, 5, 11, cyear))
		return "חג ההודיה";
	else if (cmonth == 12 && cday == 25)
		return "חג המולד";

	return "";
}

function moadim(cday, cmonth, cyear, hday, hmonth, dow) {
	if(hmonth == 6) {
		if(hday == 1 || hday == 2)
			return "ראש השנה";
		else if(hday == 3 && dow != 7)
			return "צום גדליה";
		else if(hday == 4 && dow == 1)
			return "צום גדליה";
		else if(hday == 10)
			return "יום כיפור";
		else if(hday >= 15 && hday <= 22)
			return "סוכות";
		else if(hday == 23)
			return "סוכות (ג)";
	}
	else if(hmonth == 8) {
		if(hday >= 25)
			return "חנוכה";
	}
	else if(hmonth == 9) {
		if(hday <= 2) {
			return "חנוכה";
		}
		else if(hday == 3) {
			// Kislev can be malei or chaser
			if(cday == 1) {
				cday = 29;
				cmonth = 11;
			}
			else if(cday == 2) {
				cday = 30;
				cmonth = 11;
			}
			else
				cday -= 3;
			var hdate = civ2heb(cday, cmonth, cyear);
			hd = eval(hdate.substring(0, hdate.indexOf(' ')));
			if(hd == 29)
				return "חנוכה";
		}
		else if(hday == 10)
			return "צום עשרה בטבת";
	}
	else if(hmonth == 10) {
		if(hday==15)
			return "ט\"ו בשבט";
	}
	else if(hmonth == 11 || hmonth == 13) {
		if(hday == 11 && dow == 5)
			return "תענית אסתר";
		else if(hday == 13 && dow != 7)
			return "תענית אסתר";
		else if(hday == 14)
			return "פורים";
		else if(hday == 15)
			return "שושן פורים";
	}
	else if(hmonth == 0) {
		if(hday == 12 && dow == 5)
			return "תענית בכורות";
		else if(hday == 14 && dow != 7)
			return "תענית בכורות";
		else if(hday >= 15 && hday <= 21)
			return "פסח";
		else if(hday == 22)
			return "פסח (ג)";
	}
	else if(hmonth == 1) {
		if(hday == 3 && dow == 5)
			return "יום העצמאות";
		else if(hday == 4 && dow == 5)
			return "יום העצמאות";
		else if(hday == 5 && dow != 6 && dow != 7)
			return "יום העצמאות";
		if(hday == 14)
			return "פסח שני";
		else if(hday == 18)
			return "ל\"ג בעומר";
		if(hday == 28)
			return "יום ירושלים";
	}
	else if(hmonth == 2) {
		if(hday == 6)
			return "שבועות";
		else if(hday == 7)
			return "שבועות (ג)";
	}
	else if(hmonth == 3) {
		if(hday == 17 && dow != 7)
			return "צום י\"ז בתמוז";
		if(hday == 18 && dow == 1)
			return "צום י\"ז בתמוז";
	}
	else if(hmonth == 4) {
		if(hday == 9 && dow != 7)
			return "תשעה באב";
		if(hday == 10 && dow == 1)
			return "תשעה באב";
		if(hday == 15)
			return "ט\"ו באב";
	}
	return "";
}

function get2HD(dd, mm, yy){
	var hebDate = civ2heb(dd, mm, yy);
	var hmS = hebDate.substring(hebDate.indexOf(' ')+1, hebDate.length);
	var hDay = eval(hebDate.substring(0, hebDate.indexOf(' ')));
	var hMonth = eval(hmS.substring(0, hmS.indexOf(' ')));
	var hYear = hmS.substring(hmS.indexOf(' ')+1, hmS.length);
	return(hHebDay[hDay] + hLinkM + hebMonth[hMonth+1] + ' ' + hHebYear(hYear));
}

function get2CD(dd, mm, yy){
	return(dd + "." + mm + "." + yy);
}

function getHebDate(){
	var now = new Date;
	var tday = now.getDate();
	var tmonth = now.getMonth() + 1;
	var tyear = now.getYear();
	if(tyear < 1900)
		// if date from Netscape, then add 1900
		tyear += 1900;
	var hebDate = civ2heb(tday, tmonth, tyear);
	var hmS = hebDate.substring(hebDate.indexOf(' ')+1, hebDate.length);
	var hDay = eval(hebDate.substring(0, hebDate.indexOf(' ')));
	var hMonth = eval(hmS.substring(0, hmS.indexOf(' ')));
	var hYear = hmS.substring(hmS.indexOf(' ')+1, hmS.length);
	return(hHebDay[hDay] + hLinkM + hebMonth[hMonth+1] + ' ' + hHebYear(hYear));
}



