// JavaScript Holiday Functions
//
// Author:  Rick Pike
// Website: http://calendar.pikesys.com
// Email: calendar@pikesys.com
//
// adapted to work with calendar from code by Martin Webb (http://www.irt.org)
// 
// additional functions to calculate Easter and other Christian holidays dates are available at www.irt.org
// additional functions to calculate Easter and Jewish holidays are available at www.kaluach.net
//
// A reference (and on-line calculator) for American holidays is at http://www.smart.net/~mmontes/ushols.html by Marcos J. Montes
//
// YOU SHOULD CONFIRM THAT THE CALCULATED DATES ARE CORRECT
//
// Permission is granted to use my adaptations in this script as long as the above information is included
//
// Instructions:
//	To get a list of American holidays whose dates vary for a given year, call "calcHolidays(year)" in your JavaScript
//           To get an appropriate text string for a given date, call "holidays(day, month, year)" in your JavaScript

function DayOfWeek(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 makeArray()    {
    this[0] = makeArray.arguments.length;
    for (i = 0; i<makeArray.arguments.length; i++)
        this[i+1] = makeArray.arguments[i];
}

var daysofmonth   = new makeArray( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
var daysofmonthLY = new makeArray( 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
var accumulate    = new makeArray(  0, 31, 59, 90,120,151,181,212,243,273,304,334);
var accumulateLY  = new makeArray(  0, 31, 60, 91,121,152,182,213,244,274,305,335);

function LeapYear(year) {
    if ((year/4)   != Math.floor(year/4))   return false;
    if ((year/100) != Math.floor(year/100)) return true;
    if ((year/400) != Math.floor(year/400)) return false;
    return true;
}

function NthDay(nth,weekday,month,year) {
    if (nth > 0) return (nth-1)*7 + 1 + (7 + weekday - DayOfWeek((nth-1)*7 + 1,month,year))%7;
    var days = ( LeapYear(year) ? daysofmonthLY[month] : daysofmonth[month] );
    return days - (DayOfWeek(days,month,year) - weekday + 7)%7;
}

var sun=1,mon=2,tue=3,wed=4,thu=5,fri=6,sat=7;
var jan=1,feb=2,mar=3,apr=4,may=5,jun=6,jul=7,aug=8,sep=9,oct=10,nov=11,dec=12;
var first=1,second=2,third=3,fourth=4,fifth=5,last=-1;

var daysofweek   = new makeArray('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
var monthsofyear = new makeArray('January','February','March','April','May','June','July','August','September','October','November','December');

function DayOfWeek(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 Nths(day) { 
    if (day == 1 || day == 21 || day == 31) return 'st';
    if (day == 2 || day == 22) return 'nd';
    if (day == 3 || day == 23) return 'rd';
    return 'th';
}

function FullDate(day,month,year) {
    return daysofweek[DayOfWeek(day,month,year)] +' '+ day + Nths(day) +' '+ monthsofyear[month] +' '+ year;
}

function Easter(Y) {
    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 addDays(day,month,year,addition) {
    var number = day + addition + ( LeapYear(year) ? accumulateLY[month] : accumulate[month] );

    var days = daysinyear(year);
   
    while (number > days) {
        number -= days;
        days = daysinyear(++year);
    }

    while (number < 1) {
        days = daysinyear(--year);
        number += days;
    }

    month = 1;

    if (LeapYear(year)) {
        while (number > accumulateLY[month]) { month++; }
        day = number - accumulateLY[--month];
    } else {
        while (number > accumulate[month]) { month++; }
        day = number - accumulate[--month];
    }

    var ret = new Object();
    ret[1] = month;
    ret[2] = day;
    return ret;
}

function daysinyear(year) { if (LeapYear(year)) return 366; else return 365; }

function calcHolidays(year) {
	document.write("BC Day - " + FullDate(NthDay(first,mon,aug,year),aug,year) + '<BR>');
	document.write("Labor Day - " + FullDate(NthDay(first,mon,sep,year),sep,year) + '<BR>');
	document.write("Thanksgiving Day - " + FullDate(NthDay(second,mon,oct,year),oct,year) + '<BR>');
	document.write("Victoria Day - " + FullDate(NthDay(third,mon,may,year),may,year) + '<BR>');
	document.write("Mother's Day - " + FullDate(NthDay(second,sun,may,year),may,year) + '<BR>');	
	document.write("Father's Day - " + FullDate(NthDay(third,sun,jun,year),jun,year) + '<BR>');
	
}

function holidays(cday, cmonth, cyear) {
	// Civil holidays and some major religious holiday
	if (cmonth == 1 && cday == 1)
		return "New Year's Day";
	else if (cmonth == 5 && cday == NthDay(second, sun, cmonth, cyear))
		return "Mother's Day";
	else if (cmonth == 6 && cday == NthDay(third, sun, cmonth, cyear))
		return "Father's Day";
	else if (cmonth == 7 && cday == 1)
		return "Canada Day";
	else if (cmonth == 9 && cday == NthDay(first, mon, cmonth, cyear))
		return "Labor Day";
	else if (cmonth == 11 && cday == 11)
		return "Remembrance Day";
	else if (cmonth == 10 && cday == NthDay(second, mon, cmonth, cyear))
		return "Thanksgiving";
	else if (cmonth == 12 && cday == 25)
		return "Christmas";
	else if (cmonth == 12 && cday == 26)
		return "Boxing Day";
	else if (cmonth == 5 && cday == 23)
		return "Victoria Day";
	else if (cmonth == 8 && cday == NthDay(first, mon, cmonth, cyear))
		return "BC Day";

//change or add every year
	else if (cmonth == 8 && cday == 31 && cyear == 2011)
		return "Welcome Back day";
	else if (cmonth == 9 && cday == 1 && cyear == 2011)
		return "Welcome Back day";
	else if (cmonth == 9 && cday == 2 && cyear == 2011)
		return "Welcome Back day";
	else if (cmonth == 10 && cday == 21 && cyear == 2011)
		return "Pro D Day";
	else if (cmonth == 12 && cday == 18 && cyear == 2011)
		return "Christmas Break";
	else if (cmonth == 12 && cday == 21 && cyear == 2011)
		return "---------- >";
	else if (cmonth == 12 && cday == 28 && cyear == 2011)
		return "----------";
	else if (cmonth == 12 && cday == 28 && cyear == 2011)
		return "< ----------";
	else if (cmonth == 12 && cday == 29 && cyear == 2009)
		return "Christmas Break";
	else if (cmonth == 12 && cday == 30 && cyear == 2009)
		return "----------";
	else if (cmonth == 12 && cday == 31 && cyear == 2009)
		return "Break --- >";
	else if (cmonth == 2 && cday == 8 && cyear == 2010)
		return "Pro-D Day";
	else if (cmonth == 3 && cday == 18 && cyear == 2011)
		return "< ----------";
	else if (cmonth == 3 && cday == 19 && cyear == 2011)
		return "Spring";
	else if (cmonth == 3 && cday == 20 && cyear == 2011)
		return "----------";
	else if (cmonth == 3 && cday == 21 && cyear == 2011)
		return "Break";
	else if (cmonth == 3 && cday == 12 && cyear == 2010)
		return "---------- >";
	else if (cmonth == 3 && cday == 15 && cyear == 2010)
		return "< ----------";
	else if (cmonth == 3 && cday == 16 && cyear == 2010)
		return "Spring";
	else if (cmonth == 3 && cday == 17 && cyear == 2010)
		return "----------";
	else if (cmonth == 3 && cday == 18 && cyear == 2010)
		return "Break -- ";
	else if (cmonth == 3 && cday == 19 && cyear == 2010)
		return " -- >";
	else if (cmonth == 4 && cday == 25 && cyear == 2011)
		return "Easter Monday";

//change or add every year

	else if (cmonth >= 3 && cmonth <= 5 ) {
		var e = Easter(cyear);
		var g = addDays(e[2], e[1], cyear, -2); // Good Friday
		var p = addDays(e[2], e[1], cyear, 49); // Pentecost
		if (cmonth == e[1] && cday == e[2])
			return "Easter";
		else if (cmonth == g[1] && cday == g[2])
			return "Good Friday";

	}


	return "";
}
