var holidays = ['1,1', '1,6', '4,25', '5,1', '6,2', '8,15', '11,1', '12,8', '12,25', '12,26'];
var months = [
	'Gennaio', 'Febbraio', 'Marzo',
	'Aprile', 'Maggio', 'Giugno',
	'Luglio', 'Agosto', 'Settembre',
	'Ottobre', 'Novembre', 'Dicembre'];
var weekday = ['Lunedì', 'Martedì', 'Mercoledì', 'Giovedì', 'Venerdì', 'Sabato', 'Domenica'];
var weekdayabbr = ['L', 'M', 'M', 'G', 'V', 'S', 'D'];
var today = new Date();
function div(a, b)
	{
	return Math.floor(a / b);
	}

function easter(y)
	{
	c = div(y, 100);
	n = y - 19 * div(y, 19);
	k = div(c - 17, 25);
	i = c - div(c, 4) - div(c - k, 3) + 19 * n + 15;
	i = i - 30 * div(i, 30);
	i = i - div(i, 28) * (1 - div(i, 28) * div(29, i + 1) * div(21 - n, 11));
	j = y + div(y, 4) + i + 2 - c + div(c, 4);
	j = j - 7 * div(j, 7);
	l = i - j;
	m = 3 + div(l + 40, 44);
	d = l + 28 - 31 * div(m, 4);
	return new Date(y, m - 1, d);
	}


var Calendar = {
	obj: null,
	today: new Date(today.getTime()),
	date: new Date(today.getTime()),
	busyDateRef: new Date(today.getFullYear(), today.getMonth() - 4, 1),
	busyDays: [],
	popup: true,
	selected: null,
	textbox: null,
	callback: null,
	busydays_callback: null,
	img_bw: '',
	img_fw: '',
	show: function(x, y)
		{
		if(this.obj)
			{
			this.obj.style.left = x + 'px';
			this.obj.style.top = y + 'px';
			this.obj.style.display = 'block';
			}
		},
	hide: function()
		{
		if(this.obj)
			this.obj.style.display = 'none';
		},
	assign: function(textbox, callback, busydays_callback)
		{
		if(typeof busydays_callback == 'undefined') busydays_callback = null;

		this.date.setTime(this.today.getTime());
		this.selected = null;

		var re = /^([0-9]{1,2})[ -\\\/\.]([0-9]{1,2})[ -\\\/\.]([0-9]{4})$/;

		var items = re.exec(textbox.value);
		if(items)
			{
			var dd = parseInt(items[1], 10);
			var mm = parseInt(items[2], 10);
			var yy = parseInt(items[3], 10);

			if(1 <= mm && mm <= 12)
				{
				var ddmax = 31;
				if(mm == 4 || mm == 6 || mm == 9 || mm == 11)
					ddmax = 30;
				if(mm == 2)
					{
					ddmax = 28;
					if(!(yy % 4) && (!(yy % 100) == !(yy % 400)))
						ddmax++;
					}
				if(1 <= dd && dd <= ddmax)
					{
					this.date.setDate(dd);
					this.date.setMonth(mm - 1);
					this.date.setFullYear(yy);
					this.busyDateRef = new Date(this.date.getFullYear(), this.date.getMonth() - 4, 1);
					if(this.selected != null)
						this.selected.setTime(this.date.getTime());
					else
						this.selected = new Date(this.date.getTime());
					}
				}
			}

		this.textbox = textbox;
		this.callback = callback;
		this.busydays_callback = busydays_callback;
		if(this.busydays_callback)
			this.busydays_callback(this.busyDateRef.getFullYear()+','+(this.busyDateRef.getMonth() + 1))
		if(this.obj)
			this.update();
		},
	select: function(time)
		{
		if(this.popup)
			{
			if(this.selected != null)
				this.selected.setTime(time);
			else
				this.selected = new Date(time);
			}
		else
			{
			if(this.selected != null && this.selected.getTime() == time)
				this.selected = null;
			else if(this.selected == null)
				this.selected = new Date(time);
			else
				this.selected.setTime(time);
			}
		this.date.setTime(time);
		this.update();
		if(this.callback && this.textbox)
			this.callback(this.textbox);
		},
	month: function(x)
		{
		var d = this.date.getDate();
		this.date.setMonth(this.date.getMonth() + x);
		if(this.date.getDate() != d)
			{
			var m = this.date.getMonth();
			while(this.date.getMonth() == m)
				this.date.setTime(this.date.getTime() - 24*3600*1000);
			}
		var busyDateRef2 = new Date(this.busyDateRef.getFullYear(), this.busyDateRef.getMonth() + 12, 1);
		if(this.date.getTime() < this.busyDateRef.getTime())
			{
			this.busyDateRef.setMonth(this.busyDateRef.getMonth() - 12);
			if(this.busydays_callback)
				this.busydays_callback(this.busyDateRef.getFullYear()+','+(this.busyDateRef.getMonth() + 1))
			}
		if(this.date.getTime() >= busyDateRef2.getTime())
			{
			this.busyDateRef.setMonth(this.busyDateRef.getMonth() + 12);
			if(this.busydays_callback)
				this.busydays_callback(this.busyDateRef.getFullYear()+','+(this.busyDateRef.getMonth() + 1))
			}
		this.update();
		},
	update: function()
		{
		var s = '';
		var day = new Date(this.date.getTime());
		var m = day.getMonth();
		var easterMonday = easter(day.getFullYear());
		easterMonday.setTime(easterMonday.getTime() + 24*3600*1000);
		var mstr = months[m] + ' ' + day.getFullYear();
		while(day.getDay() != 1)
			day.setTime(day.getTime() - 24*3600*1000);
		while(day.getMonth() == m)
			day.setTime(day.getTime() - 7*24*3600*1000);
		var tz_offset = (this.today.getTimezoneOffset() - this.date.getTimezoneOffset())*60*1000;
		s += '<table cellpadding="0" cellspacing="0" class="calendar">\n';
		s += '<thead>\n';
		if(this.popup)
			s += '<tr><th colspan="7" style="background-color: #eeeeee;"><a title="chiudi" href="javascript:Calendar.hide();" style="font-weight: bold; border: 1px solid #000000; font-size: 6pt; padding: 0px 4px; float: right;">X</a></th></tr>\n';
		bw = '&lt;&lt;';
		fw = '&gt;&gt;';
		if((this.img_bw != '') && (this.img_fw != ''))
			{
			bw = '<img class="month_bw" src="' + this.img_bw + '" style="border-style: none;" />';
			fw = '<img class="month_fw" src="' + this.img_fw + '" style="border-style: none;" />';
			}
		s += '<tr><th colspan="7" class="label"><a title="Mese precedente" href="javascript:Calendar.month(-1);" style="float: left;">' + bw + '</a><a title="Mese successivo" href="javascript:Calendar.month(1);" style="float: right;">' + fw + '</a>' + mstr + '</th></tr>\n';
		s += '</thead>\n';
		s += '<tfoot>\n';
		s += '<tr><td colspan="7">&nbsp;</td></tr>\n';
		s += '</tfoot>\n';
		s += '<tbody>\n';

		for(var w = 0; w <= 6; w++)
			{
			s += '<tr>';
			for(var d = 0; d < 7; d++)
				{
				if(w == 0)
					s += '<th class="daylabel ' + weekdayabbr[d] + '">' + weekdayabbr[d] + '</th>';
				else
					{
					var daystr = '&nbsp;';
						daystr = day.getDate();
					var classname = '';
					var offset = day.getTime() - easterMonday.getTime();
					if(day.getDay() == 0)
						classname += ' sunday holiday';
					else if(0 <= offset && offset < 24*3600*1000)
						classname += ' holiday';
					else
						{
						var dstr = (day.getMonth() + 1) + ',' + day.getDate();
						for(var i = 0; i < holidays.length; i++)
							if(dstr == holidays[i])
								{
								classname += ' holiday';
								break;
								}
						}
					for(var i = 0; i < this.busyDays.length; i++)
						if(dstr == this.busyDays[i])
							{
							classname += ' busyday';
							break;
							}

 					if((day.getTime() + tz_offset) == this.today.getTime())
						classname += ' today';
					if(this.selected != null && day.getTime() == this.selected.getTime())
						classname += ' selected';
					var href = ' title="' + daystr + ' ' + mstr + '" href="javascript:Calendar.select(' + day.getTime() + ');"';
					var style = "";
					if(day.getMonth() != m)
						{
						classname += ' out';
						href = "";
						}
					classname += ' ' + weekdayabbr[d];
					s += '<td class="day' + classname + '"><div><a' + href + '>' + daystr + '</a></div></td>';
					day.setTime(day.getTime() + 24*3600*1000);
					}
				}
			s += '</tr>';
			}
		s += '</tbody>\n';
		s += '</table>\n';
		this.obj.innerHTML = s;
		},
	init: function(id, popup)
		{
		if(typeof popup == 'undefined') popup = true;
			this.popup = popup;
		this.obj = document.getElementById(id);
		if(this.obj)
			{
			this.update();
			if(this.popup)
				this.hide();
			}
		}
};

