var PapercutCalendar = {
	Version: '2.4.3',
	
	init: function() {
		//Nifty("div.calendarBottom", 'transparent bottom', 'white');
		//Nifty("div#tabs a","transparent top", 'white');
		//Nifty("div#toggleHeader div","transparent small", 'white');
		//showMonth(currentDate.getMonth());
		currentDate.setTime($('calendarStart').value * 1000);
		switch ($('calendarView').value) {
			case 'month':
				switchToCalendar('month');
			break;
			case 'day':
				switchToCalendar('day');
			break;
			case 'week':
				switchToCalendar('week');
			break;
			default:
				switchToCalendar('month');
			break;
		}
		getEvents($('calendarIds').innerHTML);
	},
	initialLoad: false
};

var serverOffset = 18000000; // 4 hours in ms
var localTime = new Date();
var timeDifference = (localTime.getTimezoneOffset() * 60 * 1000) - serverOffset;
//alert(240 * 60 * 1000);
// 4 hours - 14400000
// 5 hours - 18000000
// 6 hours - 15600000 

function duringDST(ts) {
	if ((ts > 1173589200 && ts < 1194148800) || (ts > 1205038800 && ts < 1225598400) || (ts > 1236488400 && ts < 1257048000) || (ts > 1268542800 && ts < 1289102400)) {
		return true;
	}
	else {
		return false;
	}
	/*3/11/07 12:00am = 1173589200
	11/4/07 12:00am = 1194148800
	3/9/08 12:00am = 1205038800
	11/2/08 12:00am = 1225598400
	3/8/09 12:00am = 1236488400
	11/1/09 12:00am = 1257048000
	3/14/10 12:00am = 1268542800
	11/7/10 12:00am = 1289102400*/
}

var currentDate = new Date();
var dayName = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
var monthName = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
var currentView; // month, week, day
var viewType = 'calendar'; // calendar, agenda
var eventItems = new Object();
var eventSlots = new Object();
var eventSlotsCount = new Object();
var showViewAllSet = new Object();
var visibleEvents = new Object();

var loadedCalendars = new Object();
var loadedMonths = new Object();

// object for holding all day or spanned events
var fullDayEvents = new Object();
var timedEvents = new Object();
var eventsByItemId = new Object();

// caching objects
var cacheCalendarCode = new Object();
var cacheMonthEvents = new Object();
var cacheWeekEvents = new Object();
var cacheDayEvents = new Object();
var cacheViewAllEvents = new Object();

// three days ago timestamp for generating an !
var threeDaysAgoDate = new Date();
threeDaysAgoDate.setDate(threeDaysAgoDate.getDate() - 3);
var threeDaysAgo = threeDaysAgoDate.getTime() / 1000;

Event.observe(window, 'load', PapercutCalendar.init);
//Event.observe(window, 'resize', updateDisplay);

var isOverCalendarList = false;

function setOverCalendarList() {
	isOverCalendarList = true;
}
function setOutCalendarList() {
	isOverCalendarList = false;
}

var dstAutoGood = false;
var dstNewGood = false;
checkDST();
//alert(dstAutoGood + ' ' + dstNewGood);
function checkDST() {
	var testDate1 = new Date(2007, 2, 7, 10, 30, 00, 1);
	var dateDiff1 = (testDate1.getHours()-testDate1.getUTCHours());
	
	var testDate2 = new Date(2007, 2, 14, 10, 30, 00, 1);
	var dateDiff2 = (testDate2.getHours()-testDate2.getUTCHours());
	
	var testDate3 = new Date(2007, 2, 30, 10, 30, 00, 1);
	var dateDiff3 = (testDate3.getHours()-testDate3.getUTCHours());
	
	var testDate4 = new Date(2007, 6, 1, 10, 30, 00, 1);
	var dateDiff4 = (testDate4.getHours()-testDate4.getUTCHours());
	
	var testDate5 = new Date(2007, 9, 25, 10, 30, 00, 1);
	var dateDiff5 = (testDate5.getHours()-testDate5.getUTCHours());
	
	var testDate6 = new Date(2007, 9, 31, 10, 30, 00, 1);
	var dateDiff6 = (testDate6.getHours()-testDate6.getUTCHours());
	
	var testDate7 = new Date(2007, 10, 8, 10, 30, 00, 1);
	var dateDiff7 = (testDate7.getHours()-testDate7.getUTCHours());
	
	//test for DST or Summertime at all
	if (dateDiff1 == dateDiff4) {
		/*document.write("Your computer may need to have DST updating turned on.<br><br>");
		document.write("No DST or Summertime in your current timezone <br>or you have automatic DST updating turned off. <br>");
		document.write("Just in case here are links to major OS vendors' DST update info:<br><br> <A HREF=\"http://support.microsoft.com/gp/cp_dst\"> Microsoft Windows XP, 2003, Vista</A> &nbsp; <A HREF=\"http://www.intelliadmin.com/Downloads.htm\"> Microsoft Windows 95/98/NT/2000</A> &nbsp; <br> <A HREF=\"http://docs.info.apple.com/article.html?artnum=305056\">Apple OSX</A> &nbsp; <A HREF=\"http://packages.ubuntu.com/edgy/libs/tzdata\">Ubuntu Linux</A> <br>");*/
	}
	else {
		dstAutoGood = true;
		if ((dateDiff1 + 1 == dateDiff2) && ((dateDiff7 + 1) == dateDiff6)) {
			dstNewGood = true;
			/*document.write("Your computer successfully returned information.<br><br>");
			document.write("<b>Your system appears ready for DST 2007 and later!</b><br>");*/
		}
		else {
			if ((dateDiff1 == dateDiff3) && ((dateDiff6 + 1) == dateDiff5)) {
				/*document.write("Your computer reported deficiencies for DST07 and later.<br><br>");
				document.write("<FONT color=\"red\"><b>Your system does not appear patched for the DST 2007 change!</b></FONT><br>");
				document.write("Use the appropriate link for your computer's operating system <br>to get a patch or just more information:<br><br> <A HREF=\"http://support.microsoft.com/gp/cp_dst\"> Microsoft Windows XP, 2003, Vista</A> &nbsp; <A HREF=\"http://www.intelliadmin.com/Downloads.htm\"> Microsoft Windows 95/98/NT/2000</A> &nbsp; <br> <A HREF=\"http://docs.info.apple.com/article.html?artnum=305056\">Apple OSX</A> &nbsp; <A HREF=\"http://packages.ubuntu.com/edgy/libs/tzdata\">Ubuntu Linux</A> <br>");*/
			}
			/*else {
				if (((dateDiff6 + 1) == dateDiff5) && ((dateDiff2 + 1) == dateDiff3)) {
					document.write("Your computer reports a configuration to use EU Summertime for 2007.<br><br>");
					document.write("<b>Your system appears to be configured for an <br>EU timezone that uses summer time!</b><br>");
					document.write("Just in case here are links to major OS vendors' DST update info:<br><br> <A HREF=\"http://support.microsoft.com/gp/cp_dst\"> Microsoft Windows XP, Vista</A> &nbsp; <A HREF=\"http://www.intelliadmin.com/Downloads.htm\"> Microsoft Windows 95/98/NT/2000</A> &nbsp; <br> <A HREF=\"http://docs.info.apple.com/article.html?artnum=305056\">Apple OSX</A> &nbsp; <A HREF=\"http://packages.ubuntu.com/edgy/libs/tzdata\">Ubuntu Linux</A> <br>");
				}
				else {
					document.write("Your computer may need a patch or update for DST07 and later.<br><br>");
					document.write("<b>Unable to determine your DST status.</b><br>");
					document.write("Just in case here are links to major OS vendors' DST update info:<br><br> <A HREF=\"http://support.microsoft.com/gp/cp_dst\"> Microsoft Windows XP, Vista</A> &nbsp; <A HREF=\"http://www.intelliadmin.com/Downloads.htm\"> Microsoft Windows 95/98/NT/2000</A> &nbsp; <br> <A HREF=\"http://docs.info.apple.com/article.html?artnum=305056\">Apple OSX</A> &nbsp; <A HREF=\"http://packages.ubuntu.com/edgy/libs/tzdata\">Ubuntu Linux</A> <br>");
				}
			}*/
		}
	}
}

function showCalendarList() {
	Element.show($('calendarList'));
	//new Effect.BlindDown($('calendarList'), {duration:.5, afterFinish: function() {
		//Nifty('div#calendarList', 'transparent top', 'white');
		//Nifty("div#calendarList a","transparent small", 'white');
		document.body.onmousedown = function() {
			if ($('calendarList').style.display != 'none' && !isOverCalendarList) {
				hideCalendarList();
			}
		}
	//}});
}

function hideCalendarList() {
	Element.hide($('calendarList'));
	//new Effect.BlindUp($('calendarList'), {duration:.5, afterFinish: function() {
		isOverCalendarList = false;
	//}});
}

function showOnly(calendarId) {
	selectNoCalendars();
	toggleCalendar(calendarId);
}

var toggleTimer = null;
var toggleWaitIds = new Array();
function toggleCalendar(calendarId) {
	clearTimeout(toggleTimer);
	toggleWaitIds.push(calendarId);
	showLoading(true);
	toggleTimer = setTimeout('toggleCalendarTimeout()', 1000);
}

function toggleCalendarTimeout() {
	clearTimeout(toggleTimer);
	for (var i = 0; i < toggleWaitIds.length; i++) {
		calendarId = toggleWaitIds[i];
		var h = $('calendar-' + calendarId);
		if (h != null) {
			if (h.className == 'activeLink') {
				h.className = '';
				h.getElementsByTagName('a')[0].style.backgroundColor = '';
				h.childNodes[0].checked = false;
				setTimeout('unloadEvents('+calendarId+')', 0);
			}
			else {
				h.className = 'activeLink';
				h.getElementsByTagName('a')[0].style.backgroundColor = h.getElementsByTagName('a')[0].rel;
				h.childNodes[0].checked = true;
				getEvents(calendarId);
				//getEventsMonth();
			}
		}
	}
		
	toggleWaitIds = new Array();
}

function highlightCalendarName(calendarId) {
	var h = $('calendar-' + calendarId);
	if (h != null) {
		h.className = 'activeLink';
		h.childNodes[0].checked = true;
		h.getElementsByTagName('a')[0].style.backgroundColor = h.getElementsByTagName('a')[0].rel;
	}
}

function showMonthCodeFromCache() {
	
}

function clearCache() {
	//d('function clear cache');
	
	// clear event display cache
	
	for (var i in cacheMonthEvents) {
		delete cacheMonthEvents[i];
	}
	$('eventHolder').innerHTML = '';
	
	for (var i in cacheCalendarCode) {
		//alert('deleting cacheCalendarCode[i] ' + cacheCalendarCode[i]);
		delete cacheCalendarCode[i];
		//d('deleted cacheCalendarCode[i] ' + cacheCalendarCode[i]);
	}
	for (var i in cacheWeekEvents) {
		delete cacheWeekEvents[i];
	}
	for (var i in cacheDayEvents) {
		delete cacheDayEvents[i];
	}
	for (var i in cacheViewAllEvents) {
		delete cacheViewAllEvents[i];
	}
	
	showMonthCodeFromCache();
}

function unloadEvents(calendarId) {
	//d('function unload events ' + calendarId);
	removeEvents();
	var calendarIds = calendarId.toString().split(',');
	
	clearCache();
	
	for (var k = 0; k < calendarIds.length; k++) {
		//d('function unload events for ' + calendarIds[k]);
		delete loadedCalendars[calendarIds[k]];
		delete loadedMonths[calendarIds[k]];
		//$('calendar-' + calendarIds[k]).childNodes[0].checked = false;
		//loadedCalendars[calendarIds[k]] = null;
		//loadedMonths[calendarIds[k]] = null;

		// remove from event items
		for (var i in eventItems) {
			for (var j = 0; j < eventItems[i].length; j++) {
				if (eventItems[i][j].calendarId == calendarIds[k]) {
					eventItems[i].splice([j], 1);
					j--;
				}
			}
		}
		
		// remove from full day events
		for (var i in fullDayEvents) {
			for (var j = 0; j < fullDayEvents[i].length; j++) {
				if (fullDayEvents[i][j].calendarId == calendarIds[k]) {
					fullDayEvents[i].splice([j], 1);
					j--;
				}
			}
		}
		
		// remove from timed events
		for (var i in timedEvents) {
			for (var j = 0; j < timedEvents[i].length; j++) {
				if (timedEvents[i][j].calendarId == calendarIds[k]) {
					timedEvents[i].splice([j], 1);
					j--;
				}
			}
		}
		
		// remove from event items by id
		for (var i in eventsByItemId) {
			if (eventsByItemId[i].calendarId == calendarIds[k]) {
				delete eventsByItemId[i];
			}
		}
	}
	
	updateDisplay();
}

var waitingOnEvents = false;
function getEvents(calendarId, preloadYear, preloadMonth, preload) {
	waitingOnEvents = true;
	showLoading(true);
	//d('function get events for ' + calendarId);
	if (preloadMonth == null) {
		preloadMonth = currentDate.getMonth();
	}
	if (preloadYear == null) {
		preloadYear = currentDate.getFullYear();
	}
	
	var calendarIds = calendarId.toString().split(',');
	var needToClearCache = false;
	for (var i = 0; i < calendarIds.length; i++) {
		highlightCalendarName(calendarIds[i]);
		loadedCalendars[calendarIds[i]] = calendarIds[i];
		if (loadedMonths[calendarIds[i]] == null) {
			loadedMonths[calendarIds[i]] = new Object();
			needToClearCache = true;
		}
		loadedMonths[calendarIds[i]][preloadYear + '-' + preloadMonth] = true;
		//d(''+'set ' + preloadYear + '-' + preloadMonth);
	}
	if (needToClearCache) {
		clearCache();
	}
	
	var url = 'calendarGetEvents.php';
	var pars = 'calendarId=' + calendarId + '&ts=' + (currentDate.getTime() / 1000);
	
	if (preload == null) {
		var myAjax = new Ajax.Request( url, { method: 'get', parameters: pars, onComplete: getEventsP });
	}
	else {
		var myAjax = new Ajax.Request( url, { method: 'get', parameters: pars, onComplete: getEventsPreP });
	}
}

function getEventsThisP(response) {
	//d('function get events response');
	var funcCall = getEventsP(response);
	setTimeout(function() {	return funcCall; }, 0);
}

function getEventsPreP(response) {
	//getEventsP(response);
	//updateDisplay(); // if no events, this clears the loading
	showLoading(false);
}

function getEventsP(response) {
	//d('function get events process check');
	if (!response.responseText.match(/^false/)) {
		try {
			//d('processing');
			//d(''+response.responseText);
			eval(response.responseText);
			//d('processed');
		}
		catch(e) {
			alert('Please refresh your browser');
		}
		//d('function get events process');
	}
	else {
		//d('response text was ' + response.responseText);
	}
	waitingOnEvents = false;
	setTimeout('updateDisplay()', 0); // if no events, this clears the loading
	showLoading(false);
}

function selectAllCalendars() {
	var e = $('calendarListInner').getElementsByTagName('li');
	var calendarIds = new Array();
	var h;
	var id;
	for (var i = 2; i < e.length; i++) {
		id = e[i].id.substr(9);
		h = $('calendar-' + id);
		if (h != null && h.className != 'activeLink') {
			calendarIds.push(id);
		}
	}
	getEvents(calendarIds.join(','));
}

function selectNoCalendars() {
	//d('function select no');
	var e = $('calendarListInner').getElementsByTagName('li');
	var calendarIds = new Array();
	var h;
	var id;
	for (var i = 2; i < e.length; i++) {
		id = e[i].id.substr(9);
		calendarIds.push(id);
		h = $('calendar-' + id);
		if (h != null) {
			h.className = '';
			h.getElementsByTagName('a')[0].style.backgroundColor = '';
			h.childNodes[0].checked = false;
		}
	}
	unloadEvents(calendarIds.join(','));
}

var lastUpdatedOn = null;
function updateDisplay() {
	//d('function update display check');
	if (!waitingOnEvents) {
		lastUpdatedOn = currentDate.getTime();
		//d('function update display');
		showLoading(true);
		overViewAllCheck();
	
		switch (currentView) {
			case 'month':
				setTimeout('showEventsMonth()', 0);
			break;
			case 'day':
				showEventsDay();
			break;
			case 'week':
				showEventsWeek();
			break;
			default:
				
			break;
		}
		//d('(end) function update display');
	}
	else {
		//d('TRIED TO UPDATE BUT WAITING ON EVENTS');
	}
}

function makeDateIndex(d) {
	return d.getFullYear() + '/' + (d.getMonth() + 1).toString() + '/' + d.getDate() + '/' + currentDate.getMonth();
}

var printDiv;
function switchToPrint() {
	var middle = document.getElementById('calendarMiddle');
	if (viewType != 'agenda' || middle.childNodes.length < 1) {
		switchToAgenda();
		setTimeout('switchToPrint()', 1000);
	}
	else {
		printDiv = document.createElement('div');
		printDiv.id = 'printDiv';
		printDiv.style.width = '100%';
		printDiv.style.height = document.body.offsetHeight + 'px';
		printDiv.style.backgroundColor = '#ffffff';
		printDiv.style.position = 'absolute';
		printDiv.style.top = '0';
		printDiv.style.left = '0';
		printDiv.innerHTML = "<a href=\"#\" onmousedown=\"switchBack();\">Back</a><br/><br/>" + middle.innerHTML;
		showLoading(false);
		document.body.style.backgroundColor = '#ffffff';
		$('header').style.display = 'none';
		$('container').style.display = 'none';
		document.body.appendChild(printDiv);
		setTimeout('doPrint()', 0);
	}
}
function switchBack() {
	document.body.style.backgroundColor = '';
	printDiv.parentNode.removeChild(printDiv);
	$('header').style.display = '';
	$('container').style.display = '';
}
function doPrint() {
	window.print();
}

function switchToAgenda() {
	//d('function switch to agenda');
	viewType = 'agenda';
	$('agendaLabel').className = 'linkactive';
	$('calendarLabel').className = 'link';
	
	switch (currentView) {
		case 'month':
			showMonth();
		break;
		
		case 'week':
			showWeek();
		break;
		
		case 'day':
			showDay();
		break;
		
		default:
			showMonth();
		break;
	}
}

function switchToCalendar(c, calView) {
	//d('functions switch to calendar ' + calView);
	/*if (viewType == 'calendar') {
		if (currentView == 'month') {
			
		}
	}*/
	if (calView != null) {
		viewType = 'calendar';
		$('agendaLabel').className = 'link';
		$('calendarLabel').className = 'linkactive';
	}
	switch (c) {
		case 'month':
			showMonth();
		break;
		case 'day':
			showDay();
		break;
		case 'week':
			showWeek();
		break;
		default:
			
		break;
	}
}

function updateNavMonth() {
	var str = '';
	// update month navigation display
	var center = $('calendarCenter');
	if (center != null) {
		str = '<div class="arrowLeft" onmousedown="showPreviousMonth();">&nbsp;</div>'
		str += '<div class="arrowRight" onmousedown="showNextMonth()">&nbsp;</div>'
		var tempDates = new Date();
		tempDates.setTime(currentDate.getTime());
		tempDates.setMonth(tempDates.getMonth() - 6);
		str += '<select onchange="showNextMonth(this.options[this.selectedIndex].value)" style="width:100px;">';
		for (var i = -5; i <= 6; i++) {
			tempDates.setMonth(tempDates.getMonth() + 1);
			if (i != 0) {
				str += '<option value="'+i+'">';
			}
			else {
				str += '<option selected value="'+i+'">';
			}
			str += monthName[tempDates.getMonth()] + ' ' + tempDates.getFullYear();
			str += '</option>';
		}
		//str += monthName[currentDate.getMonth()] + ' ' + currentDate.getFullYear();
		str += '</select>';
		
		center.innerHTML = str;
		//Nifty('div.arrowLeft', 'transparent small fixed-height', 'white');
		//Nifty('div.arrowRight', 'transparent small fixed-height', 'white');
	}
}

function updateHeaderMonth() {
	var str = '';
	// update header (Sunday - Saturday)
	var header = $('calendarTop');
	if (header != null) {
		str = '<table id="calendarTableHeader"><tr><td>Sunday</td><td>Monday</td><td>Tuesday</td><td>Wednesday</td><td>Thursday</td><td>Friday</td><td>Saturday</td></tr></table>';
		header.innerHTML = str;
		//Nifty("div.calendarTop", 'transparent tl', 'white');
	}
}

function makeYMI(d) {
	return d.getFullYear() + '-' + d.getMonth();
}

function cacheMiddleContent() {
	//d('function cache middle content');
	if (viewType == 'calendar') {
		switch (currentView) {
			case 'month':
				
			break;
		}
	}
}

function switchToDay(ts) {
	currentDate.setTime(ts);
	switchToCalendar('day');
}

function updateMiddleMonth() {
	var container = $('calendarMiddle');
	var ymi = makeYMI(currentDate);
	//d('function update middle month');
	// check if this month's calendar is cached
	if (cacheCalendarCode[ymi] == null) {
		//d('function update middle month (redraw calendar - generate code)');
		// build the calendar table
		if (container != null) {
			str = '<table class="calendarTable" id="calendarTable-'+ymi+'">';
			for (var i = firstSunday(); i <= lastSaturday(); i = nextDay(i)) {
				if (i.getDay() == 0) {
					str += '<tr>';
				}
				str += '<td><div class="dayHeader" onmousedown=\"switchToDay(\'' + i.getTime() + '\');\">' + i.getDate() + '</div><div class="dayContent" id="'+makeDateIndex(i)+'">&nbsp;</div></td>';
				if (i.getDay() == 6) {
					str += '</tr>';
				}
			}
			str += '</table>';
			
			// cache calendar code
			cacheCalendarCode[ymi] = str;
			container.innerHTML = str;
			highlightTodayMonth();
			//setTimeout('showEventsMonth()', 0);
		}
	}
	else {
		//d('function update middle month (redraw calendar from cache)');
		container.innerHTML = cacheCalendarCode[ymi];
	}
}

function highlightTodayMonth() {
	var today = new Date();
	var todayDiv = $(makeDateIndex(today));
	if (todayDiv != null) {
		todayDiv.parentNode.getElementsByTagName('div')[0].className = 'dayHeaderActive';
		/*var n = todayDiv.parentNode.getElementsByTagName('div')[0];
		new Effect.Highlight(n, {duration:1, startcolor:'#999999', endcolor:'#cccccc', afterFinish: function() {
			todayDiv.parentNode.getElementsByTagName('div')[0].className = 'dayHeaderActive';
			//todayDiv.parentNode.getElementsByTagName('div')[0].style.backgroundColor = 'black';
		}}
		);*/
	}
}

function updateHeaderAgendaMonth() {
	// update header
	var header = $('calendarTop');
	if (header != null) {
		str = '&nbsp;';
		header.innerHTML = str;
		//Nifty("div.calendarTop", 'transparent tl', 'white');
	}
}

function updateMiddleAgendaMonth() {
	// make middle blank
	//d('function update middle agenda month (' + currentView + ')');
	var container = $('calendarMiddle');
	if (container != null && !waitingOnEvents) {
		str = '<div class="">';
		
		str += '</div>';
		container.innerHTML = str;
		
		if (currentView == 'month') {
			setTimeout('showEventsMonth()', 0);
		}
		else if (currentView == 'week') {
			setTimeout('showEventsWeek()', 0);
		}
		else {
			setTimeout('showEventsDay()', 0);
		}
	}
}

function getEventsMonth() {
	var sendingIds = new Array();
	var sendingIndex = makeYMI(currentDate);
	
	//d('function get events month');
	/*var nextMonthIds = new Array();
	var tempDate = new Date();
	tempDate.setTime(currentDate.getTime());
	tempDate.setMonth(tempDate.getMonth() + 1);
	var nextMonthIndex = tempDate.getFullYear() + '-' + tempDate.getMonth();
	
	var previousMonthIds = new Array();
	var tempDate2 = new Date();
	tempDate2.setTime(currentDate.getTime());
	tempDate2.setMonth(tempDate2.getMonth() - 1);
	var previousMonthIndex = tempDate2.getFullYear() + '-' + tempDate2.getMonth();
	*/
	
	for (var i in loadedCalendars) {
		if (loadedMonths[i][sendingIndex] == null) {
			sendingIds.push(i);
		}
		/*if (loadedMonths[i][nextMonthIndex] == null) {
			nextMonthIds.push(i);
		}
		if (loadedMonths[i][previousMonthIndex] == null) {
			previousMonthIds.push(i);
		}*/
	}
	//d(sendingIds.join(','));
	var needToUpdate = true;
	if (sendingIds.length) {
		needToUpdate = false;
		//d('need to get events for ' + sendingIds.join(','));
		getEvents(sendingIds.join(','));
	}
	/*if (nextMonthIds.length) {
		needToUpdate = false;
		getEvents(nextMonthIds.join(','), tempDate.getFullYear(), tempDate.getMonth(), true);
	}
	if (previousMonthIds.length) {
		needToUpdate = false;
		getEvents(previousMonthIds.join(','), tempDate2.getFullYear(), tempDate2.getMonth(), true);
	}*/
	if (needToUpdate) {
		if (currentView == 'month' && viewType == 'calendar') {
			//d('need to update display');
			updateDisplay();
		}
		return true;
	}
	else {
		return false;
	}
}


function showMonth(month) {
	//d('function show month');
	showLoading(true);
	$('weekCodeDiv').style.display = 'none';
	setTabsInactive();
	$('tabMonth').className = 'activeLink';
	
	hideVisibleEvents();
	currentView = 'month';
	
	if (month == null) {
		var month = currentDate.getMonth();
	}
	currentDate.setMonth(month);
	updateNavMonth();
	
	if (viewType == 'calendar') {
		setTimeout('updateHeaderMonth()', 0);
		updateMiddleMonth();
	}
	else {
		setTimeout('updateHeaderAgendaMonth()', 0);
		setTimeout('updateMiddleAgendaMonth()', 0);
	}
	
	if (PapercutCalendar.initialLoad == true || $('calendarView').value != 'month') {
		getEventsMonth();
	}
	else {
		PapercutCalendar.initialLoad = true;
	}
}

function updateWeekNav() {
	var str = '';
	// update week navigation display
	var center = $('calendarCenter');
	if (center != null) {
		str = '<div class="arrowLeft" onmousedown="showPreviousWeek();">&nbsp;</div>'
		str += '<div class="arrowRight" onmousedown="showNextWeek()">&nbsp;</div>'
		str += 'Week of ' + (currentDate.getMonth() + 1) + '/' + currentDate.getDate() + '/' + currentDate.getFullYear();
		
		center.innerHTML = str;
		//Nifty('div.arrowLeft', 'transparent small fixed-height', 'white');
		//Nifty('div.arrowRight', 'transparent small fixed-height', 'white');
	}
}

function updateDayNav() {
	var str = '';
	// update day navigation display
	var center = $('calendarCenter');
	if (center != null) {
		str = '<div class="arrowLeft" onmousedown="showPreviousDay();">&nbsp;</div>'
		str += '<div class="arrowRight" onmousedown="showNextDay()">&nbsp;</div>'
		str += (currentDate.getMonth() + 1) + '/' + currentDate.getDate() + '/' + currentDate.getFullYear();
		
		center.innerHTML = str;
		//Nifty('div.arrowLeft', 'transparent small fixed-height', 'white');
		//Nifty('div.arrowRight', 'transparent small fixed-height', 'white');
	}
}


function updateHeaderWeek() {
	var str = '';
	// update header (Sunday - Saturday)
	var header = $('calendarTop');
	var tempDate = currentDate;
	if (header != null) {
		str = '<table id="calendarTableHeaderWeek"><tr><td class="space"></td>';
		str += '<td onmousedown=\"switchToDay(\'' + tempDate.getTime() + '\');\">Sunday<br/>' + (tempDate.getMonth() + 1) + '/' + tempDate.getDate() + '</td>';
		tempDate = nextDay(tempDate);
		str += '<td onmousedown=\"switchToDay(\'' + tempDate.getTime() + '\');\">Monday<br/>' + (tempDate.getMonth() + 1) + '/' + tempDate.getDate() + '</td>';
		tempDate = nextDay(tempDate);
		str += '<td onmousedown=\"switchToDay(\'' + tempDate.getTime() + '\');\">Tuesday<br/>' + (tempDate.getMonth() + 1) + '/' + tempDate.getDate() + '</td>';
		tempDate = nextDay(tempDate);
		str += '<td onmousedown=\"switchToDay(\'' + tempDate.getTime() + '\');\">Wednesday<br/>' + (tempDate.getMonth() + 1) + '/' + tempDate.getDate() + '</td>';
		tempDate = nextDay(tempDate);
		str += '<td onmousedown=\"switchToDay(\'' + tempDate.getTime() + '\');\">Thursday<br/>' + (tempDate.getMonth() + 1) + '/' + tempDate.getDate() + '</td>';
		tempDate = nextDay(tempDate);
		str += '<td onmousedown=\"switchToDay(\'' + tempDate.getTime() + '\');\">Friday<br/>' + (tempDate.getMonth() + 1) + '/' + tempDate.getDate() + '</td>';
		tempDate = nextDay(tempDate);
		str += '<td onmousedown=\"switchToDay(\'' + tempDate.getTime() + '\');\">Saturday<br/>' + (tempDate.getMonth() + 1) + '/' + tempDate.getDate() + '</td></tr></table>';
		header.innerHTML = str;
		//Nifty("div.calendarTop", 'transparent tl', 'white');
	}
}

function updateHeaderDay() {
	var str = '';
	// update header (Sunday - Saturday)
	var header = $('calendarTop');
	var tempDate = currentDate;
	
	if (header != null) {
		str = '<table id="calendarTableHeaderDay"><tr><td class="space"></td>';
		str += '<td>' + dayName[tempDate.getDay()] + '<br/>' + (tempDate.getMonth() + 1) + '/' + tempDate.getDate() + '</td>';
		header.innerHTML = str;
		//Nifty("div.calendarTop", 'transparent tl', 'white');
	}
}


function updateMiddleWeek() {
	//d('function update middle week');
	var str = '';
	var container = $('calendarMiddle');
	if (container != null) {
		str = '<div id="allDayBoxes"><table class="calendarTableWeek"><tr><td class="space"></td>';
		
		// build all-day boxes
		for (var i = currentDate; i <= nextSaturday(); i = nextDay(i)) {
			str += '<td><div class="allDayBox" style="height:1px;" id="' + makeDateIndex(i) + '"></div></td>';
		}
		str += '</tr></table></div>';
		
		container.innerHTML = str;
		if ($('weekCodeDiv').style.display == 'none') {
			$('weekCodeDiv').style.display = '';
		}
		
		setTimeout('showEventsWeek();', 0);
	}
}

function updateMiddleDay() {
	//d('function update middle day');
	var str = '';
	var container = $('calendarMiddle');
	if (container != null) {
		str = '<div id="allDayBoxes"><table class="calendarTableDay"><tr><td class="space"></td>';
		
		// build all-day boxes
		str += '<td><div class="allDayBox" style="height:1px;" id="' + makeDateIndex(currentDate) + '"></div></td>';
		str += '</tr></table></div>';
		
		container.innerHTML = str;
		if ($('dayCodeDiv').style.display == 'none') {
			$('dayCodeDiv').style.display = '';
		}
		setTimeout('showEventsDay();', 0);
	}
	
	
	
	/*var str = '';
	// build the actual calendar table
	var container = $('calendarMiddle');
	if (container != null) {
		if (currentView != 'day') {
			str = '<div id="allDayBoxes"><table class="calendarTableDay"><tr><td class="space"></td>';
			
			// build all-day boxes
			str += '<td><div class="allDayBox" style="height:1px;" id="' + makeDateIndex(currentDate) + '"></div></td>';
			str += '</tr></table></div>';
			container.innerHTML = str;
			if (currentView != 'day') {
				container.appendChild(getDayCode());
				currentView = 'day';
			}
		}
		else {
			str = '<table class="calendarTableDay"><tr><td class="space"></td>';
			// build all-day boxes
			str += '<td><div class="allDayBox" style="height:1px;" id="' + makeDateIndex(currentDate) + '"></div></td>';
			str += '</tr></table>';
			$('allDayBoxes').innerHTML = str;
		}
		
		setTimeout('showEventsDay()', 0);
	}*/
}

function showWeek(week) {
	//d('function show week');
	showLoading(true);
	setTabsInactive();
	$('tabWeek').className = 'activeLink';
	
	hideVisibleEvents();
	currentView = 'week';
	
	if (week == null) {
		var week = previousSunday(currentDate);
	}
	
	currentDate.setTime(week.getTime());
	currentDate.setMinutes(0);
	currentDate.setHours(0);
	currentDate.setSeconds(0);
	setTimeout('updateWeekNav()', 0);
	
	getEventsMonth();
	
	if (viewType == 'calendar') {
		setTimeout('updateHeaderWeek()', 0);
		updateMiddleWeek();
	}
	else {
		// update header
		currentView = 'week';
		$('weekCodeDiv').style.display = 'none';
		setTimeout('updateHeaderAgendaMonth()', 0);
		setTimeout('updateMiddleAgendaMonth()', 0);
	}
}

function showDay(day) {
	//d('function show day');
	showLoading(true);
	setTabsInactive();
	$('tabDay').className = 'activeLink';

	hideVisibleEvents();
	currentView = 'day';
	
	if (day == null) {
		var day = currentDate.getDate();
	}
	
	currentDate.setDate(day);
	currentDate.setMinutes(0);
	currentDate.setHours(0);
	currentDate.setSeconds(0);
	
	setTimeout('updateDayNav()', 0);
	
	getEventsMonth();
	
	if (viewType == 'calendar') {
		setTimeout('updateHeaderDay()', 0);
		updateMiddleDay();
	}
	else {
		setTimeout('updateHeaderAgendaMonth()', 0);
		setTimeout('updateMiddleAgendaMonth()', 0);
	}
	
	/*setTimeout('updateDayNav()', 0);
	
	if (viewType == 'calendar') {
		setTimeout('updateHeaderDay()', 0);
		updateMiddleTimer = setTimeout('updateMiddleDay();', 0);
	}
	else {
		// update header
		var header = $('calendarTop');
		if (header != null) {
			str = '&nbsp;';
			header.innerHTML = str;
			Nifty("div.calendarTop", 'transparent tl', 'white');
		}
		
		// make middle blank
		var container = $('calendarMiddle');
		if (container != null) {
			str = '<div class="">';
			
			str += '</div>';
			container.innerHTML = str;
		}
		currentView = 'day';
	}*/
}

function putInMiddle(o) {
	o.style.left = screen_left() + Math.floor(get_screen_width() / 2) - Math.floor(o.offsetWidth / 2) + 'px';
}

function showLoading(show) {
	document.body.appendChild($('loading'));
	if (show) {
		$('loading').style.display = '';
		putInMiddle($('loading'));
	}
	else {
		$('loading').style.display = 'none';
	}
}

function setTabsInactive() {
	['tabMonth', 'tabWeek', 'tabDay'].each(function(e) {
		$(e).className = 'inactiveLink';
	});
}

function makeSlotsMonth(di, i, ymi) {
	// if there is an event for this date
	var eventHTML = ''
	if (eventItems[di] != null && eventItems[di].length) {
		eventItems[di].sort(eventSort);		// sort events
		if (eventSlots[di] == null) {
			eventSlots[di] = new Array();	// create event slot array for this day
			eventSlotsCount[di] = 0;		// start event slot count for this day
		}
		//d(di);
		// there is an event for this day
		for (var j = 0; j < eventItems[di].length; j++) {
			//d(''+''+'event for ' + di + eventItems[di][j].eventItemId);
			//d(''+visibleEvents[eventItems[di][j].eventId] + ' and ' + eventItems[di][j].calendarId);
			if (visibleEvents[eventItems[di][j].eventId] == null || visibleEvents[eventItems[di][j].eventId] == eventItems[di][j].calendarId) {
				visibleEvents[eventItems[di][j].eventId] = eventItems[di][j].calendarId;
				var openSlot = 0;
				var foundSlot = false;
				for (var k = 0; k < eventSlots[di].length && !foundSlot; k++) {
					openSlot = k;
					if (eventSlots[di][k] == null || eventSlots[di][k] == false) {
						foundSlot = true;
					}
				}
				if (!foundSlot) {
					openSlot = eventSlots[di].length;
				}
				
				var start = new Date();
				start.setTime(eventItems[di][j].eiStartTime * 1000);
				
				var end = new Date();
				end.setTime(eventItems[di][j].eiStopTime * 1000);
				
				var numMoreDays = end.getDay() - start.getDay();
				for (k = 0, tempDay = i; k <= numMoreDays; k++, tempDay = nextDay(tempDay)) {
					if (eventSlots[makeDateIndex(tempDay)] == null) {
						eventSlots[makeDateIndex(tempDay)] = new Array();
						eventSlotsCount[makeDateIndex(tempDay)] = 0;
					}
					eventSlots[makeDateIndex(tempDay)][openSlot] = eventItems[di][j];
					eventSlotsCount[makeDateIndex(tempDay)]++;
				}
				
				if (viewType == 'calendar') {
					eventHTML += positionEvent(di, eventItems[di][j], openSlot, makeDateIndex(end), numMoreDays, ymi);
				}
			}
		}
	}
	return eventHTML;
}

function showEventsMonth() {
	var di;
	clearAllSlots();
	//d('function show events month');
	//removeEvents();
	
	$('dayCodeDiv').style.display = 'none';
	$('weekCodeDiv').style.display = 'none';
	
	var ymi = makeYMI(currentDate);
	if (cacheMonthEvents[ymi] == null && viewType == 'calendar') {
		//d('new ymi array for ' + ymi);
		updateMiddleMonth(); // redraw the day blocks to the minimum height
		cacheMonthEvents[ymi] = new Array();
		//d('cache visible events');
		//d('(now run the loop month code)');
		// loop through each visible day for this calendar and check if there are events for the day
		
		var eventHTML = '';
		for (var i = firstSunday(), j = 0; i <= lastSaturday(); i = nextDay(i), j++) {
			di = makeDateIndex(i);
			eventHTML += makeSlotsMonth(di, i, ymi);
		}
		
		var beforeLength = Element.childElements($('eventHolder')).length;
		$('eventHolder').innerHTML += eventHTML;
		
		var childElements = Element.childElements($('eventHolder'));
		var afterLength = childElements.length;
		for (var i = beforeLength; i < afterLength; i++) {
			cacheMonthEvents[ymi].push(childElements[i].id);
			//d('cached ' + ymi + ' ' + i + ' ' + childElements[i].id);
		}
		
		// store calendar innerhtml
		//d('store calendar innerhtml');
		cacheCalendarCode[ymi] = $('calendarMiddle').innerHTML;

		//d('finished the loop');
	}
	else if (viewType == 'calendar') {
		//d('cache hit.. show cached events and day blocks');
		showCachedEvents();
	}
	
	if (viewType == 'agenda') {
		var str = '';
		var anyEvents = false;
		
		// for loop to make slots
		//d('MAKING SLOTS');
		for (var i = firstSunday(); i <= lastSaturday(); i = nextDay(i)) {
			di = makeDateIndex(i);
			makeSlotsMonth(di, i, ymi);
		}
		//d('CHECKING SLOTS');
		for (var i = firstOfMonth(); i <= lastOfMonth(); i = nextDay(i)) {
			di = makeDateIndex(i);
			// if there is an event for this date
			if (eventSlots[di] != null) {
				anyEvents = true;
				eventSlots[di].sort(eventSort);		// sort events
				
				str += '<div class="agendaLeft">';
				str += '<div class="leftDay">' + dayName[i.getDay()].substr(0,3).toUpperCase() + '</div>';
				str += '<div class="leftMonth">' + monthName[i.getMonth()].substr(0,3).toUpperCase() + '</div>';
				str += '<div class="leftDate">' + i.getDate() + '</div>';
				str += '</div>';
				str += '<div class="agendaRight"><div class="agendaBar"></div>';
				for (var j = 0; j < eventSlots[di].length; j++) {
					if (eventSlots[di][j] != null) {
						str += '<div class="title">' + eventSlots[di][j].title + '</div>';
						if (j == eventSlots[di].length - 1) {
							str += '<div class="secondNo">';
						}
						else {
							str += '<div class="second">'
						}
						if (eventSlots[di][j].location != '') {
							str +=  eventSlots[di][j].location + ' * ';
						}
						if (eventSlots[di][j].allDay == 1) {
							str += ' All day * ';
						}
						else {
							var start = new Date();
							start.setTime(eventSlots[di][j].startTime * 1000);
							var stop = new Date();
							stop.setTime(eventSlots[di][j].stopTime * 1000);
							str += ' ' + start.getHours12() + ':' + start.getMinutes2();
							if (start.getTime() != stop.getTime()) {
								str += ' to ' + stop.getHours12() + ':' + stop.getMinutes2();
							}
							str +=  ' * ';
						}
						str += '<a href="event.php?event=' + eventSlots[di][j].eventId + '">More Info</a>';
						str += '</div>';
					}
				}
				str += '</div><div class="clear"></div>';
			}
		}
		if (!anyEvents) {
			str = '<div class="noEvents">There are no events for this month.</div>';
		}
		//var container = $('calendarMiddle');
		var container = $('calendarMiddle');
		if (container != null) {
			container.innerHTML = str;
		}
	}
	
	//Nifty('div.eventDiv', 'transparent small', 'white');
	setTimeout('showLoading(false)', 100);
}

///

function showEventsWeek() {
	//d('function show events week');
	var di;
	clearAllSlots();
	//removeEvents();
	
	$('dayCodeDiv').style.display = 'none';
	
	// full day events loop
	// loop through each visible day for this calendar and check if there are events for the day
	if (viewType == 'calendar') {
		for (var i = currentDate; i <= nextSaturday(); i = nextDay(i)) {
			di = makeDateIndex(i);
			// if there is an event for this date
			if (fullDayEvents[di] != null) {
				fullDayEvents[di].sort(eventSort);		// sort events
	
				if (eventSlots[di] == null) {
					eventSlots[di] = new Array();	// create event slot array for this day
					eventSlotsCount[di] = 0;		// start event slot count for this day
				}
				
				// there is an event for this day
				for (var j = 0; j < fullDayEvents[di].length; j++) {
					//d(''+'event for ' + di + fullDayEvents[di][j].eventItemId);
					//d(''+visibleEvents[fullDayEvents[di][j].eventId] + ' and ' + fullDayEvents[di][j].calendarId);
					if (visibleEvents[fullDayEvents[di][j].eventId] == null || visibleEvents[fullDayEvents[di][j].eventId] == fullDayEvents[di][j].calendarId) {
						visibleEvents[fullDayEvents[di][j].eventId] = fullDayEvents[di][j].calendarId;
						var openSlot = 0;
						var foundSlot = false;
						for (var k = 0; k < eventSlots[di].length && !foundSlot; k++) {
							openSlot = k;
							if (eventSlots[di][k] == null || eventSlots[di][k] == false) {
								foundSlot = true;
							}
						}
						if (!foundSlot) {
							openSlot = eventSlots[di].length;
						}
						
						var start = new Date();
						start.setTime(fullDayEvents[di][j].eiStartTime * 1000);
						
						var end = new Date();
						end.setTime(fullDayEvents[di][j].eiStopTime * 1000);
						
						var numMoreDays = end.getDay() - start.getDay();
						for (k = 0, tempDay = i; k <= numMoreDays; k++, tempDay = nextDay(tempDay)) {
							if (eventSlots[makeDateIndex(tempDay)] == null) {
								eventSlots[makeDateIndex(tempDay)] = new Array();
								eventSlotsCount[makeDateIndex(tempDay)] = 0;
							}
							eventSlots[makeDateIndex(tempDay)][openSlot] = fullDayEvents[di][j];
							eventSlotsCount[makeDateIndex(tempDay)]++;
							$(makeDateIndex(tempDay)).style.height = eventSlotsCount[makeDateIndex(tempDay)] * 18 + 'px';
						}
						if (viewType == 'calendar') {
							positionEvent(di, fullDayEvents[di][j], openSlot, makeDateIndex(end), numMoreDays);
						}
					}
				}
			}
		}
		// timed events loop
		// loop through each visible day for this calendar and check if there are events for the day
		for (var i = currentDate; i <= nextSaturday(); i = nextDay(i)) {
			//alert(i);
			di = makeDateIndex(i);
			// if there is an event for this date
			if (timedEvents[di] != null) {
				timedEvents[di].sort(eventSort);		// sort events
	
				var block = new Array();
				for (var j = 0; j < timedEvents[di].length; j++) {
					if (visibleEvents[timedEvents[di][j].eventId] == null || visibleEvents[timedEvents[di][j].eventId] == timedEvents[di][j].calendarId) {
						visibleEvents[timedEvents[di][j].eventId] = timedEvents[di][j].calendarId;
						// || (block.length > 0 && timedEvents[di][j].startTime < timedEvents[di][j-1].stopTime)
						if (timedEvents[di][j].stopTime == timedEvents[di][j].startTime) {
							timedEvents[di][j].stopTime = parseInt(timedEvents[di][j].stopTime) + 3600;
						}
						if (block.length == 0) {
							//d(''+j + ' push because first');
							block.push(timedEvents[di][j]);
						}
						else {
							var pushed = false;
							for (var k = 0, klength = block.length; k < klength && !pushed; k++) {
								if (block[k].stopTime > timedEvents[di][j].startTime) {
									block.push(timedEvents[di][j]);
									//d(''+j + ' push because start before stop');
									pushed = true;
								}
							}
							if (!pushed) {
								if (viewType == 'calendar') {
									positionEventBlock(block);
								}
								block = new Array();
								block.push(timedEvents[di][j]);
								//d(''+j + 'position then push because starting new block');
							}
						}
						if (j == timedEvents[di].length - 1) {
							//d(''+j + ' position becuase last');
							if (viewType == 'calendar') {
								positionEventBlock(block);
							}
							block = new Array();
						}
					}
				}
			}
		}
	}
	if (viewType == 'agenda') {

		var str = '';
		var anyEvents = false;
		
		for (var i = firstOfWeek(); i <= lastOfWeek(); i = nextDay(i)) {
			di = makeDateIndex(i);
			makeSlotsMonth(di, i);
			
			// if there is an event for this date
			if (eventSlots[di] != null) {
				anyEvents = true;
				eventSlots[di].sort(eventSort);		// sort events
				
				str += '<div class="agendaLeft">';
				str += '<div class="leftDay">' + dayName[i.getDay()].substr(0,3).toUpperCase() + '</div>';
				str += '<div class="leftWeek">' + monthName[i.getMonth()].substr(0,3).toUpperCase() + '</div>';
				str += '<div class="leftDate">' + i.getDate() + '</div>';
				str += '</div>';
				str += '<div class="agendaRight"><div class="agendaBar"></div>';
				for (var j = 0; j < eventSlots[di].length; j++) {
					if (eventSlots[di][j] != null) {
						str += '<div class="title">' + eventSlots[di][j].title + '</div>';
						if (j == eventSlots[di].length - 1) {
							str += '<div class="secondNo">';
						}
						else {
							str += '<div class="second">'
						}
						if (eventSlots[di][j].location != '') {
							str +=  eventSlots[di][j].location + ' * ';
						}
						if (eventSlots[di][j].allDay == 1) {
							str += ' All day * ';
						}
						else {
							var start = new Date();
							start.setTime(eventSlots[di][j].startTime * 1000);
							var stop = new Date();
							stop.setTime(eventSlots[di][j].stopTime * 1000);
							str += ' ' + start.getHours12() + ':' + start.getMinutes2();
							if (start.getTime() != stop.getTime()) {
								str += ' to ' + stop.getHours12() + ':' + stop.getMinutes2();
							}
							str +=  ' * ';
						}
						str += '<a href="event.php?event=' + eventSlots[di][j].eventId + '">More Info</a>';
						str += '</div>';
					}
				}
				str += '</div><div class="clear"></div>';
			}
		}
		if (!anyEvents) {
			str = '<div class="noEvents">There are no events for this week.</div>';
		}
		var container = $('calendarMiddle');
		if (container != null) {
			container.innerHTML = str;
		}
	}
	//setTimeout("Nifty('div.eventDiv', 'transparent small', 'white')", 0);
	//setTimeout("Nifty('div.eventWeekDiv', 'transparent small fixed-height', 'white')", 0);
	setTimeout('showLoading(false)', 100);
}

//////////////////////////////////////////////////////////

function showEventsDay() {
	//d(''+'function show events day');
	var di;
	clearAllSlots();
	//removeEvents();
	
	$('weekCodeDiv').style.display = 'none';
	
	// full day events loop
	// loop through each visible day for this calendar and check if there are events for the day
	if (viewType == 'calendar') {
		for (var i = previousSunday(); i <= currentDate; i = nextDay(i)) {
			di = makeDateIndex(i);
			// if there is an event for this date
			if (fullDayEvents[di] != null) {
				fullDayEvents[di].sort(eventSort);		// sort events
	
				if (eventSlots[di] == null) {
					eventSlots[di] = new Array();	// create event slot array for this day
					eventSlotsCount[di] = 0;		// start event slot count for this day
				}
				
				// there is an event for this day
				for (var j = 0; j < fullDayEvents[di].length; j++) {
					//d(''+'event for ' + di + fullDayEvents[di][j].eventItemId);
					//d(''+visibleEvents[fullDayEvents[di][j].eventId] + ' and ' + fullDayEvents[di][j].calendarId);
					if (visibleEvents[fullDayEvents[di][j].eventId] == null || visibleEvents[fullDayEvents[di][j].eventId] == fullDayEvents[di][j].calendarId) {
						visibleEvents[fullDayEvents[di][j].eventId] = fullDayEvents[di][j].calendarId;
						var openSlot = 0;
						var foundSlot = false;
						for (var k = 0; k < eventSlots[di].length && !foundSlot; k++) {
							openSlot = k;
							if (eventSlots[di][k] == null || eventSlots[di][k] == false) {
								foundSlot = true;
							}
						}
						if (!foundSlot) {
							openSlot = eventSlots[di].length;
						}
						
						var start = new Date();
						start.setTime(fullDayEvents[di][j].eiStartTime * 1000);
						
						var end = new Date();
						end.setTime(fullDayEvents[di][j].eiStopTime * 1000);
						
						var numMoreDays = end.getDay() - start.getDay();
						for (k = 0, tempDay = i; k <= numMoreDays; k++, tempDay = nextDay(tempDay)) {
							if (eventSlots[makeDateIndex(tempDay)] == null) {
								eventSlots[makeDateIndex(tempDay)] = new Array();
								eventSlotsCount[makeDateIndex(tempDay)] = 0;
							}
							eventSlots[makeDateIndex(tempDay)][openSlot] = fullDayEvents[di][j];
							eventSlotsCount[makeDateIndex(tempDay)]++;
							//$(makeDateIndex(tempDay)).style.height = eventSlotsCount[makeDateIndex(tempDay)] * 18 + 'px';
							$(makeDateIndex(currentDate)).style.height = eventSlotsCount[makeDateIndex(tempDay)] * 18 + 'px';
						}
						
						if (viewType == 'calendar' && i.getTime() == currentDate.getTime()) {
							if (viewType == 'calendar') {
								positionEvent(di, fullDayEvents[di][j], openSlot, makeDateIndex(start), 0);
							}
						}
					}
				}
			}
		}
		
		// timed events loop
		// loop through each visible day for this calendar and check if there are events for the day
		var i = currentDate;
		di = makeDateIndex(i);
		// if there is an event for this date
		if (timedEvents[di] != null) {
			timedEvents[di].sort(eventSort);		// sort events
			//d(''+'sorted');
			var block = new Array();
			for (var j = 0; j < timedEvents[di].length; j++) {
				if (visibleEvents[timedEvents[di][j].eventId] == null || visibleEvents[timedEvents[di][j].eventId] == timedEvents[di][j].calendarId) {
					visibleEvents[timedEvents[di][j].eventId] = timedEvents[di][j].calendarId;
					// || (block.length > 0 && timedEvents[di][j].startTime < timedEvents[di][j-1].stopTime)
					if (timedEvents[di][j].stopTime == timedEvents[di][j].startTime) {
						timedEvents[di][j].stopTime = parseInt(timedEvents[di][j].stopTime) + 3600;
					}
					if (block.length == 0) {
						//d(''+j + ' push because first');
						block.push(timedEvents[di][j]);
					}
					else {
						var pushed = false;
						for (var k = 0, klength = block.length; k < klength && !pushed; k++) {
							if (block[k].stopTime > timedEvents[di][j].startTime) {
								block.push(timedEvents[di][j]);
								//d(''+j + ' push because start before stop');
								pushed = true;
							}
						}
						if (!pushed) {
							if (viewType == 'calendar') {
								positionEventBlock(block, 'day');
							}
							block = new Array();
							block.push(timedEvents[di][j]);
							//d(''+j + 'position then push because starting new block');
						}
					}
					if (j == timedEvents[di].length - 1) {
						//d(''+j + ' position becuase last');
						if (viewType == 'calendar') {
							positionEventBlock(block, 'day');
						}
						block = new Array();
					}
				}
			}
		}
	}
	if (viewType == 'agenda') {
		var str = '';
		var anyEvents = false;
		for (var i = firstOfDay(); i <= lastOfDay(); i = nextDay(i)) {
			di = makeDateIndex(i);
			makeSlotsMonth(di,i);
			// if there is an event for this date
			if (eventSlots[di] != null) {
				anyEvents = true;
				eventSlots[di].sort(eventSort);		// sort events
				
				str += '<div class="agendaLeft">';
				str += '<div class="leftDay">' + dayName[i.getDay()].substr(0,3).toUpperCase() + '</div>';
				str += '<div class="leftDay">' + monthName[i.getMonth()].substr(0,3).toUpperCase() + '</div>';
				str += '<div class="leftDate">' + i.getDate() + '</div>';
				str += '</div>';
				str += '<div class="agendaRight"><div class="agendaBar"></div>';
				for (var j = 0; j < eventSlots[di].length; j++) {
					if (eventSlots[di][j] != null) {
						str += '<div class="title">' + eventSlots[di][j].title + '</div>';
						if (j == eventSlots[di].length - 1) {
							str += '<div class="secondNo">';
						}
						else {
							str += '<div class="second">'
						}
						if (eventSlots[di][j].location != '') {
							str +=  eventSlots[di][j].location + ' * ';
						}
						if (eventSlots[di][j].allDay == 1) {
							str += ' All day * ';
						}
						else {
							var start = new Date();
							start.setTime(eventSlots[di][j].startTime * 1000);
							var stop = new Date();
							stop.setTime(eventSlots[di][j].stopTime * 1000);
							str += ' ' + start.getHours12() + ':' + start.getMinutes2();
							if (start.getTime() != stop.getTime()) {
								str += ' to ' + stop.getHours12() + ':' + stop.getMinutes2();
							}
							str +=  ' * ';
						}
						str += '<a href="event.php?event=' + eventSlots[di][j].eventId + '">More Info</a>';
						str += '</div>';
					}
				}
				str += '</div><div class="clear"></div>';
			}
		}
		if (!anyEvents) {
			str = '<div class="noEvents">There are no events for this day.</div>';
		}
		var container = $('calendarMiddle');
		if (container != null) {
			container.innerHTML = str;
		}
	}
	//setTimeout("Nifty('div.eventDiv', 'transparent small', 'white')", 0);
	//setTimeout("Nifty('div.eventDayDiv', 'transparent small fixed-height', 'white')", 0);
	setTimeout('showLoading(false)', 100);
}

//////////////////////////////////////////////////////////

function positionEventBlock(block, w) {
	var which = 'week';
	if (w != null && w == 'day') {
		which = 'day';
	}
	//d(''+'position function.... ' + block.length + ' events');
	// loop to find maximum number of overlays
	var numOverlays = 0;
	var tempOverlays = 0;
	for (var i = 0; i < block.length; i++) {
		tempOverlays = 0;
		for (var j = 0; j < i; j++) {
			if (block[j].stopTime > block[i].startTime) {
				tempOverlays++;
			}
		}
		if (tempOverlays > numOverlays) {
			numOverlays = tempOverlays;
		}
	}
	
	var daySpace;
	if (currentView == 'week') {
		var daySpace = $('weekCodeDiv').getElementsByClassName('timeSlot')[0].offsetWidth;
	}
	if (currentView == 'day') {
		var daySpace = $('dayCodeDiv').getElementsByClassName('timeSlot')[0].offsetWidth;
	}
	// = document.getElementsByClassName('timeSlot')[0].offsetWidth;//$('Sunday-0-0').offsetWidth;
	var spacing = daySpace / (numOverlays+1);
	var normalWidth = daySpace * .5;
	var lastWidth = daySpace * (1/(numOverlays+1)) - 2;
	var currentHighestSlot = 0;
	//d(''+spacing + ' ' + normalWidth + ' ' + lastWidth + ' ' + currentHighestSlot);
	for (var i = 0, ilength = block.length; i < ilength; i++) {
		// create div for event
		var eventWeekDiv = document.createElement('div');
		eventWeekDiv.className = 'eventWeekDiv';
		eventWeekDiv.id = 'eventItem-' + block[i].calendarId + '-' + block[i].eventItemId;

		var eventWeekDivTitle = document.createElement('div');
		var eventWeekDivContent = document.createElement('div');
		eventWeekDivTitle.className = 'title';
		eventWeekDivContent.className = 'content';
		eventWeekDiv.style.backgroundColor = '#' + block[i].color;
		eventWeekDivTitle.style.backgroundColor = '#' + darkenRgb(block[i].color, 30);
		
		// get time slot
		var temp = new Date();
		temp.setTime(block[i].startTime * 1000);
		var difference = temp.getMinutes() - previous15(temp);
		temp.setMinutes(previous15(temp));
		var realDayName = dayName[temp.getDay()];
		if (which == 'day') {
			realDayName = 'day';
		}
		var slot = $(realDayName + '-' + temp.getHours() + '-' + temp.getMinutes());
		//d(''+realDayName + '-' + temp.getHours() + '-' + temp.getMinutes());
		// only show this if slot exists.. won't exist if before 7am
		if (slot != null) {
			var p = Position.positionedOffset(slot);
			// calculate top position
			eventWeekDiv.style.top = (p[1] + difference - 3).toString() + 'px';
			// calculate left position by looping through the positioned blocks and checking available slots
			var foundSlot = false;
			
			for (var j = i-1; j >= 0 && !foundSlot; j--) {
				// if this block will fit below an existing block
				if (block[i].startTime >= block[j].stopTime && block[j].nextSlot == false) {
					foundSlot = true;
					block[j].nextSlot = true;
					block[i].slot = block[j].slot;
				}
			}
			if (!foundSlot) {
				// didn't find a slot so use currentHighestSlot and increment slot
				block[i].slot = currentHighestSlot++;
			}
			block[i].nextSlot = false;
			eventWeekDiv.style.left = (p[0]-1) + (block[i].slot * spacing) + 'px' ;
			// set width
			if (block[i].slot != numOverlays) {
				eventWeekDiv.style.width = normalWidth + 'px';
			}
			else {
				eventWeekDiv.style.width = lastWidth + 'px';
			}
			
			// calculate the height
			temp.setTime(block[i].stopTime * 1000);
			var difference2 = temp.getMinutes() - previous15(temp);
			temp.setMinutes(previous15(temp));
			var endSlot = $(realDayName + '-' + temp.getHours() + '-' + temp.getMinutes());
			var p2 = Position.positionedOffset(endSlot);
			var newHeight = p2[1] + difference2 - p[1] - difference - 1;
			eventWeekDiv.style.height = newHeight + 'px';
			
			// set onclick handler
			var eventItemId = block[i].eventItemId;
			setWeekEventClick(eventWeekDiv, block[i]);
			
			// set display content
			if (block[i].tsUpdated > threeDaysAgo) {
				eventWeekDivTitle.innerHTML = '! ' + block[i].title;
			}
			else {
				eventWeekDivTitle.innerHTML = block[i].title;
			}
			eventWeekDivContent.innerHTML = block[i].description;
			
			
			eventWeekDiv.appendChild(eventWeekDivTitle);
			eventWeekDiv.appendChild(eventWeekDivContent);
			
			// append to calendar
			$('eventHolder').appendChild(eventWeekDiv);
		}
	}
}

function setWeekEventClick(div, event) {
	//d(''+'function set week event click');
	div.onclick = function() {
		//d(''+'clicked');
		showEventDetails(event, this);
	};
}

// input: date object
// return: integer of the previous interval of 15 minutes
function previous15(date) {
	if (date.getMinutes() >= 45) {
		return 45;
	}
	else if (date.getMinutes() >= 30) {
		return 30;
	}
	else if (date.getMinutes() >= 15) {
		return 15;
	}
	else {
		return 0;
	}
}

var verticalSpacing = 18;
var activeViewAllDiv = null;
var overViewAllDiv = false;
function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
	}
	return [curleft,curtop];
}
function positionEvent(di, event, openSlot, di2, numMoreDays, ymi) {
	//d(''+'position ' + event.title + ' at ' + di + ' in slot ' + openSlot + ' through ' + di2);
	
	var dayBlock = $(di);
	if (openSlot > 4) {
		dayBlock.style.height = ((openSlot+1) * verticalSpacing + 2).toString() + 'px';
	}
	
	var p = Position.positionedOffset(dayBlock);
	if (!netscape()) {
		p[1] -= 14;
	}
	
	var divHTML = '<div class="eventDiv" id="eventItem-' + event.calendarId + '-' + event.eventItemId + '-' + ymi + '"';
	divHTML += ' style="left: ' + p[0] + 'px; top:' + (p[1] + (verticalSpacing * openSlot)).toString() + 'px; width:' + (right_side($(di2)) - from_left($(di)) - 12 ).toString() + 'px; background-color:#' + event.color + ';"';
	divHTML += ' onclick="showEventDetails(eventsByItemId['+event.eventItemId+'], this)"';
	divHTML += '>';
	
	if (event.tsUpdated > threeDaysAgo) {
		divHTML += '! ';
	}
	
	divHTML += event.title;
	divHTML += '</div>';
	
	return divHTML;
}

function diToDate(di) {
	var parts = di.split('/');
	var tempDate = new Date();
	tempDate.setFullYear(parts[0], parts[1], parts[2]);
	return tempDate;
}

function setViewAllClick(eventDiv, di) {
	eventDiv.onclick = function() {
		//d(''+'display cached view all');
		
		// hide other detail box if it is there
		if (activeDetailsDiv != null) {
			removeDetails(activeDetailsDiv);
			activeDetailsDiv = null;
		}
		activeViewAllDiv = cacheViewAllEvents[di];
		document.body.onmousedown = overViewAllCheck;
		
		cacheViewAllEvents[di].style.display = '';
		//document.body.appendChild(cacheViewAllEvents[di]);
		activeViewAllDiv = cacheViewAllEvents[di];
	}
}

/* This function is called when an event div cannot fit in the day.
 * It takes the date index yyyy/m(m)/d(d) as input.
 * It hides the 5th event box (element 4) obtained from the eventSlots object.
 * A 'View All' div is put where slot 5 normally is.
 * If an event being hidden is spanned from a previous day in the week, call the function
 * with that date index.
 */
function showViewAllDiv(di, event, openSlot, di2, numMoreDays) {
	if (eventSlots[di][4] == null) {
		return;
	}
	
	// check if the view all div has been created for this day
	if (showViewAllSet[di] != null) {
		$('viewAll' + di).innerHTML = 'View events ' + eventSlotsCount[di];	// update this day's total events and return
		return;
	}
	showViewAllSet[di] = true;	// mark this day as having a view all events div
	$('eventItem-' + eventSlots[di][4].calendarId + '-' + eventSlots[di][4].eventItemId).style.display = 'none';	// hide the 5th event of the day
	
	// check if the beginning of the date being hidden starts on a previous day
	// if so, create a view all events div for that day
	var t = new Date();
	t.setTime(eventSlots[di][4].eiStartTime * 1000 + timeDifference);
	t = makeDateIndex(t);
	if (t != di) {
		showViewAllDiv(t, event, openSlot, di2, numMoreDays);
	}
	
	// generate the html for the view all div
	var eventDiv = document.createElement('div');
	eventDiv.id = 'viewAll' + di;
	eventDiv.className = 'eventDiv';
	eventDiv.name = di;
	
	var p = Position.positionedOffset($(di));
	//eventDiv.style.left = from_left($(di)) + 'px' ;
	eventDiv.style.left = p[0] + 'px';
	//eventDiv.style.top = (from_top($(di)) + (verticalSpacing * 4)).toString() + 'px';
	eventDiv.style.top = (p[1] + (verticalSpacing * 4)).toString() + 'px';
	eventDiv.style.width = (right_side($(di)) - from_left($(di)) - 12 ).toString() + 'px';
	eventDiv.style.background = '#000000';
	//eventDiv.style.zIndex = '6';
	
	setViewAllClick(eventDiv, di);
	
	eventDiv.innerHTML = 'View all ' + eventSlotsCount[di];
	eventDiv.style.textAlign = 'center';
	//document.body.appendChild(eventDiv);
	$('eventHolder').appendChild(eventDiv);
	cacheMonthEvents[makeYMI(currentDate)].push(eventDiv);
}

var activeDetailsDiv = null;
var overDetails = false;
function showEventDetails(event, e) {
	//d(''+event.eventId);
	var detailsDiv = document.createElement('div');
	
	detailsDiv.className = 'detailsDiv';
	detailsDiv.style.display = 'none';
	//detailsDiv.style.zIndex = '8';
	
	// generate innerHTML
	var str = '';
	str += '<div class="detailsX" onclick="setOutDetails(); overDetailsCheck();">X</div>';
	str += '<div class="detailsTitle" style="color:#'+ event.color +';">' + event.title + '</div>';
	str += '<div class="detailsDate">';
	var startDisplay = new Date();
	startDisplay.setTime(event.eiStartTimeDisplay * 1000 + timeDifference);
	var stopDisplay = new Date();
	stopDisplay.setTime(event.eiStopTimeDisplay * 1000 + timeDifference);
	
	// date
	str += dayName[startDisplay.getDay()] + ', ' + monthName[startDisplay.getMonth()] + ' ' + startDisplay.getDate();
	if (makeDateIndex(startDisplay) != makeDateIndex(stopDisplay)) {
		str += ' to ' + dayName[stopDisplay.getDay()] + ', ' + monthName[stopDisplay.getMonth()] + ' ' + stopDisplay.getDate();
	}
	
	// time
	if (event.tba == '0') {
		if (event.allDay == 0) {
			if (makeTimeDisplay(startDisplay) == makeTimeDisplay(stopDisplay)) {
				str += ' at ' + makeTimeDisplay(startDisplay);
			}
			else {
				str += ' from ' + makeTimeDisplay(startDisplay) + ' to ' + makeTimeDisplay(stopDisplay);
			}
		}
	}
	else {
		str += ' (time TBA)';
	}
	
	//str += event.startTime;
	str += '</div>';
	if (event.tsUpdated > threeDaysAgo) {
		str += '<div class="detailsRed">Event has been revised</div>';
	}
	str += '<div class="detailsText">' + event.location + '</div>';
	str += '<div class="detailsText">' + event.description + '</div>';
	str += '<div><a href="event.php?eventId=' + event.eventId + '">View event details and activities</a>';
	str += '<div class="detailsExport"><a href="calendarExportEvent.php?eventId=' + event.eventId + '">Export</a></div>';
	detailsDiv.innerHTML = str;
	document.body.appendChild(detailsDiv);
	
	detailsDiv.style.visibility = 'hidden';
	detailsDiv.style.display = '';

	var tempDate = new Date();
	tempDate.setTime(event.eiStartTime * 1000);
	var di = makeDateIndex(tempDate);
	var top = Position.cumulativeOffset(e)[1];
	var left = Position.cumulativeOffset(e)[0];
	
	top -= detailsDiv.offsetHeight;
	if (currentView != 'day') {
		left += $(di).offsetWidth + 40;
	}
	
	var w = detailsDiv.offsetWidth;
	if (left + detailsDiv.offsetWidth > screen_right()) {
		left = from_left(e) - detailsDiv.offsetWidth - 20;//$(di).offsetWidth;
	}
	while (top < screen_top()) {
		top += $(di).offsetHeight / 2;
	}
	
	detailsDiv.style.display = 'none';
	detailsDiv.style.visibility = 'visible';

	detailsDiv.style.left = left + 'px';
	detailsDiv.style.top = top + 'px';
	// hide other detail box if it is there
	if (activeDetailsDiv != null) {
		removeDetails(activeDetailsDiv);
		activeDetailsDiv = null;
	}
	
	activeDetailsDiv = detailsDiv;
	
	if (!overViewAllDiv) {
		document.body.onmousedown = overDetailsCheck;
	}
	detailsDiv.onmouseover = setOverDetails;
	detailsDiv.onmouseout = setOutDetails;
	
	// show new detail box
	Element.show(detailsDiv);
	/*new Effect.Appear(detailsDiv, {duration:.5, afterFinish: function() {
		
	}});*/
}

function calendarExport() {
	var url = 'calendarExport.php?';
	for (var i in loadedCalendars) {
		if (loadedCalendars[i]) {
			url += '&calendarIds[]=' + i;
		}
	}
	
	if (currentView == 'month') {
		url += '&view=month';
	}
	else if (currentView == 'week') {
		url += '&view=week';
	}
	else {
		url += '&view=day';
	}
	
	url += '&ts=' + (currentDate.getTime()/1000);
	
	location.href = url;
}

function setOverViewAll() {
	//d(''+'function set over view all');
	overViewAllDiv = true;
}

function setOutViewAll() {
	//d(''+'function set out view all');
	overViewAllDiv = false;
}

function overViewAllCheck() {
	//d(''+'function over view all check ' + overViewAllDiv);
	if (activeDetailsDiv != null && !overDetails) {
		removeDetails(activeDetailsDiv);
		activeDetailsDiv = null;
	}
	//d(''+activeViewAllDiv + ' ' + overViewAllDiv + ' ' + overDetails);
	if (activeViewAllDiv != null && !overViewAllDiv && !overDetails) {
		Element.hide(activeViewAllDiv);
		activeViewAllDiv = null;
	}
}

/*function removeViewAll(detailsDiv) {
	//d(''+'function remove view all');
	if (detailsDiv != null) {
		Element.hide(detailsDiv);
		//new Effect.Fade(detailsDiv, {duration:.5, afterFinish: function() {
			detailsDiv.parentNode.removeChild(detailsDiv);
		//}});
	}
}*/

function setOverDetails() {
	//d(''+'function set over details');
	overDetails = true;
}

function setOutDetails() {
	//d(''+'function set out details');
	overDetails = false;
}

function overDetailsCheck() {
	//d(''+'function over details check');
	if (activeDetailsDiv != null && !overDetails) {
		removeDetails(activeDetailsDiv);
		activeDetailsDiv = null;
	}
}

function removeDetails(detailsDiv) {
	//d(''+'function remove details');
	if (detailsDiv != null) {
		overDetails = false;
		document.body.onmousedown = overViewAllCheck;
		Element.hide(detailsDiv);
		//new Effect.Fade(detailsDiv, {duration:.5, afterFinish: function() {
			detailsDiv.parentNode.removeChild(detailsDiv);
			overDetails = false;
			//overViewAllDiv = false;
			document.body.onmousedown = overViewAllCheck;
		//}});
	}
}

function clearAllSlots() {
	eventSlots = new Object();
	eventSlotsCount = new Object();
	showViewAllSet = new Object();
	visibleEvents = new Object();
}

function removeEvents() {
	//d(''+'function remove events');
	var e = document.getElementsByClassName('eventDiv');
	for (var i = 0, len = e.length; i < len; i++) {
		e[i].parentNode.removeChild(e[i]);
	}
	
	e = document.getElementsByClassName('eventWeekDiv');
	for (var i = 0, len = e.length; i < len; i++) {
		e[i].parentNode.removeChild(e[i]);
	}
}

function hideVisibleEvents() {
	//d(''+'function hide visible events');
	var e = $('eventHolder');
	for (var i = 0, len = e.childNodes.length; i < len; i++) {
		e.childNodes[i].style.display = 'none';
	}
}

function showCachedEvents() {
	var ymi = makeYMI(currentDate);
	//d('function show cached events');
	for (var i = 0, len = cacheMonthEvents[ymi].length; i < len; i++) {
		//d('show cached ' + ymi + ' ' + i);
		Element.show(cacheMonthEvents[ymi][i]);
	}
}

/*****************************************************/

function rememberCalendars() {
	$('loading').innerHTML = 'Saving . . .';
	showLoading(true);
	var sendingIds = new Array();
	for (var i in loadedCalendars) {
		sendingIds.push(i);
	}
	var url = 'calendarRemember.php';
	var pars = 'calendarIds=' + sendingIds.join(',');
	var myAjax = new Ajax.Request( url, { method: 'get', parameters: pars, onComplete: rememberCalendarsP });
}

function rememberCalendarsP(response) {
	$('loading').innerHTML = 'Saved . . .';
	setTimeout(function() {
		showLoading(false);
		$('loading').innerHTML = 'Loading . . .';
	 }, 1000);
}

/*****************************************************/

function eventSort(a, b) {
	return (a.eiStartTime - b.eiStartTime);
}
function showNextMonth(num) {
	if (num == null) {
		num = 1;
	}
	showLoading(true);
	//d(''+'function show next month');
	showMonth(currentDate.getMonth() + parseInt(num));
}

function showPreviousMonth(num) {
	if (num == null) {
		num = 1;
	}
	showLoading(true);
	//d(''+'function show previous month');
	showMonth(currentDate.getMonth() - num);
}

function showPreviousWeek() {
	currentDate.setDate(currentDate.getDate() - 7);
	showWeek();
}

function showNextWeek() {
	currentDate.setDate(currentDate.getDate() + 7);
	showWeek();
}

function showPreviousDay() {
	showDay(currentDate.getDate() - 1);
}

function showNextDay() {
	showDay(currentDate.getDate() + 1);
}

function previousSunday() {
	var tempDate = new Date();
	tempDate.setTime(currentDate.getTime());
	if (tempDate.getDay() > 0) {
		tempDate.setDate(tempDate.getDate() - tempDate.getDay());
	}
	return tempDate;
}

function nextSaturday() {
	var tempDate = new Date();
	tempDate.setTime(currentDate.getTime());
	if (tempDate.getDay() < 6) {
		tempDate.setDate(tempDate.getDate() + 6 - tempDate.getDay());
	}
	return tempDate;
}

function firstSunday() {
	var tempDate = new Date();
	tempDate.setFullYear(currentDate.getFullYear(), currentDate.getMonth(), 1);
	tempDate.setFullYear(tempDate.getFullYear(), tempDate.getMonth(), 1 - tempDate.getDay());
	return tempDate;
}

function firstOfMonth() {
	var tempDate = new Date();
	tempDate.setFullYear(currentDate.getFullYear(), currentDate.getMonth(), 1);
	return tempDate;
}

function firstOfWeek() {
	var tempDate = new Date();
	tempDate.setFullYear(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() - currentDate.getDay() );
	//alert(tempDate);
	return tempDate;
}

function firstOfDay() {
	return currentDate;
}

function lastOfMonth() {
	var tempDate = new Date();
	tempDate.setFullYear(currentDate.getFullYear(), currentDate.getMonth() + 1, 0);
	return tempDate;
}

function lastOfWeek() {
	var tempDate = new Date();
	tempDate.setFullYear(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() + ( 7 - currentDate.getDay()) );
	//alert(tempDate);
	return tempDate;
}

function lastOfDay() {
	return currentDate;
}

function lastSaturday() {
	var tempDate = new Date();
	tempDate.setFullYear(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
	tempDate.setFullYear(tempDate.getFullYear(), tempDate.getMonth()+1, 0);
	tempDate.setFullYear(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() + 6 - tempDate.getDay());
	//document.write('last sat = ' + tempDate + '<br>');
	return tempDate;
}

function nextDay(timestamp) {
	var dateObject = new Date();
	dateObject.setTime(timestamp);
	dateObject.setFullYear(dateObject.getFullYear(), dateObject.getMonth(), dateObject.getDate() + 1);
	return dateObject;
}

function next15(timestamp) {
	var dateObject = new Date();
	dateObject.setTime(timestamp);
	dateObject.setMinutes(dateObject.getMinutes() + 15);
	return dateObject;
}
function nextHour(timestamp) {
	var dateObject = new Date();
	dateObject.setTime(timestamp);
	dateObject.setHours(dateObject.getHours() + 1);
	return dateObject;
}


function previousDay(timestamp) {
	var dateObject = new Date();
	dateObject.setTime(timestamp);
	dateObject.setFullYear(dateObject.getFullYear(), dateObject.getMonth(), dateObject.getDate() - 1);
	return dateObject;
}

function nextWeek(timestamp) {
	var dateObject = new Date();
	dateObject.setTime(timestamp);
	dateObject.setFullYear(dateObject.getFullYear(), dateObject.getMonth(), dateObject.getDate() + 7);
	return dateObject;
}

function makeTimeDisplay(d) {
	return d.getHours12() + ':' + d.getMinutes2() + d.getAmpm();
}