﻿(function ($) {
	$.fn.eventCalendar = function (options) {
		var defaults = {
			xmlPath: ''
		};
		options = $.extend(defaults, options);
		return this.each(function () {
			// global vars
			var $ThisDiv = $(this);
			var dateList = [];
			var weekday = ["M", "T", "O", "T", "F", "L", "S"];

			var currentDate = new Date().clearTime();

			var selectedDate = null;

			var dateQuery = $.getQueryString({
				ID: "date"
			})
			if (dateQuery != "undefined" && dateQuery != "0.1.0" && dateQuery != "0.0.0" && dateQuery != "") {
				var dateQuery_arr = dateQuery.split(".");
				selectedDate = new Date(Number(dateQuery_arr[0]), Number(dateQuery_arr[1]) - 1, Number(dateQuery_arr[2])).clearTime();
			}else{
				$(".ChooseAll", $ThisDiv).addClass("selected");					
			}

			var calendarDate = (selectedDate != null) ? new Date(selectedDate.getFullYear(), selectedDate.getMonth()).clearTime() : new Date().clearTime();
			calendarDate.setDate(1);

			var lastDate = null;
			var firstDate = null;

			var htmlString = "";

			////////////////////////////////////////
			// get days of month
			function daysInMonth(month, year) {
				var m = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
				if (month != 2) {
					return m[month - 1];
				}
				if (year % 4 != 0) {
					return m[1];
				}
				if (year % 100 == 0 && year % 400 != 0) {
					return m[1];
				}
				return m[1] + 1;
			}
			// calculate WeekDiff
			function getWeekDiff(date, year) {
				var jan_4 = new Date(year, 0, 4).clearTime();
				var weekDay_1 = (jan_4.getDay() + 6) % 7;
				var month_1 = Math.floor(0.01 + jan_4.getTime() / 864e5 - weekDay_1);
				var dateT = Math.floor(0.01 + date.getTime() / 864e5);
				return Math.floor(1 + (dateT - month_1) / 7);
			}
			// calculate CalendarWeek
			function getCalendarWeek(year, month, day) {
				var date = new Date(year, month - 1, day).clearTime();
				var nextYear = year + 1;
				var week = getWeekDiff(date, nextYear);
				while (week < 1) {
					nextYear--;
					week = getWeekDiff(date, nextYear);
				}
				return week;
			}

			// chooseDate
			function chooseDate(year, month, day) {
				if (typeof(day) == "undefined" || year == null) {
					selectedDate = null;
					ChangePageQuerystring("date", "");
					$(".ChooseAll", $ThisDiv).addClass("selected");					
				} else {
					$(".ChooseAll", $ThisDiv).removeClass("selected");		
					selectedDate = new Date().clearTime();
					selectedDate.setFullYear(year, month, day);
					ChangePageQuerystring("date", year + "." + (month + 1) + "." + day)
				}
			}

			////////////////////////////////////////
			// ADD
			// addDates
			function addDates() {
				var startDay = calendarDate.getDay();
				startDay = (startDay > 0) ? startDay - 1 : 6;
				var date = 1;
				var $Dates = $(".Dates li", $ThisDiv)
				$Dates.each(function (index) {
					if (startDay <= index && date <= (daysInMonth(calendarDate.getMonth() + 1, calendarDate.getFullYear() + 1))) {
						$(this).text(date);
						$(this).attr("date", date);
						$(this).addClass("active");
						date++;
						// mark current day
						if ((calendarDate.getMonth() == currentDate.getMonth()) && (calendarDate.getFullYear() == currentDate.getFullYear()) && ($(this).attr("date") == currentDate.getDate())) {
							$(this).addClass("currentDate");
						}
						//
						if (selectedDate != null) {
							if ((calendarDate.getMonth() == selectedDate.getMonth()) && (calendarDate.getFullYear() == selectedDate.getFullYear()) && ($(this).attr("date") == selectedDate.getDate())) {
								$(this).addClass("selected");
							}
						}
						//
						if (index % 7 == 0) {
							$(this).append("<span>" + getCalendarWeek(calendarDate.getFullYear(), calendarDate.getMonth() + 1, $(this).attr("date")) + "</span>")
						}
					}
				});
				
				var $Actives = $(".Dates li.active", $ThisDiv)
				$Actives.click(function () {
					$Dates.removeClass("selected");
					$(this).addClass("selected");
					selectedDate = new Date(calendarDate.getFullYear(), calendarDate.getMonth(), $(this).attr("date")).clearTime()
					chooseDate(calendarDate.getFullYear(), calendarDate.getMonth(), $(this).attr("date"));
				});

				$Actives.hover(
				function () {
					$(this).addClass("hover");
				},
				function () {
					$(this).removeClass("hover");
				});
			}
			// addEvents
			function addEvents() {
				var $Dates = $(".Dates li.active", $ThisDiv)

				var tempDate = new Date(calendarDate.getFullYear(), calendarDate.getMonth(), 1).clearTime();
				
				$Dates.each(function (index) {
					tempDate.setDate($(this).attr("date"));
					for (var i = 0; i < dateList.length; i++) {		
						if (tempDate.between(dateList[i].start, dateList[i].end)){					
							$(this).addClass("event");
						}
					}
				});
			}

			//changeMonth
			function changeMonth(newMonth) {
				var newYear = calendarDate.getFullYear()
				if (newMonth > 11) {
					newMonth = 0
					newYear += 1
				} else if (0 > newMonth) {
					newMonth = 11
					newYear -= 1
				}
				calendarDate.setFullYear(newYear);
				calendarDate.setMonth(newMonth);
				fillHTML();
			}

			// clean HTML month
			function cleanHTMLMonth() {
				$(".Dates li", $ThisDiv).each(function () {
					$(this).text("").removeAttr("class").removeAttr("date");
					$(this).unbind();
				});
				$(".CalendarTop h4", $ThisDiv).text("");
				$(".NextButton", $ThisDiv).show();
				$(".PrevButton", $ThisDiv).show();
			}

			// fillHTML
			function fillHTML() {
				cleanHTMLMonth();
				$(".CalendarTop span.MonthName", $ThisDiv).text(calendarDate.getMonthName() + " " + calendarDate.getFullYear());
				$(".weekDays li", $ThisDiv).each(function (index) {
					$(this).text(weekday[index]);
				});
				if (firstDate != null) {
					if (firstDate.getFullYear() == calendarDate.getFullYear() && firstDate.getMonth() == calendarDate.getMonth()) {
						$(".PrevButton", $ThisDiv).hide();
					}
				}
				addDates();
				addEvents();
			}
			// parse XML
			function parseXML() {
				var cityQuery = $.getQueryString({
					ID: "city"
				})
				cityQuery = (cityQuery != "undefined") ? "?city=" + cityQuery : "";

				try {
					// parse XML
					$.ajax({
						type: "GET",
						url: options.xmlPath + cityQuery,
						dataType: "xml",
						success: function (xml) {
							var $Dates = $(xml).find('date')
							if($Dates.length > 0){
								$(xml).find('date').each(function (i) {
									dateList[i] = {}
	
									dateList[i].start = new Date().clearTime();
									var startdate_array = $(this).attr("startdate").split(".");
									dateList[i].start.setFullYear(Number(startdate_array[0]), Number(startdate_array[1]) - 1, Number(startdate_array[2]));
	
									dateList[i].end = new Date().clearTime();
									var end_array = $(this).attr("enddate").split(".");
									dateList[i].end.setFullYear(Number(end_array[0]), Number(end_array[1]) - 1, Number(end_array[2]));
								});
								dateList.sort(function (a, b) {
									return (a.start - b.start)
								});
								firstDate = dateList[0].start;
								//
								dateList.sort(function (a, b) {
									return (a.end - b.end)
								});
								lastDate = dateList[dateList.length - 1].end;
							}
							fillHTML();
						}
					});
				}
				catch(err) {
					fillHTML();
				}
			}

			// write HTML
			function writeHTML() {
				var i
				htmlString += '<ul class="weekDays floatContainer">';
				for (i = 0; i < 7; i++) {
					htmlString += "<li>" + weekday[i] + "</li>";
				}
				htmlString += '</ul><ul class="Dates floatContainer">';
				for (i = 0; i < 42; i++) {
					htmlString += '<li></li>';
				}
				htmlString += '</ul>';

				$(".Calendar", $ThisDiv).html(htmlString);

				$(".ChooseAll", $ThisDiv).click(function () {
					chooseDate(null);
					changeMonth(currentDate.getMonth());
				});
				$(".PrevButton", $ThisDiv).click(function () {
					changeMonth(calendarDate.getMonth() - 1);
				});
				$(".NextButton", $ThisDiv).click(function () {
					changeMonth(calendarDate.getMonth() + 1);
				});

				parseXML();
			}

			writeHTML();
		});
	};
})(jQuery);