﻿// Copyright © 2008-2009 Robert L. Crawford

// Global constants
var HourMsec = 3600000;
var DayMsec = 24*HourMsec;
var WeekMsec = 7*DayMsec;
var SlotMsec = Math.floor(2.5*HourMsec);
var BaseHour = 8*HourMsec;

var MonthNames = ['January','February','March','April','May','June','July','August','September','October','November','December'];
var MonthAbbrs = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];

var DayNames = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];

var SigNames = 'Comp. Yourself SIG; Genealogy SIG; Financial Ed. SIG; Mac SIG; New Technology SIG; Graphics SIG';

// Holiday entry constants
var HMO = 0;	// Month holiday occurs
var HDY = 1;	// Day holiday occurs (HDW == 0) or week holiday occurs (HDW <> 0)
var HDW = 2;	// Day of week (0 = any)
var HOS = 3;	// Offset (used for day after Thanksgiving)
var HNM = 4;	// Holiday name
var HLO = 5;	// Location of event if any
var HCO = 6;	// Comment on holiday

var RegularHoliday = new Array();

// One-time holiday entry constants
var ODT = 0;	// Specific date holiday occurs
var ONM = 1;	// Holiday name
var OLO = 2;	// Location of event if any
var OCO = 3;	// Comment

var OneTimeHoliday = new Array();

// Meeting entry constants
var MVA = 0;	// Valid months
var MDW = 1;	// Day of week
var MDY = 2; 	// Week holiday occurs
var MST = 3;	// Meeting start time
var MLN = 4;	// Length of meeting
var MNM = 5;	// Meeting name
var MLO = 6;	// Meeting location
var MCO = 7;	// Comment on meeting

var YearMeeting = new Array();
var MonthMeeting = new Array();
var WeekMeeting = new Array();

// One-time meeting entry constants
var TDT = 0;	// Specific date of meeting
var TST = 1;	// Meeting start time
var TLN = 2;	// Length of meeting
var TNM = 3;	// Meeting name
var TLO = 4;	// Meeting location
var TCO = 5;	// Comment on meeting

var OneTimeMeeting = new Array();

function Initialize()
{
	SetSizes();
	window.onresize = SetSizes;
	DisplayCalendar();
}

function SetSizes()
{
	var headHeight = document.getElementById('PageHead').offsetHeight;
	var bodyHeight = document.getElementById('PageBody').offsetHeight;
	var footHeight = document.getElementById('PageFoot').offsetHeight;
	var h = headHeight + bodyHeight + footHeight;
	document.getElementById('BodyDiv').style.height = h + 'px';
}

function DisplayCalendar()
{
	var cd = new Date(CurrentDate.valueOf());
	var m = cd.getMonth();
	var mon = MonthAbbrs[m]+' ';

	if (cd.getDate() == 1)
		var monyr = MonthNames[m]+' '+cd.getFullYear();
	else if (m < 11)
		var monyr = MonthNames[m+1]+' '+cd.getFullYear();
	else
		var monyr = MonthNames[0]+' '+(cd.getFullYear()+1);

	document.getElementById('ThisMonth').innerHTML = monyr;

	for (var w = 0; w < 6; w++)
	{
		for (var d = 0; d < 7; d++)
		{
			document.getElementById('w'+w+'d'+d).style.backgroundColor = '';

			var box = document.getElementById('w'+w+'d'+d+'s0');
			box.innerHTML = mon + cd.getDate();
			var cd = new Date(cd.getFullYear(), cd.getMonth(), cd.getDate()+1);
			var tm = cd.getMonth();
			if (tm == m)
				mon = '';
			else
			{
				m = cd.getMonth();
				mon = MonthAbbrs[m]+' ';
			}
			if (d > 0) // Mon-Sat have time slots
			{
				for (var s = 1; s < 6; s++)
				{
					var slot = document.getElementById('w'+w+'d'+d+'s'+s);
					slot.innerHTML = '&nbsp;';
					slot.style.background = '';
					slot.title = '';
					slot.itemCode = '';
					slot.monIndex = '';
					slot.oneIndex = '';
				}
			}
		}
	}
	ShowHolidays();
	ShowMeetings();
	HighlightToday();
}

function HighlightToday()
{
	var begin = CurrentDate.valueOf();
	var end = CurrentDate.valueOf() + 6*WeekMsec;
	var today = new Date().valueOf();

	if (today >= begin && today < end)
	{
		var day = Math.floor((today-begin)/DayMsec);
		var w = Math.floor(day/7);
		var d = day % 7;

		document.getElementById('w'+w+'d'+d).style.backgroundColor = 'lightgreen';
	}
}

function ShowHolidays()
{
	var begin = CurrentDate.valueOf();
	var end = CurrentDate.valueOf() + 6*WeekMsec;

	var month1 = CurrentDate.getMonth();
	var month2 = (month1 == 11)? 0: month1 + 1;
	var month3 = (CurrentDate.getDate() == 1)? month2: (month2 == 11)? 0: month2 + 1;

	for (var h = 0; h < RegularHoliday.length; h++)
	{
		var mon = RegularHoliday[h][HMO] - 1;
		if (mon != month1 && mon != month2 && mon != month3) continue;

		var dom = RegularHoliday[h][HDY];
		var wkd = RegularHoliday[h][HDW];
		var year = CurrentDate.getFullYear();
		if (mon == month1)
			var yr = year;
		else
			var yr = (mon < month1)? year + 1: year;

		if (wkd == 0) // Holiday on specific date (ie July 4)
		{
			var dt = new Date(yr, mon, dom);
			var dow = dt.getDay();
			if (dow == 0)
				dt = new Date(yr, mon, dom + 1);
			else if (dow == 6)
				dt = new Date(yr, mon, dom - 1);
		}
		else // Holiday on day of week
		{
			var day = 7 * (dom - 1) + 1;
			if (dom < 5)
				var dt = new Date(yr, mon, day);
			else
				var dt = new Date(yr, mon + 1, -6);
			var dow = dt.getDay();
			var inc = (wkd >= dow)? wkd - dow: 7 + wkd - dow;
			inc += RegularHoliday[h][HOS];
			dt = new Date(dt.valueOf() + DayMsec * inc);
		}
		if (dt >= begin && dt < end)
		{
			var day = Math.floor((dt-begin)/DayMsec);
			var w = Math.floor(day/7);
			var d = day % 7;
			document.getElementById('w'+w+'d'+d+'s1').innerHTML = RegularHoliday[h][HNM];
			document.getElementById('w'+w+'d'+d+'s1').itemCode = 'h';
			document.getElementById('w'+w+'d'+d+'s2').innerHTML = '&nbsp;';
			document.getElementById('w'+w+'d'+d+'s3').innerHTML = 'Club closed today';
			document.getElementById('w'+w+'d'+d+'s3').itemCode = 'h';
			document.getElementById('w'+w+'d'+d+'s4').innerHTML = '&nbsp;';
			document.getElementById('w'+w+'d'+d+'s5').innerHTML = '&nbsp;';
		}
	}
}

function ShowMeetings()
{
	var begin = CurrentDate.valueOf();
	var end = CurrentDate.valueOf() + 6*WeekMsec;

	for (var m = 0; m < OneTimeMeeting.length; m++)
	{
		var dt = OneTimeMeeting[m][TDT].valueOf();
		if (dt < begin || dt >= end) continue;

		var day = Math.floor((dt-begin)/DayMsec);
		var w = Math.floor(day/7);
		var d = day % 7;
		if (document.getElementById('w'+w+'d'+d+'s1').itemCode == 'h') continue;

		for (s = 1; s < 6; s++)
		{
			var slot = document.getElementById('w'+w+'d'+d+'s'+s);
			if (slot.innerHTML == '&nbsp;' || slot.innerHTML.charCodeAt(0) == 160) break;
		}
		if (s < 6)
		{
			var cTime = tmf(OneTimeMeeting[m][TST]);
			if (cTime.substr(1,1) == ':')
				var sTime = '0' + cTime.substr(0,1) + cTime.substr(2,2) + cTime.substr(5,1);
			else
				var sTime = cTime.substr(0,2) + cTime.substr(3,2) + cTime.substr(6,1);
			slot.innerHTML = sTime + ' ' + OneTimeMeeting[m][TNM];
			slot.title = cTime + ' in ' + OneTimeMeeting[m][TLO];
			slot.itemCode = 'm';
			slot.oneIndex = m.toString();
			slot.onclick = DisplayMeetingDetails;
		}
	}
	var yr = CurrentDate.getFullYear();
	var baseMonth = CurrentDate.getMonth();
	for (var m = 0; m < MonthMeeting.length; m++)
	{
		var valid = MonthMeeting[m][MVA];
		var wkd = MonthMeeting[m][MDW];
		var dom = MonthMeeting[m][MDY];
		for (var mon = baseMonth; mon != (baseMonth + 3) % 12; mon = (mon + 1) % 12)
		{
			if (((1 << mon) & valid) == 0) continue;
			var yrAdj = (mon < baseMonth)? 1: 0;

			if (dom < 5)
				var md = new Date(yr + yrAdj, mon, 7 * (dom - 1) + 1);
			else
				var md = new Date(yr + yrAdj, mon + 1, -6);

			var dow = md.getDay();
			var inc = (wkd >= dow)? wkd - dow: 7 + wkd - dow;
			var md = new Date(md.valueOf() + DayMsec * inc);
			var dt = md.valueOf();

			if (dt >= begin && dt < end)
			{
				var day = Math.floor((dt-begin)/DayMsec);
				var w = Math.floor(day/7);
				var d = day % 7;
				if (document.getElementById('w'+w+'d'+d+'s1').itemCode == 'h') continue;
				if (SpecificSig(md, MonthMeeting[m][MNM])) continue;	// Skip monthly SIG meeting when specific specified

				for (s = 1; s < 6; s++)
				{
					var slot = document.getElementById('w'+w+'d'+d+'s'+s);
					if (slot.innerHTML == '&nbsp;' || slot.innerHTML.charCodeAt(0) == 160) break;
				}
				if (s < 6)
				{
					var cTime = tmf(MonthMeeting[m][MST]);
					if (cTime.substr(1,1) == ':')
						var sTime = '0' + cTime.substr(0,1) + cTime.substr(2,2) + cTime.substr(5,1);
					else
						var sTime = cTime.substr(0,2) + cTime.substr(3,2) + cTime.substr(6,1);
					slot.innerHTML = sTime + ' ' + MonthMeeting[m][MNM];
					slot.title = cTime + ' in ' + MonthMeeting[m][MLO];
					slot.itemCode = 'm';
					slot.monIndex = m.toString();
					slot.onclick = DisplayMeetingDetails;
				}
			}
		}
	}
}

function SpecificSig(dt, name)
{
//	if (SigNames.indexOf(name) < 0) return false;

	var year = dt.getFullYear();
	var month = dt.getMonth();

	for (var m = 0; m < OneTimeMeeting.length; m++)
		if (name == OneTimeMeeting[m][TNM] && year == OneTimeMeeting[m][TDT].getFullYear() && month == OneTimeMeeting[m][TDT].getMonth())
			return true;

	return false;
}

function DisplayMeetingDetails()
{
	if (this.monIndex)
	{
		var m = this.monIndex;
		var sTime = MonthMeeting[m][MST];
		var len = MonthMeeting[m][MLN];
		var name = MonthMeeting[m][MNM];
		var loc = MonthMeeting[m][MLO];
		var com = MonthMeeting[m][MCO];
	}
	else if (this.oneIndex)
	{
		var m = this.oneIndex;
		var sTime = OneTimeMeeting[m][TST];
		var len = OneTimeMeeting[m][TLN];
		var name = OneTimeMeeting[m][TNM];
		var loc = OneTimeMeeting[m][TLO];
		var com = OneTimeMeeting[m][TCO];
	}
	else return false;

	msg = name + '\n';
	mDate = new Date(CurrentDate.valueOf() + WeekMsec * this.id.substr(1,1) + DayMsec * this.id.substr(3,1));
	msg += 'On ' + MonthAbbrs[mDate.getMonth()] + ' ' + mDate.getDate() + ' from ' + tmf(sTime);
	eTime = new Date(sTime.valueOf() + 60000 * len);
	msg += ' to ' + tmf(eTime) + '\n';
	msg += 'In ' + loc + '\n\n';
	msg += com;

	alert(msg); // Display the meeting details
	return false;
}

function tmf(dt)
{
	var ap = ' am';
	var hr = dt.getHours();

	if (hr >= 12)
	{
		if (hr > 12) hr -= 12;
		ap = ' pm';
	}
	min = dt.getMinutes();
	if (min < 10) min = '0'+min;
	return hr + ':' + min + ap;
}

// Called by LastMonth (a = -1) and NextMonth (a = +1) buttons
function ChangeDate(a)
{
	CurrentDate = AdjustCurrentDate(a);
	CurrentEnd = new Date(CurrentDate.valueOf() + 6*WeekMsec);
	DisplayCalendar();
}

function AdjustCurrentDate(a)
{
	var y = CurrentDate.getFullYear();
	var m = CurrentDate.getMonth() + a;
	if (CurrentDate.getDate() != 1) m++;

	if (m >= 12)
	{
		m -= 12;
		y++;
	}
	if (m < 0)
	{
		m += 12;
		y--;
	}
	var cd = new Date(y,m,1);
	return new Date(cd.getFullYear(), cd.getMonth(), cd.getDate() - cd.getDay());
}

