/* 'Magic' date parsing, by Simon Willison (6th October 2003)
   http://simon.incutio.com/archive/2003/10/06/betterDateInput
*/


// Configuration options

// Available date types (us|iso|it)
var configDateType = 'it';

// Dates such as 2/29/2005 to rollover to 3/1/2005
var configAutoRollOver = false;


//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////

function keyListener(e)
{
    if(!e)
	{
	    //for IE
		e = window.event;
	}
	switch (e.keyCode)
	{
		case 10: // return
		case 13: // enter
			// perform the update
			magicDate('dateField');
			return false;
		default:
		    return true;
	}
}

switch (configDateType)
{
    case 'us':
        var calendarIfFormat = '%m/%d/%Y';
        var calendarFormatString = 'mm/dd/yyyy';
        break;
    case 'it':
        var calendarIfFormat = '%d/%m/%Y';
        var calendarFormatString = 'dd/mm/yyyy';
        break;
    case 'iso':
    default:
        var calendarIfFormat = '%Y-%m-%d';
        var calendarFormatString = 'yyyy-mm-dd';
        break;
}  

/* Finds the index of the first occurence of item in the array, or -1 if not found */
Array.prototype.indexOf = function(item)
{
    for (var i = 0; i < this.length; i++)
	{
        if (this[i] == item)
		{
            return i;
        }
    }
    return -1;
};
/* Returns an array of items judged 'true' by the passed in test function */
Array.prototype.filter = function(test)
{
    var matches = [];
    for (var i = 0; i < this.length; i++)
	{
        if (test(this[i]))
		{
            matches[matches.length] = this[i];
        }
    }
    return matches;
};

// le tengo ma per il momento non mi servono
var monthNames   = "Gennaio Febbraio Marzo Aprile Maggio Giugno Luglio Agosto Settembre Ottobre Novembre Dicembre".split(" ");
var weekdayNames = "Lunedi Martedi Mercoledi Giovedi Venerdi Sabato Domenica".split(" ");

/* Takes a string, returns the index of the month matching that string, throws
   an error if 0 or more than 1 matches
*/
function parseMonth(month)
{
    var matches = monthNames.filter(	function(item)
										{ 
											return new RegExp("^" + month, "i").test(item);
										}
									);
	
    if (matches.length == 0)
	{
        throw new Error("Invalid month string");
    }
	
    if (matches.length > 1)
	{
        throw new Error("Ambiguous month");
    }
	
    return monthNames.indexOf(matches[0]);
}
/* Same as parseMonth but for days of the week */
function parseWeekday(weekday)
{
    var matches = weekdayNames.filter(	function(item)
									  	{
        									return new RegExp("^" + weekday, "i").test(item);
										}
									);
	
    if (matches.length == 0)
	{
        throw new Error("Invalid day string");
    }
	
    if (matches.length > 1)
	{
        throw new Error("Ambiguous weekday");
    }
	
    return weekdayNames.indexOf(matches[0]);
}

/* Array of objects, each has 're', a regular expression and 'handler', a 
   function for creating a date from something that matches the regular 
   expression. Handlers may throw errors if string is unparseable. 
*/
var dateParsePatterns = [
    // ddmmyyyy oppure ddmmyy
    {
		re: /^(\d{2})(\d{2})(\d{1,4})$/,
        handler: function(bits)
		{
			/*inizializzo la data al 1° gennaio 1900: questo è molto importante
			perchè se non lo faccio d assume la data odierna come valore iniziale
			e questo causa errori in caso di mesi con meno di 31 giorni.
			Esempio: oggi è il 1° feb ed io sto digitando la data 30/01/2006
			         1° step: (new Date) ==> d = 01/02/2006
					 2° step: (setDate) ==> d = 30/02/2006 CHE NON ESISTE
					          quindi l'oggetto Date provvede a cambiare d
							  in 02/03/2006
					 3° step: (setMonth) ==> d = 02/01/2006
					 
			Risultato: la data non è quella digitata
			
			
			Modificata in 2000 in quanto anno bisestile 29/02
			*/
			
            var d = new Date( 2000, 0, 1 );
			
			d.setDate ( parseInt( bits[1], 10 ) );
			
            d.setMonth( parseInt( bits[2], 10 ) - 1 ); // Because months indexed from 0
			
			var year = parseInt( bits[3], 10 )
			
			if ( year < 1000 )
			{
				year += 2000;
			}
			d.setYear ( year );
			
            return d;
        }
    },
	
    // dd/mm/yyyy oppure dd/mm/yy
    {
		re: /^(\d{1,2})\/(\d{1,2})\/(\d{1,4})$/,
        handler: function(bits)
		{
            var d = new Date( 2000, 0, 1 ); //inizializzo a 1° gennaio 1900 Modificata in 2000 in quanto anno bisestile 29/02
			
			d.setDate ( parseInt( bits[1], 10 ) );
            d.setMonth( parseInt( bits[2], 10 ) - 1 ); // Because months indexed from 0
			
			var year = parseInt( bits[3], 10 )
			if ( year < 1000 )
			{
				year += 2000;
			}
			d.setYear ( year );
			
            return d;
        }
    },
	
	// Oggi
    {
		re: /^og/,
        handler: function()
		{ 
            return new Date();
        } 
    },
	
	// Domani
    {
		re: /^do/,
        handler: function()
		{ 
            var d = new Date(); 
            d.setDate(d.getDate() + 1); 
            return d;
        } 
    },
	
	// Ieri
    {
		re: /^ie/,
        handler: function()
		{ 
            var d = new Date(); 
            d.setDate(d.getDate() - 1); 
            return d;
        } 
    },
];

/*var dateParsePatterns = [
    // Today
    {   re: /^tod/i,
        handler: function() { 
            return new Date();
        } 
    },
    // Tomorrow
    {   re: /^tom/i,
        handler: function() {
            var d = new Date(); 
            d.setDate(d.getDate() + 1); 
            return d;
        }
    },
    // Yesterday
    {   re: /^yes/i,
        handler: function() {
            var d = new Date();
            d.setDate(d.getDate() - 1);
            return d;
        }
    },
    // 4th
    {   re: /^(\d{1,2})(st|nd|rd|th)?$/i, 
        handler: function(bits) {
            var d = new Date();
            d.setDate(parseInt(bits[1], 10));
            return d;
        }
    },
    // 4th Jan
    {   re: /^(\d{1,2})(?:st|nd|rd|th)? (\w+)$/i, 
        handler: function(bits) {
            var d = new Date();
            d.setDate(parseInt(bits[1], 10));
            d.setMonth(parseMonth(bits[2]));
            return d;
        }
    },
    // 4th Jan 2003
    {   re: /^(\d{1,2})(?:st|nd|rd|th)? (\w+),? (\d{4})$/i,
        handler: function(bits) {
            var d = new Date();
            d.setDate(parseInt(bits[1], 10));
            d.setMonth(parseMonth(bits[2]));
            d.setYear(bits[3]);
            return d;
        }
    },
    // Jan 4th
    {   re: /^(\w+) (\d{1,2})(?:st|nd|rd|th)?$/i, 
        handler: function(bits) {
            var d = new Date();
            d.setDate(parseInt(bits[2], 10));
            d.setMonth(parseMonth(bits[1]));
            return d;
        }
    },
    // Jan 4th 2003
    {   re: /^(\w+) (\d{1,2})(?:st|nd|rd|th)?,? (\d{4})$/i,
        handler: function(bits) {
            var d = new Date();
            d.setDate(parseInt(bits[2], 10));
            d.setMonth(parseMonth(bits[1]));
            d.setYear(bits[3]);
            return d;
        }
    },
    // next Tuesday - this is suspect due to weird meaning of "next"
    {   re: /^next (\w+)$/i,
        handler: function(bits) {
            var d = new Date();
            var day = d.getDay();
            var newDay = parseWeekday(bits[1]);
            var addDays = newDay - day;
            if (newDay <= day) {
                addDays += 7;
            }
            d.setDate(d.getDate() + addDays);
            return d;
        }
    },
    // last Tuesday
    {   re: /^last (\w+)$/i,
        handler: function(bits) {
            throw new Error("Not yet implemented");
        }
    },
    // mm/dd/yyyy (American style)
    {   re: /(\d{1,2})\/(\d{1,2})\/(\d{4})/,
        handler: function(bits) {
            var d = new Date();
            d.setYear(bits[3]);
            d.setDate(parseInt(bits[2], 10));
            d.setMonth(parseInt(bits[1], 10) - 1); // Because months indexed from 0
            return d;
        }
    },
    // yyyy-mm-dd (ISO style)
    {   re: /(\d{4})-(\d{1,2})-(\d{1,2})/,
        handler: function(bits) {
            var d = new Date();
            d.setYear(parseInt(bits[1]));
            d.setDate(parseInt(bits[3], 10));
            d.setMonth(parseInt(bits[2], 10) - 1);
            return d;
        }
    },
];*/

function parseDateString(s)
{
    for (var i = 0; i < dateParsePatterns.length; i++)
	{
        var re = dateParsePatterns[i].re;
        var handler = dateParsePatterns[i].handler;
        var bits = re.exec(s);
        if (bits)
		{
            return handler(bits);
        }
    }
    throw new Error("Data non valida");
}

function magicDate(input)
{
    try
	{
		if ( input.value != '' )
		{
			var d = parseDateString( input.value );
			var day = d.getDate().toString();
			if ( day.length == 1 )
			{
				day = '0' + day;
			}
			
			var month = (d.getMonth() + 1).toString();
			if ( month.length == 1 )
			{
				month = '0' + month;
			}
			
			input.value = day + '/' + month + '/' + d.getFullYear();
		}
        input.className = 's60';
    }
    catch (e)
	{
        input.className = 'error';
//        var message = e.message;
//		
//        // Fix for IE6 bug
//        if ( message.indexOf('is null or not an object') > -1 )
//		{
//            message = 'Data non valida';
//        }
		
//		input.value = 'Data non valida';
		input.select();
		input.focus();
    }
}
