//==============================================================================
// Globals

var CalendarAllowEdit = (typeof(WebsiteManager) != "undefined");
var CalendarEditorHeight = 60;

var DayNames = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");

var MonthNames = new Array("January", "February", "March", "April", "May", "June",
	"July", "August", "September", "October", "November", "December");


// Gets the Top and Left coordinates of the given object
function GetTopLeftOf(object) {
	var toReturn = new Object();
	toReturn.Top = 0;
	toReturn.Left = 0;
	while (object != null) {
		toReturn.Top += object.offsetTop - object.scrollTop;
		toReturn.Left += object.offsetLeft - object.scrollLeft;
		object = object.offsetParent;
	}
	return toReturn;
}


function GetSessionCookie(name) {
	var cookies = document.cookie.split(";");
	for(var i in cookies) {
		var j = cookies[i].indexOf(name + "=");
		if (j >= 0) {
			return cookies[i].substr(j + name.length + 1);
		}
	}
	return null;
}

function SetSessionCookie(name, value) {
	var d = new Date();
	d.setFullYear(d.getFullYear() + 5);
	document.cookie = name + "=" + value + "; path=/";
}

function CreateXmlRequest() {
    return (navigator.appName == "Microsoft Internet Explorer") ?
	new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
}

function PostfixDate(date) {
	var postfix = "th";
	if (date < 4 || date > 20) {
		var end = date % 10;
		if (end == 1) {
			postfix = "st";
		} else if (end == 2) {
			postfix = "nd";
		} else if (end == 3) {
			postfix = "rd";
		}
	}
	return date + postfix;
}

var WebRootUrl = ROOT_URL;
var GetURL = WebRootUrl + "_design/plugins/calendar/data/";
var SetURL = WebRootUrl + "_design/calendar.cgi";


//==============================================================================
// Calendar

var editingDate = null;
var editValue = null;
function EditDay(date) {
	if (editingDate != null) {
		if (date == editingDate) {
			return;
		}
		if (!confirm("You are currently editing the "
			+ PostfixDate(editingDate)
			+ ". Would you like to undo your changes and edit the "
			+ PostfixDate(date) + " instead?")) {
			return;
		}
		CancelEditDay();
	}

	editingDate = date;

	var editorDiv = document.all["dayValue" + date];
	editValue = editorDiv.innerHTML;

	var height = editorDiv.offsetHeight > CalendarEditorHeight ?
		editorDiv.offsetHeight: CalendarEditorHeight;
	var html = "<textarea id=\"editor\"";
	html += " wrap=\"virtual\" style=\"font-size: 8pt; font-family: Arial;";
	html += "width: " + editorDiv.offsetWidth + ";";
	html += " height: " + height + ";";
	html += "\">";
	html += editValue;
	html += "</textarea>\n";
	html += "<div style=\"font-size: 8pt; text-align: center;\">";
	html += "<a href=\"javascript: SaveDay();\" style=\"color: #0000FF;\">Save</a>";
	html += " | ";
	html += "<a href=\"javascript: CancelEditDay();\" style=\"color: #0000FF;\">Cancel</a>";
	html += "</div>";
	editorDiv.innerHTML = html;
}

function CancelEditDay() {
	if (editingDate != null) {
		var dayDiv = document.all["dayValue" + editingDate];
		dayDiv.innerHTML = editValue;
		editingDate = null;
	}
}

function SaveDay() {
	ShowStatus("Saving...");
	// Set timeout to force status to show (TODO: research some more)
	setTimeout(PerformSave, 1);
}

function PerformSave() {
	var date = (Calendar.date.getMonth() + 1) + "/"
		+ editingDate + "/" + Calendar.date.getFullYear();
	var value = encodeURIComponent(document.all["editor"].value);

	var request = CreateXmlRequest();
	request.open("POST", SetURL, false);
	request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	request.send("date=" + date + "&html=" + value);
	if (request.status == 200) {
		editingDate = null;
		Calendar._Refresh();
	} else {
		alert("Error saving");
	}
	HideStatus();
}

function ShowStatus(status) {
	var calendarDiv = document.all["calendar"];
	var statusDiv = document.all["statusDiv"];
	var calendarTopLeft = GetTopLeftOf(calendarDiv);
	statusDiv.style.top = calendarTopLeft.Top;
	statusDiv.style.left = calendarTopLeft.Left;
	statusDiv.style.width = calendarDiv.offsetWidth;
	var height = calendarDiv.offsetHeight;
	var pad = Math.round(height / 2);
	statusDiv.style.paddingTop = pad;
	statusDiv.style.height = (height - pad);
	statusDiv.style.zIndex = 100;
	statusDiv.style.visibility = "visible";
	statusDiv.innerHTML = "<center><div style=\"width: 150; background-color: #FFFFFF; border: #000000 1px solid; padding: 5px;\">" + status + "</div></center>";
}

function HideStatus() {
	var statusDiv = document.all["statusDiv"];
	statusDiv.style.zIndex = -100;
	statusDiv.style.visibility = "hidden";
}

function GetMonthSelectHtml(year) {
	var html = "<table style=\"background-color: #FFFFFF;\"><tr><td colspan=\"3\" align=\"center\"><b>";
	html += year;
	html += "</b></td></tr><tr>";
	for(var i = 0, j = 0; i < 12; i++) {
		if ((i % 3) == 0) {
			html += "</tr><tr>";
		}
		html += "<td align=\"center\" style=\"font-size: 9pt; padding: 3px;\">";
		var isOff = (year != Calendar.Year
				|| i != Calendar.date.getMonth());
		if (isOff) {
			html += "<a href=\"javascript:MonthSelected(";
			html += year + "," + i;
			html += ");\" style=\"color: #0000FF;\">";
		}
		html += MonthNames[i];
		if (isOff) {
			html += "</a>";
		}
		html += "</td>";
	}
	html += "</tr></table>";
	return html;
}

function SelectMonth() {
	var calendarDiv = document.all["calendar"];
	var monthDiv = document.all["monthSelectDiv"];

	var html = "<table cellspacing=\"0\" cellpadding=\"0\" style=\"border: #666666 1px solid;\">";
	html += "<tr><td colspan=\"3\" align=\"right\" style=\"background-color: #CCCCCC; border-bottom: #CCCCCC 1px solid; cursor: pointer; cursor: hand; font-size: 8pt; padding-right: 2px;\" onClick=\"CloseSelectMonth();\">Cancel</td></tr>";
	html += "<tr><td>";
	html += GetMonthSelectHtml(Calendar.Year - 1);
	html += "</td><td style=\"border-left: #CCCCCC 1px solid; border-right: #CCCCCC 1px solid;\">";
	html += GetMonthSelectHtml(Calendar.Year);
	html += "</td><td>";
	html += GetMonthSelectHtml(Calendar.Year + 1);
	html += "</td></tr></table>";

	monthDiv.innerHTML = html;
	var calendarTopLeft = GetTopLeftOf(calendarDiv);
	monthDiv.style.top = calendarTopLeft.Top + document.all["calendarTitle"].offsetHeight;
	monthDiv.style.left = calendarTopLeft.Left + 4;
	monthDiv.style.width = calendarDiv.offsetWidth - 10;
	monthDiv.style.height = calendarDiv.offsetHeight - 10;
	monthDiv.style.zIndex = 100;
	monthDiv.style.visibility = "visible";
}

function MonthSelected(year, month) {
	Calendar.SetYearMonth(year, month);
	CloseSelectMonth();
}

function CloseSelectMonth() {
	var monthDiv = document.all["monthSelectDiv"];
	monthDiv.style.zIndex = -100;
	monthDiv.style.visibility = "hidden";
}

// Static reference to singleton instance
var Calendar = new _Calendar();

function _Calendar(year, month) {

	// Set default internal date for first of the current calendar month
	this.date = new Date();
	this.date.setDate(1);

	// Properties
	this.TableBorder = 0;
	this.TableCellspacing = -1;
	this.TableCellpadding = -1;
	this.Month = MonthNames[this.date.getMonth()];
	this.Year = this.date.getFullYear();

	// Methods
	this.SetYearMonth = _Calendar_SetYearMonth;
	this.NextMonth = _Calendar_NextMonth;
	this.PreviousMonth = _Calendar_PreviousMonth;
	this.Render = _Calendar_Render;
	this._GetHtml = _Calendar_GetHtml;
	this._Refresh = _Calendar_Refresh;

	// See if there's a cookie with the year & month
	if (year == null && month == null) {
		// TODO
		var yearMonth = GetSessionCookie("CalendarMonth");
		if (yearMonth != null) {
			var a = yearMonth.split("-");
			if (a.length == 2) {
				year = a[0];
				month = a[1];
			}
		}
	}

	// Set the year and month
	this.SetYearMonth(year, month);
}

function _Calendar_SetYearMonth(year, month) {
	if (year != null && year > 0) {
		if (month != null) {
			this.date.setFullYear(year, month);
		} else {
			this.date.setFullYear(year);
		}

		this.Year = this.date.getFullYear();
		this.Month = MonthNames[this.date.getMonth()];

		// Set a cookie with the year & month
		SetSessionCookie("CalendarMonth", year + "-" + month);

		this._Refresh();
	}
}

function _Calendar_NextMonth() {
	this.SetYearMonth(this.date.getFullYear(), this.date.getMonth() + 1);
}

function _Calendar_PreviousMonth() {
	this.SetYearMonth(this.date.getFullYear(), this.date.getMonth() - 1);
}

function _Calendar_Render() {
	document.writeln("<div id=\"calendar\">");
	document.writeln("</div>");
	document.writeln("<div id=\"statusDiv\" style=\"position: absolute; visibility: hidden; z-index: -100; text-align: center;\"></div>");
	document.writeln("<div id=\"monthSelectDiv\" style=\"position: absolute; visibility: hidden; z-index: -100; padding-top: 6px; text-align: center;\"></div>");
	this._Refresh();
}

function _Calendar_Refresh() {

	if (document.all["calendar"] != null) {
		document.all["calendar"].innerHTML = this._GetHtml();

		// Get the calendar
		var now = new Date().getTime(); // Timestamp to force refresh
		var request = CreateXmlRequest();
		request.open("GET", GetURL + this.date.getFullYear() + (this.date.getMonth() + 1) + ".xml?now=" + now, false);
		request.send(null);
		if (request.status == 200) {
			var dayNodes = request.responseXML.getElementsByTagName("Day");
			for(var i = 0; i < dayNodes.length; i++) {
				var day = dayNodes[i].getAttribute("date");
				document.all["dayValue" + day].innerHTML
					= dayNodes[i].firstChild.nodeValue;
			}
		}
	}
}

function _Calendar_GetHtml() {

	var border = "";
	if (this.TableBorder != null && this.TableBorder > 0) {
		border = " border=\"" + this.TableBorder + "\"";
	}
	var cellspacing = "";
	if (this.TableCellspacing >= 0) {
		cellspacing = " cellspacing=\"" + this.TableCellspacing + "\"";
	}
	var cellpadding = "";
	if (this.TableCellpadding >= 0) {
		cellpadding = " cellpadding=\"" + this.TableCellpadding + "\"";
	}
	var html = "<table" + border + cellspacing + cellpadding + " class=\"calendarTable\">\n";

	// Month & year header
	html += "<tr>\n";
	html += "<td colspan=\"7\" class=\"calendarTitleRow\">\n";
	html += " <table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"><tr>\n";
	html += "  <td class=\"calendarPrevNextCell\" onClick=\"Calendar.PreviousMonth();\">&lt;</td>\n";
	html += "  <td id=\"calendarTitle\" class=\"calendarTitleCell\">" + this.Month + " " + this.Year + "</td>\n";
	html += "  <td class=\"calendarPrevNextCell\" onClick=\"Calendar.NextMonth();\">&gt;</td>\n";
	html += " </tr></table>\n";
	html += "</td>\n";
	html += "</tr>\n";

	// Day column headers
	html += "<tr>\n";
	for (var iDay = 0; iDay < 7; iDay++) {
		html += "<td class=\"calendarDayHeaderCell\">" + DayNames[iDay] + "</td>\n";
	}
	html += "</tr>";

	var today = new Date();
	var isCurrentMonth = (this.date.getFullYear() == today.getFullYear()
		&& this.date.getMonth() == today.getMonth());

	// Determine days in current month
	var dayCount;
	var dateCopy = new Date(this.date.getFullYear(), this.date.getMonth(), 28);
	do {
		dayCount = dateCopy.getDate();
		dateCopy.setDate(dayCount + 1);
	} while (dateCopy.getMonth() == this.date.getMonth());

	var calendarDay = -1;
	var historyClass = "";
	if (!isCurrentMonth
		&& (this.date.getFullYear() < today.getFullYear()
			|| (this.date.getFullYear() == today.getFullYear()
			&& this.date.getMonth() < today.getMonth()))) {
		historyClass = "History";
	}

	for (var iWeek = 0; iWeek < 6; iWeek++) {
		html += "<tr>\n";
		for (var iDay = 0; iDay < 7; iDay++) {

			if (iWeek == 0 && iDay == this.date.getDay()) {
				calendarDay = 1;
			}
			if (calendarDay > dayCount) {
				calendarDay = -1;
			}

			var todayClass = "";
			if (isCurrentMonth) {
				historyClass = ((calendarDay < today.getDate()) ? "History" : "");
				todayClass = ((calendarDay == today.getDate()) ? "Today" : "");
			}

			html += "<td class=\"calendarDayCell";
			if (calendarDay > 0) {
				html += historyClass + todayClass + "\" id=\"day" + calendarDay + "\">\n";
				if (CalendarAllowEdit) {
					html += "<a href=\"javascript: EditDay(" + calendarDay + ");\" style=\"color: #0000FF;\">";
				}
				html += calendarDay;
				if (CalendarAllowEdit) {
					html += "</a>\n";
				}

				// TODO: Events for the day
				html += "<div id=\"dayValue" + calendarDay;
				html += "\" class=\"calendarDayDiv\"></div>\n";

				calendarDay++;
			} else {
				html += "OtherMonth\">\n";
			}
			html += "</td>\n";
		}
		html += "</tr>\n";
	}

	html += "</table>\n";
	return html;
}
