var J0000 = 1721424.5;                // Julian date of Gregorian epoch: 0000-01-01
var J1970 = 2440587.5;                // Julian date at Unix epoch: 1970-01-01
var JMJD  = 2400000.5;                // Epoch of Modified Julian Date system
var J1900 = 2415020.5;                // Epoch (day 1) of Excel 1900 date system (PC)
var J1904 = 2416480.5;                // Epoch (day 0) of Excel 1904 date system (Mac)

var NormLeap = new Array("Normal year", "Leap year");
function toHebrewConvert (dateE) {
	
	return "Adar 33, 5765"
}

var J0000 = 1721424.5;                // Julian date of Gregorian epoch: 0000-01-01
var J1970 = 2440587.5;                // Julian date at Unix epoch: 1970-01-01
var JMJD  = 2400000.5;                // Epoch of Modified Julian Date system
var J1900 = 2415020.5;                // Epoch (day 1) of Excel 1900 date system (PC)
var J1904 = 2416480.5;                // Epoch (day 0) of Excel 1904 date system (Mac)

var NormLeap = new Array("Normal year", "Leap year");
var hebrewMonth = new Array("Nisan","Iyar","Sivan","Tammuz","Av","Elul","Tishrei","Heshvan","Kislev","Teveth","Shevat","Adar","Adar II");
var hebrewMonthH = new Array("ניסן", "אייר", "סיון", "תמוז", "אב", "אלול", "תשרי", "חשון", "כסלו", "טבת", "שבט", "אדר", "אדר ב'")
function search_weekday(weekday, jd, direction, offset)
{
    return weekday_before(weekday, jd + (direction * offset));
}
function leap_julian(year)
{
    var tst = year%4;// mod(year,4);
    return (tst == ((year > 0) ? 0 : 3));
}


//  Utility weekday functions, just wrappers for search_weekday

function nearest_weekday(weekday, jd)
{
    return search_weekday(weekday, jd, 1, 3);
}

function next_weekday(weekday, jd)
{
    return search_weekday(weekday, jd, 1, 7);
}

function next_or_current_weekday(weekday, jd)
{
    return search_weekday(weekday, jd, 1, 6);
}

function previous_weekday(weekday, jd)
{
    return search_weekday(weekday, jd, -1, 1);
}

function previous_or_current_weekday(weekday, jd)
{
    return search_weekday(weekday, jd, 1, 0);
}
//  LEAP_GREGORIAN  --  Is a given year in the Gregorian calendar a leap year ?

function leap_gregorian(year)
{
    return ((year % 4) == 0) &&
            (!(((year % 100) == 0) && ((year % 400) != 0)));
}

/*  JD_TO_HEBREW  --  Convert Julian date to Hebrew date
                      This works by making multiple calls to
                      the inverse function, and is this very
                      slow.  */

function jd_to_hebrew(jd)
{
    var year, month, day, i, count, first;

    jd = Math.floor(jd) + 0.5;
    count = Math.floor(((jd - HEBREW_EPOCH) * 98496.0) / 35975351.0);
    year = count - 1;
    for (i = count; jd >= hebrew_to_jd(i, 7, 1); i++) 
    {
        year++;
    }
    first = (jd < hebrew_to_jd(year, 1, 1)) ? 7 : 1;
    month = first;
    for (i = first; jd > hebrew_to_jd(year, i, hebrew_month_days(year, i)); i++) 
    {
        month++;
    }
    day = (jd - hebrew_to_jd(year, month, 1)) + 1;
    return new Array(year, month, day);
}

function gematriya (n) {
	//handle numbers 1 to 499
	var ones = "אאבגדהוזחט"
	var tens = "ייכלמנסעפצ"
	var hundreds = "קקרשת"
	var result = ""
	var myMod

	myMod = n % 10
	if (myMod) {
		result += ones.substring(myMod, myMod + 1)
		n -= myMod
	}

	myMod = n % 100
	if (myMod) {
		result = tens.substring(myMod/10, myMod/10 + 1) + result
		if (result == "יה")
			result = "טו"
		else if (result == "יו")
			result = "טז"
		n -= myMod
	}

	n /= 100
	if (n)
		result = hundreds.substring(n, n + 1) + result

	return result
}

function updateFromGregorian(dayofweek, mday, mon, year, lang)
{
	//for some reason, this function assumes that mon will be one month behind the current month
	//maybe because of array indexes. So we subtract one from month to get the correct month to 
	//show up.
	mon--;
    var j, hour, min, sec,
        weekday, julcal, hebcal, islcal, hmindex, utime, isoweek,
        may_countcal, mayhaabcal, maytzolkincal, bahcal, frrcal,
        indcal, isoday, xgregcal;
	mday = new Number(mday);
	mon = new Number(mon);
	year = new Number(year);
	hour=min=sec=0;
    //  Update Julian day
	var julianday, modifiedjulianday;
    j = gregorian_to_jd(year, mon + 1, mday) +
           (Math.floor(sec + 60 * (min + 60 * hour) + 0.5) / 86400.0);
	julianday = j;
	modifiedjulianday = j-JMJD;

    //  Update leap year status in Gregorian box
	var gregorianLeap = NormLeap[leap_gregorian(year)?1:0];

    //  Update Julian Calendar

    julcal = jd_to_julian(j);
	var julianCalendarYear, julianCalendarMonth, julianCalendarDay, julianCalendarLeap;
    julianCalendarYear = julcal[0];
    julianCalendarMonth=julcal[1]-1;
    julianCalendarDay = julcal[2];
    julianCalendarLeap = NormLeap[leap_julian(julcal[0])?1:0];
    //  Update Hebrew Calendar

    hebcal = jd_to_hebrew(j);
    if (hebrew_leap(hebcal[0])) 
    {
		hebrewMonth[11] = "Adar I";
		hebrewMonthH[11] = "אדר א'";
		//hebrewMonth[12] = "Adar II";
    } 
    else 
    {
		hebrewMonth[11]="Adar";
		hebrewMonthH[11]="אדר";
    }
    var hebDate
	var days = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")
	var daysH = new Array("ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת")
	if (lang = "hebrew") {
	    hebDate = "יום"  + " " + daysH[dayofweek] + " " + gematriya(hebcal[2]) + " " + hebrewMonthH[hebcal[1]-1] + ", " + "ת" + gematriya(hebcal[0] - 5400) ;
	}
	else {
	    hebDate =hebcal[2] + " " + hebrewMonth[hebcal[1]-1] + ", " + hebcal[0] ;
	}
    hmindex = hebcal[1];
//  HEBREW_TO_JD  --  Determine Julian day from Hebrew date
    return hebDate;
}
var HEBREW_EPOCH = 347995.5;

//  Is a given Hebrew year a leap year ?

function hebrew_leap(year)
{
    return (((year * 7) + 1)%19) < 7;
}

//  How many months are there in a Hebrew year (12 = normal, 13 = leap)

function hebrew_year_months(year)
{
    return hebrew_leap(year) ? 13 : 12;
}

//  Test for delay of start of new year and to avoid
//  Sunday, Wednesday, and Friday as start of the new year.

function hebrew_delay_1(year)
{
    var months, days, parts;

    months = Math.floor(((235 * year) - 234) / 19);
    parts = 12084 + (13753 * months);
    day = (months * 29) + Math.floor(parts / 25920);

    if (((3 * (day + 1))% 7) < 3) {
        day++;
    }
    return day;
}

//  Check for delay in start of new year due to length of adjacent years

function hebrew_delay_2(year)
{
    var last, present, next;

    last = hebrew_delay_1(year - 1);
    present = hebrew_delay_1(year);
    next = hebrew_delay_1(year + 1);

    return ((next - present) == 356) ? 2 :
                                     (((present - last) == 382) ? 1 : 0);
}

//  How many days are in a Hebrew year ?

function hebrew_year_days(year)
{
    return hebrew_to_jd(year + 1, 7, 1) - hebrew_to_jd(year, 7, 1);
}

//  How many days are in a given month of a given year

function hebrew_month_days(year, month)
{
    //  First of all, dispose of fixed-length 29 day months

    if (month == 2 || month == 4 || month == 6 ||
        month == 10 || month == 13) {
        return 29;
    }

    //  If it's not a leap year, Adar has 29 days

    if (month == 12 && !hebrew_leap(year)) {
        return 29;
    }

    //  If it's Heshvan, days depend on length of year

    if (month == 8 && !((hebrew_year_days(year)% 10) == 5)) {
        return 29;
    }

    //  Similarly, Kislev varies with the length of year

    if (month == 9 && ((hebrew_year_days(year)% 10) == 3)) {
        return 29;
    }

    //  Nope, it's a 30 day month

    return 30;
}

//  Finally, wrap it all up into...

function hebrew_to_jd(year, month, day)
{
    var jd, mon, months;

    months = hebrew_year_months(year);
    jd = HEBREW_EPOCH + hebrew_delay_1(year) +
         hebrew_delay_2(year) + day + 1;

    if (month < 7) {
        for (mon = 7; mon <= months; mon++) {
            jd += hebrew_month_days(year, mon);
        }
        for (mon = 1; mon < month; mon++) {
            jd += hebrew_month_days(year, mon);
        }
    } else {
        for (mon = 7; mon < month; mon++) {
            jd += hebrew_month_days(year, mon);
        }
    }

    return jd;
}
//  GREGORIAN_TO_JD  --  Determine Julian day number from Gregorian calendar date

var GREGORIAN_EPOCH = 1721425.5;

function gregorian_to_jd(year, month, day)
{
    return (GREGORIAN_EPOCH - 1) +
           (365 * (year - 1)) +
           Math.floor((year - 1) / 4) +
           (-Math.floor((year - 1) / 100)) +
           Math.floor((year - 1) / 400) +
           Math.floor((((367 * month) - 362) / 12) +
           ((month <= 2) ? 0 :
                               (leap_gregorian(year) ? -1 : -2)
           ) +
           day);
}

//  calcGregorian  --  Perform calculation starting with a Gregorian date

function calcGregorian()
{
    updateFromGregorian();
}
//  JD_TO_JULIAN  --  Calculate Julian calendar date from Julian day

function jd_to_julian(td) {
    var z, a, alpha, b, c, d, e, year, month, day;

    td += 0.5;
    z = Math.floor(td);

    a = z;
    b = a + 1524;
    c = Math.floor((b - 122.1) / 365.25);
    d = Math.floor(365.25 * c);
    e = Math.floor((b - d) / 30.6001);

    month = Math.floor((e < 14) ? (e - 1) : (e - 13));
    year = Math.floor((month > 2) ? (c - 4716) : (c - 4715));
    day = b - d - Math.floor(30.6001 * e);

    /*  If year is less than 1, subtract one to convert from
        a zero based date system to the common era system in
        which the year -1 (1 B.C.E) is followed by year 1 (1 C.E.).  */

    if (year < 1) {
        year--;
    }

    return new Array(year, month, day);
}