FSite2.calendars = new Object();

FSite2.extendCalendar = function(calendarElement, params)
{
	if (calendarElement.calendarObject)
		return;
	calendarID = calendarElement.getAttribute('calendar');
	if (!calendarID && calendarElement.id)
		calendarID = calendarElement.id + '_calendar';
	else if (!calendarID)
		return;
	var cal;
	if (FSite2.calendars[calendarID])
	{
		cal = FSite2.calendars[calendarID];
		for (i = 0, j = 0; i < cal.focusElements.length; i++)
			if (!cal.focusElements[i].parentNode || !cal.focusElements[i].parentNode.parentNode)
			{
				cal.focusElements[i] = null;
				j++;
			}
		if (i && (j == i))
		{
			FSite2.calendars[calendarID] = null
			cal = null;
		}
	}
	if (!cal)
	{
		cal = new FSite2.Calendar(calendarID, params);
		FSite2.calendars[calendarID] = cal;
	}
	cal.appendFocusElement(calendarElement);
	calendarElement.calendarObject = cal;
	if (calendarElement.onfocus)
		calendarElement._onfocus_cal = calendarElement.onfocus;
	if (calendarElement.onblur)
		calendarElement._onblur_cal = calendarElement.onblur;
	calendarElement.onfocus = function() {
		this.calendarObject.showCalendar();
		if (this._onfocus_cal)
			this._onfocus_cal();
	}
	calendarElement.onblur = function() {
		this.calendarObject.hideCalendar();
		if (this._onblur_cal)
			this._onblur_cal();
	}
}

FSite2.removeCalendars = function(node)
{
	if (!node)
		node = document.body;
	var cals = node.getElementsByTagName('*');
	for (var x = 0; x < cals.length; x++)
		if (FSite2.calendars[cals[x].id])
			delete FSite2.calendars[cals[x].id];
		else if (cals[x].calendarObject)
			delete FSite2.calendars[cals[x].calendarObject.containerID];
}

FSite2.Calendar = function(containerID, params)
{
	this.containerID = containerID;
	if (params.calendarClass)
		this.className = params.calendarClass;
	this.currentDate = new Date();
	this.currentDate.setHours(0);
	this.currentDate.setMinutes(0);
	this.currentDate.setSeconds(0);
	this.currentDate.setMilliseconds(0);
	this.currentMonth = this.currentDate.getMonth();
	this.currentYear = this.currentDate.getFullYear();
	this.monthsNames = params.calendarMonths;
	if (params.calendarDays)
		this.daysNames = params.calendarDays;
	this.monthsCount = params.calendarMonthsCount?params.calendarMonthsCount:1;
	this.minDate = null;
	this.maxDate = null;
	this.focusElements = new Array();
	this.closeText = params.calendarClose?params.calendarClose:false;
	if (typeof params.calendarOnInit == 'function')
	{
		this._oninit = params.calendarOnInit;
		this.oninit = function() {
			if (!this._oninit_called) this._oninit();
			this._oninit_called = true;
		};
	}
	if (params.calendarOnChange)
		this.onchange = params.calendarOnChange;
	return this;
}

FSite2.Calendar.prototype.appendFocusElement = function(newElement)
{
	if (typeof newElement == 'object')
	{
		this.focusElements[this.focusElements.length] = newElement;
	}
}

FSite2.Calendar.prototype.setDate = function(newDate, dontCallOnChange)
{
	if (typeof newDate == 'object')
	{
		newDate.setHours(0);
		newDate.setMinutes(0);
		newDate.setSeconds(0);
		newDate.setMilliseconds(0);
		var change = true;
		if (this.minDate && (newDate.valueOf() < this.minDate.valueOf()))
			change = false;
		if (this.maxDate && (newDate.valueOf() > this.maxDate.valueOf()))
			change = false;
		if (change)
		{
			this.currentDate = newDate;
			this.currentMonth = this.currentDate.getMonth();
			this.currentYear = this.currentDate.getFullYear();
		}
		if (!dontCallOnChange && (typeof this.onchange == 'function'))
			this.onchange();
		if (change && this.container)
			this.buildCalendar();
		return change;
	}
	return false;
}

FSite2.Calendar.prototype.setDay = function(newDay)
{
	var current = new Date(this.currentDate);
	current.setDate(newDay);
	return this.setDate(current);
}

FSite2.Calendar.prototype.setMonth = function(newMonth)
{
	var current = new Date(this.currentDate);
	current.setMonth(newMonth);
	return this.setDate(current);
}

FSite2.Calendar.prototype.setYear = function(newYear)
{
	var current = new Date(this.currentDate);
	current.setFullYear(newYear);
	return this.setDate(current);
}

FSite2.Calendar.prototype.setMinDate = function(newMinDate, dontCallOnChange)
{
	if (typeof newMinDate == 'object')
	{
		newMinDate.setHours(0);
		newMinDate.setMinutes(0);
		newMinDate.setSeconds(0);
		newMinDate.setMilliseconds(0);
		this.minDate = newMinDate;
		if (this.currentDate.valueOf() < this.minDate.valueOf())
		{
			this.setDate(this.minDate, dontCallOnChange);
		}
	}
}

FSite2.Calendar.prototype.setMaxDate = function(newMaxDate, dontCallOnChange)
{
	if (typeof newMaxDate == 'object')
	{
		newMaxDate.setHours(0);
		newMaxDate.setMinutes(0);
		newMaxDate.setSeconds(0);
		newMaxDate.setMilliseconds(0);
		this.maxDate = newMaxDate;
		if (this.currentDate.valueOf() > this.maxDate.valueOf())
		{
			this.setDate(this.maxDate, dontCallOnChange);
		}
	}
}

FSite2.Calendar.prototype.getDate = function()
{
	return new Date(this.currentDate);
}

FSite2.Calendar.prototype.prevMonth = function()
{
	this.currentMonth--;
	if (this.currentMonth == -1)
	{
		this.currentMonth = 11;
		this.currentYear--;
	}
	if (this.container)
	{
		this.buildCalendar();
		this.focus();
	}
}

FSite2.Calendar.prototype.nextMonth = function()
{
	this.currentMonth++;
	if (this.currentMonth == 12)
	{
		this.currentMonth = 0;
		this.currentYear++;
	}
	if (this.container)
	{
		this.buildCalendar();
		this.focus();
	}
}

FSite2.Calendar.prototype.showCalendar = function()
{
	this._cancelHide();
	if (!this.container)
	{
		this.buildCalendar();
//		this.container.style.display = 'block';
	}
}

FSite2.Calendar.prototype._hide = function(calendar)
{
	if (!calendar)
		calendar = this;
	if (calendar.container)
	{
		calendar.container.innerHTML = ''; //parentNode.removeChild(calendar.container);
		calendar.container.style.display = 'none';
		calendar.container = null;
	}
	calendar._timeout = null;
}

FSite2.Calendar.prototype._cancelHide = function(calendar)
{
	if (!calendar)
		calendar = this;
	if (calendar._timeout)
	{
		clearTimeout(calendar._timeout);
		calendar._timeout = null;
	}
}

FSite2.Calendar.prototype.hideCalendar = function()
{
	if (!this._timeout)
		this._timeout = setTimeout(FSite2._callRef(this._hide, this), 200);
}

FSite2.Calendar.prototype.toggleCalendar = function()
{
	if (!this.container)
	{
		this.buildCalendar();
		this.focus();
	}
	else
	{
		this.container.parentNode.removeChild(this.container);
		this.container = null;
	}
}

FSite2.Calendar.prototype.focus = function()
{
	if (this.focusElements.length)
	{
		if (this.focusElements[0]._replacement)
			this.focusElements[0]._replacement.focus();
		else
			this.focusElements[0].focus();
		this._cancelHide();
	}
	else
	{
		if (this.container)
			this.container.focus();
	}
}

FSite2.Calendar.prototype.blur = function()
{
	if (this.focusElements.length)
	{
		if (this.focusElements[0]._replacement)
			this.focusElements[0]._replacement.blur();
		else
			this.focusElements[0].blur();
	}
	else
	{
		if (this.container && this.container.firstChild)
			this.container.firstChild.blur();
	}
}

FSite2.Calendar.prototype.buildCalendar = function()
{
	this._cancelHide();
	var anchor = document.createElement('a');
	anchor.style.display = 'block';
	anchor.id = this.containerID;
	anchor.tabIndex=1000;
	if (this.className)
		anchor.className = this.className
//	anchor.className = 'calendar';
	anchor._calendar = this;
	anchor.href = '#';
	anchor.onclick = function() {this._calendar.focus(); return false; };
	anchor.onfocus = function() {
		this._calendar._cancelHide();
		if (!this._calendar.focusElements.length && window.getSelection)
			window.getSelection().removeAllRanges();
	};
	anchor.onblur = function() {if (this._calendar.focusElements.length) this._calendar.hideCalendar(); };
	this._anchor = anchor;
	var i, currentMonth, currentYear;
	currentMonth = this.currentMonth;
	currentYear = this.currentYear;
	for (i = 0; i < this.monthsCount; i++)
	{
		var month = document.createElement('div');
		month.id = this.containerID + '_month' + (i?i:'');
		month.className = 'calendar_month' + (i?i:'');
		var months = document.createElement('div');
		months.id = this.containerID + '_months' + (i?i:'');
		months.className = 'calendar_months';
		this.buildMonths(months, currentMonth, currentYear, i);
		month.appendChild(months);
		var days = document.createElement('div');
		days.id = this.containerID + '_days' + (i?i:'');
		days.className = 'calendar_days';
		this.buildDays(days, currentMonth, currentYear, i);
		month.appendChild(days);
		anchor.appendChild(month);
		currentMonth++;
		if (currentMonth == 12)
		{
			currentMonth = 0;
			currentYear++;
		}
	}
	if (this.closeText)
	{
		var close = document.createElement('div');
		close.className = 'calendar_close';
		close.id = this.containerID + '_close';
		close._calendar = this;
		close.innerHTML = this.closeText;
		close.onclick = function(event) {
			this._calendar.blur();
			this._calendar._hide();
			if (!event) event = window.event;
			event.cancelBubble = true;
			if (event.preventDefault) event.preventDefault();
		}
		anchor.appendChild(close);
	}
	var replace;
	if (this.container)
		replace = this.container;
	else
		replace = document.getElementById(this.containerID);
	if (replace)
	{
		replace.parentNode.insertBefore(anchor, replace);
		replace.parentNode.removeChild(replace);
	}
	else if (lastFocusElement = this.focusElements[this.focusElements.length - 1])
	{
		if (lastFocusElement.nextSibling)
			lastFocusElement.parentNode.insertBefore(anchor, lastFocusElement.nextSibling);
		else
			lastFocusElement.parentNode.appendChild(anchor);
	}
	this.container = anchor;
/*	if (this.container.style.display != 'none')
		this.focus();*/
}

FSite2.Calendar.prototype.buildMonths = function(months, currentMonth, currentYear, i)
{
	if (!i)
	{
		var prevMonth = document.createElement('div');
		prevMonth.className = 'month_prev';
		prevMonth.id = this.containerID + '_month_prev';
		prevMonth._calendar = this;
		prevMonth.onclick = function(event) {
			this._calendar.prevMonth();
			if (!event) event = window.event;
			event.cancelBubble = true;
			if (event.preventDefault) event.preventDefault();
			return false;
		}
		months.appendChild(prevMonth);
	}
	var currMonth = document.createElement('div');
	currMonth.className = 'month_current' + (i?i:'');
	currMonth.id = this.containerID + '_month_current' + (i?i:'');
	currMonth.innerHTML = this.monthsNames[currentMonth] + ', ' + currentYear;
	months.appendChild(currMonth);
	if (i == this.monthsCount -1)
	{
		var nextMonth = document.createElement('div');
		nextMonth.className = 'month_next';
		nextMonth.id = this.containerID + '_month_next';
		nextMonth._calendar = this;
		nextMonth.onclick = function(event) {
			this._calendar.nextMonth();
			if (!event) event = window.event;
			event.cancelBubble = true;
			if (event.preventDefault) event.preventDefault();
			return false;
		}
		months.appendChild(nextMonth);
	}
}

FSite2.Calendar.prototype.buildDays = function(days, currentMonth, currentYear, j)
{
	var tempDate = new Date();
	tempDate.setFullYear(currentYear, currentMonth, 1);
	var firstDay = (tempDate.getDay() + 6) % 7;
	var monthDays = tempDate.getDays();
	var weekElement;
	var dayElement;
	if (this.daysNames)
	{
		weekElement = document.createElement('div');
		weekElement.id = this.containerID + '_header' + (j?j:'');
		weekElement.className = 'header';
		for (i = 0; i < 7; i++)
		{
			var dayElement = document.createElement('div');
			dayElement.id = this.containerID + '_weekday' + (j?j:'') + '_' + i;
			dayElement.className = 'weekday';
			dayElement.innerHTML = this.daysNames[i];
			weekElement.appendChild(dayElement);
		}
		days.appendChild(weekElement);
	}
	for (i = 0; i < 7 * Math.floor((firstDay + monthDays + 6) / 7); i++)
	{
		if (!(i % 7))
		{
			weekElement = document.createElement('div');
			weekElement.id = this.containerID + '_week' + (j?j:'') + '_' + (i / 7);
			weekElement.className = 'week';
		}
		if ((i >= firstDay) && (i - firstDay < monthDays))
		{
			day = i - firstDay + 1;
			var tempDate = new Date(currentYear, currentMonth, day);
			if (tempDate.valueOf() == this.currentDate.valueOf())
				className = 'current';
			else if (this.minDate && (tempDate.valueOf() < this.minDate.valueOf()))
				className = 'disabled';
			else if (this.maxDate && (tempDate.valueOf() > this.maxDate.valueOf()))
				className = 'disabled';
			else
				className = 'normal';
			dayElement = this.buildDay(i, day, className + ' day', j);
			if (className == 'normal')
			{
				dayElement._calendar = this;
				dayElement._date = tempDate;
				dayElement.onclick = function(event) {
					this._calendar.blur();
					if (this._calendar.focusElements.length)
						this._calendar._hide();
					this._calendar.setDate(this._date);
					if (!event) event = window.event;
					event.cancelBubble = true;
					if (event.preventDefault) event.preventDefault();
					return false;
				}
			}
		}
		else
			dayElement = this.buildDay(i, '', 'empty day', j);
		weekElement.appendChild(dayElement);
		if ((i % 7) == 6)
			days.appendChild(weekElement);
	}
}

FSite2.Calendar.prototype.buildDay = function(number, day, classes, j)
{
	var dayElement = document.createElement('div');
	dayElement.id = this.containerID + '_day' + (j?j:'') + '_' + number;
	dayElement.className = classes;
	dayElement.innerHTML = day;
	return dayElement;
}
