/**Questa libreria necessita delle librerie:
 *	util.js
 *	AZArray.js
 *  String_ext.js
 */
 
/**Il codice seguente estende l'interfaccia del
 * oggetto buit-in Date di JavaScript.
 */

Date.prototype.getTrueYear = Date_getTrueYear;
Date.prototype.toItalianString = Date_toItalianString;
Date.prototype.setFromItalianString = Date_setFromItalianString;
Date.prototype.compare = Date_compare;
Date.prototype.addDays = Date_addDays;
Date.prototype.addMonths = Date_addMonths;
Date.prototype.addYears = Date_addYears;

function _getAZArrayOfMonths()
{
	var aiMonths = new AZArray(12, 1);
	aiMonths[1] = 31;
	aiMonths[2] = 28;
	aiMonths[3] = 31;
	aiMonths[4] = 30;
	aiMonths[5] = 31;
	aiMonths[6] = 30;
	aiMonths[7] = 31;
	aiMonths[8] = 31;
	aiMonths[9] = 30;
	aiMonths[10] = 31;
	aiMonths[11] = 30;
	aiMonths[12] = 31;
	return aiMonths;
}

var sDATE_SEPARATOR = "/";
var aiDAYS_OF_MONTH = _getAZArrayOfMonths();
var sMIN_DATE = "1/1/1753";
var sMAX_DATE = "31/12/9999";
var dtMIN_DATE = Date_parseItalianString(sMIN_DATE, false);
var dtMAX_DATE = Date_parseItalianString(sMAX_DATE, false);

/**Ritorna l'anno a quattro cifre.
 * Sopperisce al comportamento non standard
 * di Explorer che fornisce l'anno a quattro cifre
 * anziché nel seguente formato:
 *  1899 <--> -1
 *  1900 <--> 0
 *	1901 <--> 1
 *	1902 <--> 2
 *  ...
 *	1998 <--> 98
 *	1999 <--> 99
 *	2000 <--> 100
 *	2001 <--> 101
 *	...
 *  9999 <--> 8099
 * @return anno a quattro cifre.
 */
function Date_getTrueYear()
{
	var iYear = this.getYear();
	if (isExplorer())
	{
		if ((iYear >= 0) && (iYear <= 99))
			iYear += 1900;
	}
	else iYear += 1900;
	return iYear;
}


/**Ritorna una stringa che rappresenta la data odierna
 * nel formato italiano. Sopperisce al comportamento non
 * standard di Explorer che fornisce l'anno a quattro cifre
 * anziché nel seguente formato:
 *	1904 <--> 4
 *	1905 <--> 5
 *  ...
 *	1998 <--> 98
 *	1999 <--> 99
 *	2000 <--> 100
 *	2001 <--> 101
 *	...
 *	2036 <--> 136
 *	2037 <--> 137
 * @param bFillWithZeros (default false) se a true,
 *	mesi e giorni a una cifra verranno visualizzati con lo
 *	zero iniziale altrimenti non vengono inseritigli zeri.
 * @return stringa nel formato g[g]/m[m]/aaaa oppure gg/mm/aaaa.
 */
function Date_toItalianString(bFillWithZeros)
{
	if (isUndefined(bFillWithZeros))
		bFillWithZeros = false;
	var iDay = this.getDate();
	var iMonth = this.getMonth() + 1;
	var iYear = this.getTrueYear();
	var sDay;
	if ((bFillWithZeros) && (iDay <= 9))
		sDay = "0" + iDay;
	else sDay = "" + iDay;
	
	var sMonth;
	if ((bFillWithZeros) && (iMonth <= 9))
		sMonth = "0" + iMonth;
	else sMonth = "" + iMonth;
	
	return "" + sDay + sDATE_SEPARATOR
		+ sMonth + sDATE_SEPARATOR + iYear;
}

/**Imposta la data indicata da una stringa che la
 * rappresenta in formato italiano.
 * @param sDate data in formato italiano.
 * @param bCheckBounds (default true) indica se
 * la data deve essere vincolata tra i limiti imposti
 * dalle costanti dtMIN_DATE e dtMAX_DATE specificate
 * in questa libreria.
 */
function Date_setFromItalianString(sDate, bCheckBounds)
{
	if (isUndefined(bCheckBounds))
		bCheckBounds = true;
	var asDMY = sDate.tokensToAZArray(sDATE_SEPARATOR);
	if (asDMY.length != 3)
		return false;
	for (var i = 0; i < asDMY.length; i++)
	if (!isInteger(asDMY[i]))
		return false;
	var iDay = parseInt(asDMY[0], 10)
	var iMonth = parseInt(asDMY[1], 10)
	var iYear = parseInt(asDMY[2], 10);
	if (iYear < 0)
		return false;
	if (iYear <= 49)
		iYear += 2000;
	else if ((iYear >= 50) && (iYear <= 99))
		iYear += 1900;
	if (Date_isValid(iYear, iMonth, iDay))
	{
		if (bCheckBounds)
		{
			dt = new Date();
			dt.setYear(iYear);
			dt.setMonth(iMonth -1);
			dt.setDate(iDay);
			dt.setHours(0);
			dt.setMinutes(0);
			dt.setSeconds(0);
			if ((dt.compare(dtMIN_DATE) < 0)
					|| (this.compare(dtMAX_DATE) > 0))
				return false;
		}
		this.setYear(iYear);
		this.setMonth(iMonth -1);
		this.setDate(iDay);
		this.setHours(0);
		this.setMinutes(0);
		this.setSeconds(0);
		return true;
	}
	return false;
}

/**Confronta due date.
 * @param dateObj altra data oggetto del confronto
 * @return millisecondi trascorsi tra this e dateObj, cioè
 *	= 0 se this = dateObj (anche l'ora)
 *	> 0 se this > dateObj
 *	< 0 se this < dateObj
 */
function Date_compare(dtObj)
{
	return this.getTime() - dtObj.getTime();
}

function Date_addDays(iDays)
{
	this.setDate(this.getDate() + iDays);
}

function Date_addMonths(iMonths)
{
	this.setMonth(this.getMonth() + iMonths);
}

function Date_addYears(iYears)
{
	this.setYear(this.getYear() + iYears);
}

/*** le seguenti non vengono aggiunte all'interfaccia di Date ******
 *********** sono da considerasi come funzioni statiche *******/

/**Controlla se l'anno è bisestile
 * @return true se l'anno è bisestile
 */
function Date_isLeap(iYear)
{
	return (((iYear % 400) == 0)
		|| (((iYear % 4) == 0) && ((iYear % 100) != 0)));
}

/**Controlla se la data è corretta.
 * @return true se la data è corretta
 */
function Date_isValid(iYear, iMonth, iDay)
{
	if ((iMonth < 1 ) || (iMonth > 12))
		return false;
	if  (iDay < 1)
		return false;
	if ((iMonth == 2) && Date_isLeap(iYear))
	{
		if (iDay <= 29)
			return true;
		return false;
	}
	return (iDay <= aiDAYS_OF_MONTH[iMonth]);
}

/**Trasforma una stringa nella data corrispondente.
 * @param sDate stringa che rappresenta la data in formato italiano.
 * @param bCheckBounds (default true) indica se
 * la data deve essere vincolata tra i limiti imposti
 * dalle costanti dtMIN_DATE e dtMAX_DATE specificate
 * in questa libreria.
 */
function Date_parseItalianString(sDate, bCheckBounds)
{
	if (isUndefined(bCheckBounds))
		bCheckBounds = true;
	dtRes = new Date();
	if (dtRes.setFromItalianString(sDate, bCheckBounds))
		return dtRes;
	else return null;
}

/*** le precedenti non vengono aggiunte all'interfaccia di Date ******
 *********** sono da considerasi come funzioni statiche *******/

