/**
 * @author steinmetz
 */

// initialize calendar
var grid, list;
var myUrl = "" + window.location;
var BASEURL = myUrl.substring(0, myUrl.indexOf('/calendar') + 9);
var AJAXURL = BASEURL + '/ajax/';
var gridList = "grid";
var recurring = new Array();
var today;

function in_array(arr, el) {
	for (var i = 0; i < arr.length; i++) {
		if (arr[i] == el) {
			return true;
		}
	}
	return false;
}

$(function() {
	// set shading before drawing grid
	var shadeDays = [false, false, false, false, false, false, false];
	if ($('#shade-days').val() != '') {
		var days = $('#shade-days').val().toString().split(',');
		for (var i = 0; i < days.length; i++) {
			shadeDays[days[i]] = true;
		}
	}
	
	today = new Date();
	if ($.trim($('#month-showing').val()) != '') {
		var date = $('#month-showing').val().split(',');
		var month = parseInt(date[0], 10);
		var year = parseInt(date[1], 10);
	} else {
		var month = today.getMonth() + 1;
		var year = today.getFullYear();
	}
	grid = $('#calendar-grid');
	$(grid).ccccalendar({
		year: year,
		month: month,
		shadeToday: ($('#highlight-today').val() == 1) ? true : false,
		shadeDays: shadeDays,
		isAdmin: ($("#mainCalendar").attr("isAdmin") == 1) ? true : false,
		dateChanged: function(event, data) {
			// change the date in the go-to drop downs
			$('#go-to-month').val((data[0] < 10) ? '0' + data[0] : data[0]);
			$('#go-to-year').val(data[1]);
			
			$('#view-as').val(0);
			
			// hide cluetip
			$(document).trigger('hideCluetip');
			
			// get events
			getEvents(data[0], data[1]);
		},
		calendarReady: function(event, data) {
			// get events
			getEvents(data[0], data[1]);
		},
		eventAdded: function(event, data) {
			//console.log(data);
		}
	});
	list = $('#list');
	$(list).ccccalendarlist({
		year: year,
		month: month,
		shadeToday: ($('#highlight-today').val() == 1) ? true : false,
		shadeDays: shadeDays,
		isAdmin: ($('#mainCalendar').attr('isAdmin') == 1) ? true : false,
		dateChanged: function(event, data) {
			// change the date in the go-to drop downs
			$('#go-to-month').val((data[0] < 10) ? '0' + data[0] : data[0]);
			$('#go-to-year').val(data[1]);
			
			$('#view-as').val(1);
			
			// get events
			getEvents(data[0], data[1]);
		},
		listReady: function(event, data) {
		}
	});
	
	// set up date change drop downs
	var month = today.getMonth() + 1;
	$('#go-to-month').val((month < 10) ? '0' + month : month);
	$('#go-to-year').val(today.getFullYear());
	$('#go-to-change').click(function(event) {
		if (gridList == "grid") {
			$(grid).ccccalendar('changeDate', parseInt($('#go-to-month').val(), 10), parseInt($('#go-to-year').val(), 10));
		} else {
			$(list).ccccalendarlist('changeDate', parseInt($('#go-to-month').val(), 10), parseInt($('#go-to-year').val(), 10));
		}
		$('#month-showing').val($('#go-to-month').val() + ', ' + $('#go-to-year').val());
	});
	$('#view-as-change').click(function(event) {
		var showDate = $('#month-showing').val().split(',');
		if ($('#view-as').val() == 0) {
			if (gridList != "grid") {
				gridList = "grid";
				$('#list').hide();
				$('#calendar-grid').show();
				$(grid).ccccalendar('changeDate', showDate[0], showDate[1]);
			}
		} else {
			if (gridList != "list") {
				gridList = "list";
				$('#calendar-grid').hide();
				$('#list').show();
				$(list).ccccalendarlist('changeDate', showDate[0], showDate[1]);
				$(document).trigger('hideCluetip');
			}
		}
	});
	
	// fix for IE 6 select box bug
	if (($.browser.msie) && (parseInt($.browser.version, 10) < 7)) {
		var footer = $('#footer-go-to-box');
		$(footer).remove();
		$('#calendar').before(
			$('<div />').append(footer)
		);
		$('#go-to-change').click(function(event) {
			if (gridList == "grid") {
				$(grid).ccccalendar('changeDate', parseInt($('#go-to-month').val(), 10), parseInt($('#go-to-year').val(), 10));
			} else {
				$(list).ccccalendarlist('changeDate', parseInt($('#go-to-month').val(), 10), parseInt($('#go-to-year').val(), 10));
			}
			$('#month-showing').val($('#go-to-month').val() + ', ' + $('#go-to-year').val());
		});
		$('#view-as-change').click(function(event) {
			var showDate = $('#month-showing').val().split(',');
			if ($('#view-as').val() == 0) {
				if (gridList != "grid") {
					gridList = "grid";
					$('#list').hide();
					$('#calendar-grid').show();
					$(grid).ccccalendar('changeDate', showDate[0], showDate[1]);
				}
			} else {
				if (gridList != "list") {
					gridList = "list";
					$('#calendar-grid').hide();
					$('#list').show();
					$(list).ccccalendarlist('changeDate', showDate[0], showDate[1]);
				}
			}
		});
	}
});

function getEvents(month, year) {
	$.ajax({
		type: 'GET',
		url: AJAXURL + 'getEvents/' + ((month < 10) ? '0' + month : month) + '/' + year,
		async: false,
		timeout: 30000,
		dataType: "json",
		cache: false,
		success: function(data){
			recurring = new Array();
			
			var date = new Date(year, month, 1);
			
			// draw recurring events
			processEvents(month, year, date.getDay(), data);
			
			// initialize cluetip
			if (gridList == "grid") {
				initializeCluetips();
			}
			
			$('#month-showing').val(month + ',' + year);
		},
		error: function(){
			$("#errors").html("Unable to load calendar");
		}
	});
}

function processEvents(month, year, firstDay, events) {
	var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
	if ((year % 4) == 0) {
		daysInMonth[1] = 29;
	}
	
	for (var key in events) {
		var event = events[key];
		var startDate = event.startDate.split('-');
		for (var x in startDate) {
			startDate[x] = parseInt(startDate[x], 10);
		}
		if (parseInt(event.recurs) == 1) {
			var recurrence = event.recurrence;
			recurrence.type = parseInt(recurrence.type, 10);
			recurrence.frequency = parseInt(recurrence.frequency, 10);
			recurrence.numTimes = parseInt(recurrence.numTimes, 10);
			var endDate = recurrence.repeatEndDate.split('-');
			for (var x in endDate) {
				endDate[x] = parseInt(endDate[x], 10);
			}
			if (event.recurrence.ignoreDates) {
				var ignoreDates = event.recurrence.ignoreDates.split(';');
			} else {
				var ignoreDates = new Array();
			}
			switch (recurrence.type) {
				// on the...
				case 1:
					processOccursOn(month, year, endDate, recurrence, event, ignoreDates);
				break;
				// daily
				case 2:
					if (startDate[0] == year) {
						if (startDate[1] == month) {
							var i = startDate[2];
							var end = endDate[2];
							if (month != endDate[1]) {
								end = daysInMonth[(month - 1)];
							}
							while (i <= end) {
								if (!in_array(ignoreDates, year + '-' + ((month < 10) ? '0' + month : month) + '-' + ((i < 10) ? '0' + i : i))) {
									addEvent(month, i, year, event);
								}
								i += recurrence.frequency;
							}
						} else {
							var numDays = countDaysMultiMonth(startDate, month, year);
							var go = recurrence.frequency - (numDays % recurrence.frequency);
							var end = endDate[2];
							if (month != endDate[1]) {
								end = daysInMonth[(month - 1)];
							}
							while (go <= end) {
								if (!in_array(ignoreDates, year + '-' + ((month < 10) ? '0' + month : month) + '-' + ((go < 10) ? '0' + go : go))) {
									addEvent(month, go, year, event);
								}
								go += recurrence.frequency;
							}
						}
					} else {
						var numDays = countDaysMultiYear(startDate, endDate, month, year);
						var go = recurrence.frequency - (numDays % recurrence.frequency);
						if (year == endDate[0]) {
							var end = endDate[2];
							if (month != endDate[1]) {
								end = daysInMonth[(month - 1)];
							}
						} else {
							end = daysInMonth[(month - 1)];
						}
						while (go <= end) {
							if (!in_array(ignoreDates, year + '-' + ((month < 10) ? '0' + month : month) + '-' + ((go < 10) ? '0' + go : go))) {
								addEvent(month, go, year, event);
							}
							go += recurrence.frequency;
						}
					}
				break;
				// weekly
				case 3:
					if (startDate[0] != year) {
						var numDays = countDaysMultiYear(startDate, endDate, month, year);
						var firstEvent = (7 * recurrence.frequency) - (numDays % (7 * recurrence.frequency));
						var eventDate = new Date(year, (month - 1), firstEvent);
					} else {
						if (startDate[1] != month) {
							var numDays = countDaysMultiMonth(startDate, month, year);
							var firstEvent = (7 * recurrence.frequency) - (numDays % (7 * recurrence.frequency));
							var eventDate = new Date(startDate[0], (month - 1), firstEvent);
						} else {
							var eventDate = new Date(startDate[0], (startDate[1] - 1), startDate[2]);
							var firstEvent = startDate[2];
						}
					}
					var days = recurrence.occursOn.toString().split(',');
					for (var x in days) {
						days[x] = parseInt(days[x]);
					}
					if (eventDate.getDay() != days[0]) {
						if (days[0] < eventDate.getDay()) {
							firstEvent += ((days[0] + 7) - eventDate.getDay());
						} else {
							firstEvent += (days[0] - eventDate.getDay());
						}
					}
					if (firstEvent <= daysInMonth[(month - 1)]) {
						var next = firstEvent;
						var day = 0;
						if (recurrence.numTimes > 0) {
							var count = 0;
						}
						while (next <= daysInMonth[(month - 1)]) {
							if (month == endDate[1]) {
								if (next > endDate[2]) {
									break;
								}
							}
							if (!in_array(ignoreDates, year + '-' + ((month < 10) ? '0' + month : month) + '-' + ((next < 10) ? '0' + next : next))) {
								addEvent(month, next, year, event);
							}
							if (days.length > 1) {
								day++;
								if (day == days.length) {
									day = 0;
									next += ((days[0] + 7) - days[(days.length - 1)]) + ((recurrence.frequency - 1) * 7);
								} else {
									next += (days[day] - days[day - 1]);
								}
							} else {
								next += (recurrence.frequency * 7);
							}
							if (recurrence.numTimes > 0) {
								count++;
								if (count == recurrence.numTimes) {
									break;
								}
							}
						}
					}
				break;
				// monthly
				case 4:
					// @TODO check that month fits within frequency
					var check = month - (startDate[1] % recurrence.frequency);
					if (check < 1) {
						check += 12;
					}
					if ((check % recurrence.frequency) == 0) {
						if (year == endDate[0]) {
							if (month == endDate[1]) {
								if (startDate[2] <= endDate[2]) {
									if (!in_array(ignoreDates, year + '-' + ((month < 10) ? '0' + month : month) + '-' + ((startDate[2] < 10) ? '0' + startDate[2] : startDate[2]))) {
										addEvent(month, startDate[2], year, event);
									}
								}
							} else {
								if (!in_array(ignoreDates, year + '-' + ((month < 10) ? '0' + month : month) + '-' + ((startDate[2] < 10) ? '0' + startDate[2] : startDate[2]))) {
									addEvent(month, startDate[2], year, event);
								}
							}
						} else {
							if (!in_array(ignoreDates, year + '-' + ((month < 10) ? '0' + month : month) + '-' + ((startDate[2] < 10) ? '0' + startDate[2] : startDate[2]))) {
								addEvent(month, startDate[2], year, event);
							}
						}
					}
				break;
				// yearly
				case 5:
					var occursOn = recurrence.occursOn.split(',');
					var definedEndDate = event.endDate.split('-');
					for (var i in definedEndDate) {
						definedEndDate[i] = parseInt(definedEndDate[i] , 10);
					}
					// yearly on specific date(s)
					if (occursOn.length == 1) {
						if (month == startDate[1]) {
							addEvent(month, startDate[2], year, event);
						} else if (month == definedEndDate[1]) {
							addEvent(month, 1, year, event);
						}
					// yearly on specific day of specific week during the month
					} else {
						recurrence.frequency = parseInt(occursOn[1]);
						recurrence.occursOn = parseInt(occursOn[2]);
						if (parseInt(occursOn[0], 10) == month) {
							processOccursOn(month, year, endDate, recurrence, event, ignoreDates);
						}
					}
				break;
			}
			recurring.push(event.itemId);
		} else {
			addEvent(month, startDate[2], year, event);
		}
	}
	
	// check if list is empty and if so display a message
	if (gridList == "list") {
		if ($('.listBlock:visible', list).length == 0) {
			$(list).append(
				$('<div />').css({textAlign: 'center', fontWeight: 'bold'}).text("There are currently no events planned for this month").attr('id', 'list-no-events')
			);
		}
	}
}

function processOccursOn(month, year, endDate, recurrence, event, ignoreDates) {
	if (gridList == "grid") {
		if (month == endDate[1]) {
			if ($(grid).ccccalendar('getBlockDate', row, recurrence.occursOn) > endDate[2]) {
				return;
			}
		}
		if (recurrence.frequency != 5) {
			var row = 0;
			if (!$(grid).ccccalendar('blockHasDate', row, recurrence.occursOn)) {
				row++;
			}
			row += recurrence.frequency - 1;
		} else {
			var row = 5;
			while (!$(grid).ccccalendar('blockHasDate', row, recurrence.occursOn)) {
				row--;
			}
		}
		var day = $(grid).ccccalendar('getBlockDate', row, recurrence.occursOn);
		if (!in_array(ignoreDates, year + '-' + ((month < 10) ? '0' + month : month) + '-' + ((day < 10) ? '0' + day : day))) {
			$(grid).ccccalendar('addEventToBlock', row, recurrence.occursOn, event);
		}
	} else {
		var date = new Date(year, (month - 1), 1);
		var dayOfWeek = date.getDay();
		if (recurrence.frequency != 5) {
			var start = 1 + (7 * (recurrence.frequency - 1));
		} else {
			var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
			if ((year % 4) == 0) {
				daysInMonth[1] = 29;
			}
			if ((month == 2) && ((year % 4) != 0)) {
				var start = 22;
			} else {
				var start = 29;
			}
		}
		if (dayOfWeek == recurrence.occursOn) {
			var day = start;
		} if (dayOfWeek < recurrence.occursOn) {
			var day = start + (recurrence.occursOn - dayOfWeek);
			if (day > daysInMonth[(month - 1)]) {
				day -= 7;
			}
		} else {
			var day = start - (dayOfWeek - recurrence.occursOn);
			if (day < 1) {
				day += 7;
			}
		}
		if (!in_array(ignoreDates, year + '-' + ((month < 10) ? '0' + month : month) + '-' + ((day < 10) ? '0' + day : day))) {
			$(list).ccccalendarlist('addEvent', day, event);
		}
	}
}

function addEvent(month, day, year, event) {
	// event is only one day
	if (event.startDate == event.endDate) {
		if (gridList == "grid") {
			$(grid).ccccalendar('addEvent', month, day, year, event);
		} else {
			$(list).ccccalendarlist('addEvent', day, event);
		}
	// event spans multiple days
	} else {
		var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
		if ((year % 4) == 0) {
			daysInMonth[1] = 29;
		}
		var endDate = event.endDate.split('-');
		var startDate = event.startDate.split('-');
		for (var i in endDate) {
			endDate[i] = parseInt(endDate[i], 10);
			startDate[i] = parseInt(startDate[i], 10);
		}
		for (var i = ((month == startDate[1]) ? day : 1); i <= ((month == endDate[1]) ? endDate[2] : daysInMonth[(month - 1)]); i++) {
			if (gridList == "grid") {
				$(grid).ccccalendar('addEvent', month, i, year, event);
			} else {
				$(list).ccccalendarlist('addEvent', i, event);
			}
		}
	}
}

function initializeCluetips() {
	$('a.clueTip').cluetip({
		width: '255',
		positionBy: 'mouse',
		local: true,
		attribute: 'rel',
		titleAttribute: 'title',
		hoverClass: 'default',
	    sticky: true,
	    mouseOutClose: false,
	    activation: 'click',//'mouseover',  /* click or mouseover */
		closePosition: 'title',
	    dropShadow: true,
	    dropShadowSteps: '3', /* Size of drop shadow, override default */
	    onShow: function(ct, c){
			// Load delete button listener
			$("img.deleteEvent").unbind('click');
			$("img.deleteEvent").click(function() {
				var deleteId = $(this).attr("id").replace("delete_","");
				if (confirm('Are you sure you want to delete this event?')) {
					// check to see if this is a recurring event
					var item = $(this).parent().parent().attr('id').substring(1).split('_');
					if (in_array(recurring, item[0])) {
						addIgnore = {
							calId: item[0],
							date: item[1].substring(0, 4) + '-' + item[1].substring(4, 6) + '-' + item[1].substring(6, 8)
						};
						$('#recurring-event-delete-prompt').dialog('open');
					} else {
						deleteEvent(deleteId);
					}
				}
				$("#cluetip").hide();
			});
			// add edit button listener
			$('img.editEvent').unbind('click');
			$('img.editEvent').click(function(event) {
				var item = $(this).parent().parent().attr('id').substring(1).split('_');
				showAddEditEvent(item[1].substring(0, 4) + '-' + item[1].substring(4, 6) + '-' + item[1].substring(6, 8), 'edit', item[0]);
			});
		},
	    waitImage: true,
		closeText: '<img src="/resources/common/icons/iconic/white/x_alt_12x12.png" id="cluetip-close-img" alt="Close" title="Close Window" style="border:0px;" />'
	});
}

function countDaysMultiYear(startDate, endDate, month, year) {
	var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
	var numDays = 0;
	if (startDate[1] == 2) {
		if ((startDate[0] % 4) == 0) {
			numDays = 29 - startDate[2];
		} else {
			numDays = 28 - startDate[2];
		}
	} else {
		numDays = daysInMonth[(startDate[1] - 1)] - startDate[2];
	}
	for (var i = (startDate[1] + 1); i <= 12; i++) {
		if (i == 2) {
			if ((startDate[0] % 4) == 0) {
				numDays += 29;
			} else {
				numDays += 28;
			}
		} else {
			numDays += daysInMonth[(i - 1)];
		}
	}
	for (var i = 0; i < ((year - startDate[0]) - 1); i++) {
		if (((startDate[0] + i) % 4) == 0) {
			numDays += 366;
		} else {
			numDays += 365;
		}
	}
	for (var i = 1; i < month; i++) {
		if (i == 2) {
			if ((startDate[0] % 4) == 0) {
				numDays += 29;
			} else {
				numDays += 28;
			}
		} else {
			numDays += daysInMonth[(i - 1)];
		}
	}
	
	return numDays;
}

function countDaysMultiMonth(startDate, month, year) {
	var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
	if ((year % 4) == 0) {
		daysInMonth[1] = 29;
	}
	var numDays = daysInMonth[(startDate[1] - 1)] - startDate[2];
	for (var i = (startDate[1] + 1); i < month; i++) {
		numDays += daysInMonth[(i - 1)];
	}
	
	return numDays;
}

function moveBack(event) {
	var monYr = $("#month-showing").val().split(",");
	var mon = parseInt(monYr[0], 10);
	var yr = parseInt(monYr[1], 10);
	if ((mon == 1) && (yr == 2009)) {
		return;
	}
	mon -= 1;
	if (mon == 0) {
		mon = 12;
		yr -= 1;
	}
	if (gridList == "grid") {
		$(grid).ccccalendar('changeDate', mon, yr);
	} else {
		$(list).ccccalendarlist('changeDate', mon, yr);
	}
}

function moveForward(event) {
	var monYr = $("#month-showing").val().split(",");
	var mon = parseInt(monYr[0], 10);
	var yr = parseInt(monYr[1], 10);
	mon += 1;
	if(mon == 13) {
		mon = 1;
		yr += 1;
	}
	if (gridList == "grid") {
		$(grid).ccccalendar('changeDate', mon, yr);
	} else {
		$(list).ccccalendarlist('changeDate', mon, yr);
	}
}

function printCalendar() {
	var monYr = $("#month-showing").val().split(",");
	var mon = parseInt(monYr[0], 10);
	var yr = parseInt(monYr[1], 10);
	var printWindow = window.open(BASEURL + '/print/' + mon + '/' + yr, "printWin", "resizable=yes,width=800,height=600,toolbar=yes,location=yes,scrollbars=yes,menubar=yes,status=yes,directories=yes");
}

