function Calendario( m, y, dfp )
{
	this.currentLanguage = 'IT';
	this.firstDayOfWeek = 1; // 0 => Domenica	1 => Lunedi
	
        this.selectedMonth = m || this.getCurrentMonth();
        this.selectedYear = y || this.getCurrentYear();
	this.selectedDay = null;
	this.selectedDate = null;
	
	this.dateFormatPattern = dfp || 'dd/MM/yyyy';
	this.dateFormatPart = new Object();
	
	this.dayOfWeek = new Object();
	this.month = new Object();
	this.tooltip = new Object();
	
	this.initLanguage();
	
	this.lastDayOfMonth = new Array( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
	
	//
	// Le 6 festivita' annuali a data fissa
	//
	this.festiveDay = new Object();
	
	this.festiveDay['1,1'] = true;		// Capodanno
	// Epifania
	// Pasqua
	this.festiveDay['25,4'] = true;		// Festa della liberazione
	this.festiveDay['1,5'] = true;		// Festa dei Lavoratori
	this.festiveDay['15,8'] = true;		// Ferragosto
	// Ognissanti
	// Immacolata
	this.festiveDay['25,12'] = true;	// Natale
	this.festiveDay['26,12'] = true;	// S. Stefano
	
	this.easterDay = null;
	
	this.abjustDay();
}

Calendario.prototype.initLanguage = function()
{
	this.dayOfWeek['IT'] = new Array( "Domenica", "Lunedi", "Martedi", "Mercoledi", "Giovedi", "Venerdi", "Sabato" );
	this.dayOfWeek['EN'] = new Array( "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" );
	this.dayOfWeek['DE'] = new Array( "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag" );
	
	this.dayOfWeek['IT'] = this.dayOfWeek['IT'].concat( this.dayOfWeek['IT'] );
	this.dayOfWeek['EN'] = this.dayOfWeek['EN'].concat( this.dayOfWeek['EN'] );
	this.dayOfWeek['DE'] = this.dayOfWeek['DE'].concat( this.dayOfWeek['DE'] );
	
	this.month['IT'] = new Array( "Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio","Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre" );
	this.month['EN'] = new Array( "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" );
	this.month['DE'] = new Array( "Januar", "Februar", "M&auml;rz", "April", "Mag", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember" );
	
	this.tooltip['IT'] = new Array( "Chiudi", "Mese Precedente", "Mese Successivo", "Mese Corrente", "Oggi" );
	this.tooltip['EN'] = new Array( "Close", "Previous Month", "Next Month", "Current Month", "Today" );
	this.tooltip['DE'] = new Array( "Ende", "Vorhergehender Monat", "Folgender Monat", "Gegenw&auml;rtiger Monat", "Heute" );
};

Calendario.prototype.addLanguage = function( l, dow, m, tt )
{
	l = l.toUpperCase();
	
	this.dayOfWeek[l] = dow;
	this.month[l] = m;
	this.tooltip[l] = tt;
	
	this.dayOfWeek[l] = this.dayOfWeek[l].concat( this.dayOfWeek[l] );
};

Calendario.prototype.getTooltip = function( ti )
{
	var cl = this.getCurrentLanguage();
	
	return( this.tooltip[cl][ti] );
};

Calendario.prototype.delAllFestiveDay = function()
{
	for( var fd in this.festiveDay )
		this.festiveDay[fd] = false;
};

Calendario.prototype.delFestiveDay = function( d, m )
{
	this.festiveDay[parseInt(d, 10) + ',' + parseInt(m, 10)] = false;
};

Calendario.prototype.addFestiveDay = function( d, m )
{
	this.festiveDay[parseInt(d, 10) + ',' + parseInt(m, 10)] = true;
};

Calendario.prototype.isFestiveDay = function( d, m )
{
	if( arguments.length < 2 )
		m = this.getSelectedMonth();
	
	return( this.festiveDay[parseInt(d, 10) + ',' + parseInt(m, 10)] ? true : false );
};

Calendario.prototype.getDay = function( d, m, y )
{
	if( arguments.length < 2 || !m )
		m = this.getSelectedMonth();
	
	if( arguments.length < 3 || !y )
		y = this.getSelectedYear();
	
	var day = new Date(y, m-1, d).getDay();
	
	return( day );
};

Calendario.prototype.isSunday = function( d, m, y )
{
	return( this.getDay(d, m, y) == 0 );
};

Calendario.prototype.isSaturday = function( d, m, y )
{
	return( this.getDay(d, m, y) == 6 );
};

Calendario.prototype.isToday = function( d, m, y )
{
	if( arguments.length < 2 || !m )
		m = this.getSelectedMonth();
	
	if( arguments.length < 3 || !y )
		y = this.getSelectedYear();
	
	return( d == this.getCurrentDay() && m == this.getCurrentMonth() && y == this.getCurrentYear() );
};

Calendario.prototype.setCurrentLanguage = function( val )
{
	this.currentLanguage = val.toUpperCase();
};

Calendario.prototype.getCurrentLanguage = function()
{
	return( this.currentLanguage );
};

Calendario.prototype.setFirstDayOfWeek = function( val )
{
	this.firstDayOfWeek = val;
};

Calendario.prototype.getFirstDayOfWeek = function()
{
	return( this.firstDayOfWeek );
};

Calendario.prototype.getMonth = function( m )
{
	if( !m )
		m = this.getSelectedMonth();
	
	return( this.month[this.getCurrentLanguage()][parseInt(m, 10)-1] );
};

Calendario.prototype.getCurrentDay = function()
{
	return( new Date().getDate() );
};

Calendario.prototype.getCurrentYear = function()
{
	return( new Date().getFullYear() );
};

Calendario.prototype.getCurrentMonth = function()
{
	return( new Date().getMonth() + 1 );
};

Calendario.prototype.getCurrentYear = function()
{
	return( new Date().getFullYear() );
};

Calendario.prototype.setSelectedMonth = function( m )
{
	if( !m )
		m = this.getCurrentMonth();
	
	this.selectedMonth = m;
	
	this.abjustDay();
};

Calendario.prototype.setSelectedYear = function( y )
{
	if( !y )
		y = this.getCurrentYear();
	
	this.selectedYear = y;
	
	this.abjustDay();
};

Calendario.prototype.abjustDay = function()
{
	var m = this.getSelectedMonth();
	var y = this.getSelectedYear();
	
	if( y % 4 == 0 && (y % 100 != 0 || y % 400 == 0) )
		this.lastDayOfMonth[1] = 29;
	else
		this.lastDayOfMonth[1] = 28;
	
	if( this.easterDay != null )
	{
		var easter = this.easterDay.split( ',' );
		
		this.delFestiveDay( easter[0], easter[1] );
	}	
	
	// aggiungere Pasqua a this.festiveDay
};

Calendario.prototype.getLastDayOfMonth = function( m )
{
	if( !m )
		m = this.getSelectedMonth();
	
	return( this.lastDayOfMonth[m-1] );
};

Calendario.prototype.getSelectedMonth = function()
{
	return( this.selectedMonth );
};

Calendario.prototype.getSelectedYear = function()
{
	return( this.selectedYear );
};

Calendario.prototype.currMonth = function()
{
	this.setSelectedMonth( this.getCurrentMonth() );
	this.setSelectedYear( this.getCurrentYear() );
};

Calendario.prototype.nextMonth = function()
{
	var m = this.getSelectedMonth();
	var y = this.getSelectedYear();
	
	if( ++m == 13 )
	{
		y++;
		m = 1;
	}
	
	this.setSelectedMonth( m );
	this.setSelectedYear( y );
};

Calendario.prototype.prevMonth = function()
{
	var m = this.getSelectedMonth();
	var y = this.getSelectedYear();
	
	if( --m == 0 )
	{
		y--;
		m = 12;
	}
	
	this.setSelectedMonth( m );
	this.setSelectedYear( y );
};

Calendario.prototype.getFirstDay = function()
{
	var d = 1;
	
	return( this.getDay(d) );
};

Calendario.prototype.getLastDay = function()
{
	var d = this.getLastDayOfMonth();
	
	return( this.getDay(d) );
};

Calendario.prototype.getDayOfWeek = function( d ) // d => numero da 0 a 6
{
	var cl = this.getCurrentLanguage();
	var fdow = this.getFirstDayOfWeek();
	
	return( this.dayOfWeek[cl][d + fdow] );
};

Calendario.prototype.getSelectedDay = function()
{
	return( this.selectedDay );
};

Calendario.prototype.selectDay = function( annoOms, mese, giorno, ore, minuti, secondi, ms )
{
	var dfpOrder = new Array();
	
	if( !ore )	ore	= 0;
	if( !minuti )	minuti	= 0;
	if( !secondi )	secondi	= 0;
	if( !ms )	ms	= 0;
	
	if( arguments.length == 1 )
		this.selectedDate = new Date( annoOms );
	else
		this.selectedDate = new Date( annoOms, mese-1, giorno, ore, minuti, secondi, ms );
	
	var y		= new String( this.selectedDate.getFullYear() );
	var m		= '00' + (this.selectedDate.getMonth()+1);
	var d		= '00' + this.selectedDate.getDate();
	var hDigit	= '00' + this.selectedDate.getHours();					// 0-23
	var min		= '00' + this.selectedDate.getMinutes();				// 0-59
	var sec		= '00' + this.selectedDate.getSeconds();				// 0-59
	var msec	= '0000' + this.selectedDate.getMilliseconds();				// 0-999
	var hAnal	= (parseInt(hDigit, 10) > 11) ? '00' + (parseInt(hDigit, 10)-12) : hDigit;	// 0-11
	var a		= (parseInt(hDigit, 10) > 11) ? 'PM' : 'AM';				// AM-PM
	
	this.dateFormatPart[(dfpOrder[0]='yyyy')]	= y;
	this.dateFormatPart[(dfpOrder[1]='yy')]		= y.substring( 2 );
	this.dateFormatPart[(dfpOrder[2]='MMMMM')]	= this.getMonth(m);
	this.dateFormatPart[(dfpOrder[3]='MMM')]	= new String(this.getMonth(m)).substring( 0, 3 );
	this.dateFormatPart[(dfpOrder[4]='MM')]		= m.substring( m.length-2 );
	this.dateFormatPart[(dfpOrder[5]='M')]		= parseInt( m, 10 );
	this.dateFormatPart[(dfpOrder[6]='dd')]		= d.substring( d.length-2 );
	this.dateFormatPart[(dfpOrder[7]='d')]		= parseInt( d, 10 );
	this.dateFormatPart[(dfpOrder[8]='EEEEE')]	= this.dayOfWeek[this.getCurrentLanguage()][this.selectedDate.getDay()];
	this.dateFormatPart[(dfpOrder[9]='EEE')]	= new String(this.dayOfWeek[this.getCurrentLanguage()][this.selectedDate.getDay()]).substring( 0, 3 );
	this.dateFormatPart[(dfpOrder[10]='HH')]	= hDigit.substring( hDigit.length-2 );
	this.dateFormatPart[(dfpOrder[11]='H')]		= parseInt( hDigit, 10 );
	this.dateFormatPart[(dfpOrder[12]='KK')]	= hAnal.substring( hAnal.length-2 );
	this.dateFormatPart[(dfpOrder[13]='K')]		= parseInt( hAnal, 10 );
	hDigit	= '00' + (parseInt(hDigit, 10)+1);	// 1-24
	hAnal	= '00' + (parseInt(hAnal, 10)+1);	// 1-12
	this.dateFormatPart[(dfpOrder[14]='hh')]	= hDigit.substring( hDigit.length-2 );
	this.dateFormatPart[(dfpOrder[15]='h')]		= parseInt( hDigit, 10 );
	this.dateFormatPart[(dfpOrder[16]='kk')]	= hAnal.substring( hAnal.length-2 );
	this.dateFormatPart[(dfpOrder[17]='k')]		= parseInt( hAnal, 10 );
	this.dateFormatPart[(dfpOrder[18]='mm')]	= min.substring( min.length-2 );
	this.dateFormatPart[(dfpOrder[19]='m')]		= parseInt( min, 10 );
	this.dateFormatPart[(dfpOrder[20]='ss')]	= sec.substring( sec.length-2 );
	this.dateFormatPart[(dfpOrder[21]='s')]		= parseInt( sec, 10 );
	this.dateFormatPart[(dfpOrder[22]='SSS')]	= msec.substring( msec.length-4 );
	this.dateFormatPart[(dfpOrder[23]='S')]		= parseInt( msec, 10 );
	this.dateFormatPart[(dfpOrder[24]='a')]		= a;
	
	this.selectedDay = '';
	var strPattern = this.getDateFormatPattern();
	var da = 0;
	
	for( var a = 0 ; a < strPattern.length ; a++ )
	{
		if( strPattern.charAt(da) != strPattern.charAt(a) || a == strPattern.length-1 )
		{
			var blnMatch = false;
			
			if( a == strPattern.length-1 )
				a++;
			
			for( var i = 0 ; i < dfpOrder.length ; i++ )
			{
				if( dfpOrder[i] == strPattern.substring(da, a) )
				{
					blnMatch = true;
					this.selectedDay += this.getDateFormatPart( dfpOrder[i] );
					break;
				}
			}
			
			if( !blnMatch )
				this.selectedDay += strPattern.substring(da, a);
			
			da = a;
		}
	}
	
/*	this.selectedDay = this.getDateFormatPattern();
	
	for( var i = 0 ; i < dfpOrder.length ; i++ )
	{
		var dfpKey = dfpOrder[i];
		var dfpVal = this.getDateFormatPart( dfpKey );
		var re = new RegExp( dfpKey, 'g' );
		
		this.selectedDay = this.selectedDay.replace( re, dfpVal );
	}*/
};

Calendario.prototype.getDateFormatPattern = function()
{
	return( this.dateFormatPattern );
};

Calendario.prototype.setDateFormatPattern = function( dfp )
{
	this.dateFormatPattern = dfp;
};

Calendario.prototype.getSelectedDate = function()
{
	return( this.selectedDate );
};

Calendario.prototype.selectDate = function( d )
{
	this.selectDay( d.getTime() );
};

Calendario.prototype.getDateFormatPart = function( p )
{
	return( this.dateFormatPart[p] );
};