/********************************************************************
The software is provided "as is" and "with all faults." The author makes 
no representations or warranties of any kind concerning the quality, 
accuracy or suitability of the software, either express or implied.
********************************************************************/
/****************************** DateExt.js *********************************
 *
 * Object Extension for Date object
 *   description:
 *   -Stores day and month arrays in Date object.
 *   -Date.format(formatString) - Provides a format function to 'pretty' print
 *   	the date in custom formats.
 *	-Date.yearsDiff(date1, date2) - returns the difference in years between
 *		two dates.
 *	-Date.daysDiff(date1, date2) - returns the difference in days between
 *		two dates.
 *	-Date.parseDate(aDateStr) - parses a date string into a date object
 *	-addDate(days, months, years) - adds given days/months/years to the date
 *	-addYear(years) - adds given years to the date
 *	-addMonth(months) - adds given months to the date
 *	-addDay(days) - adds given days to the date
 *  -isLeapYear() - tests if this date is a leap year or not
 ***************************************************************************/

//Store the date info in the Date object
Date.prototype.Months = ["January", "February", "March", 
                         "April", "May", "June", "July", 
                         "August", "September", "October", 
                         "November", "December"];
Date.prototype.Days = ["Sunday", "Monday", "Tuesday", 
                       "Wednesday", "Thursday", 
                       "Friday", "Saturday"];
/*
Date.prototype.format = dateFormat;
Date.yearsDiff = yearsDiff;
Date.daysDiff = daysDiff;
Date.parseDate = parseDate;
Date.prototype.isLeapYear = isLeapYear;
Date.prototype.addDate = date_addDate;
Date.prototype.addYear = addYear;
Date.prototype.addMonth = addMonth;
Date.prototype.addDay = addDay;
Date.prototype.getDaysInMonth = getDaysInMonth;
Date.prototype.clone = clone;
*/
/*
 *	STATIC
 * 	Returns the difference in years between two dates
 *	aDate - the first date to compare difference in years
 *	bDate - the second date to compare the difference in years
 *	return - the difference in years between the two dates
 */
Date.yearsDiff = function(aDate, bDate)
{
	var year1 = aDate.getFullYear();
	var year2 = bDate.getFullYear();
	var yearDiff = year2 - year1;

	if (yearDiff < 0) {
		yearDiff = Math.abs(yearDiff);
	}

	var month1 = aDate.getMonth();
	var month2 = bDate.getMonth();

	if (month2 > month1) {
		return yearDiff;
	}

	if (month2 < month1) {
		return --yearDiff;
	}
	
	// if months are the same, check days
	var day1 = aDate.getDate();
	var day2 = bDate.getDate();
	if (day2 >= day1) {
		return yearDiff;
	}

	if (month1 != 2) {
		return --yearDiff;
	}

	if (day2 == 28) {
		return yearDiff;
	}

	return --yearDiff;
}


/*
 *	STATIC
 *	Returns the difference in days between two dates.
 *	aDate - a Date object
 *	bDate - a Date object
 *	return - an integer representing the difference in days between aDate and bDate
 */
Date.daysDiff = function(aDate, bDate)
{
	var diff;
	//diff = Math.abs(aDate - bDate);
	// use UTC dates to ignore differences in timezones/DST
	utcDateA = Date.UTC(aDate.getFullYear(), aDate.getMonth(), aDate.getDate(), aDate.getHours(), aDate.getMinutes(), aDate.getSeconds());
	utcDateB = Date.UTC(bDate.getFullYear(), bDate.getMonth(), bDate.getDate(), bDate.getHours(), bDate.getMinutes(), bDate.getSeconds());
	diff = Math.abs(utcDateA - utcDateB);
	diff = diff / (1000 * 60 * 60 * 24);
	return Math.floor(diff);
}


/*
 *	STATIC
 *	Parses a date string into a date object
 *	aDate - date to parses (in mm-dd-yyyy or mm/dd/yyyy format);
 *	return - a Date object set to the given date
 */
Date.parseDate = function(aDateStr)
{
	var seperator;
	var day;
	var month;
	var year;
	var inputDate;  
	
	// check to see if a "-" or a "/" is used as the seperator
	// check to see if a "-" or a "/" is used as the seperator
	if (aDateStr.indexOf("/") > 0) {
		seperator = "/";
	}
	else {
		seperator = "-";
	}
	 
	indx = aDateStr.lastIndexOf(seperator);
	year = aDateStr.substr(indx+1);
		
	indx = aDateStr.indexOf(seperator);
	month = aDateStr.substr(0,indx);
	
	indx1 = aDateStr.indexOf(seperator,indx+1);
	day = aDateStr.substring(indx+1,indx1);
	
	inputDate = new Date(year, month-1, day);
	inputDate.setHours(0, 0, 0, 0);
	return inputDate;
}


/*
*	Adds days, months, and/or years to a given date.
*	numDays - the number of days to add
*	numMonths - the number of months to add
*	numYears - the number of years to add
*	return - modified Date
*/
Date.prototype.addDate = function (numDays, numMonths, numYears)
{
	var yearsToAdd = numYears;
	// first add days, then months, then years
	// to add days, multiply number of days by milliseconds in a day
	// but becuase of DST, not all days have 24hrs, so convert to a UTC date
	var utcTime = Date.UTC(this.getFullYear(), this.getMonth(), this.getDate());
	utcTime = utcTime + (numDays*1000*60*60*24);
	var tempDate = new Date(utcTime);
	
	// now set the new UTC date to this date back again
	this.setFullYear(tempDate.getUTCFullYear());
	this.setMonth(tempDate.getUTCMonth());
	this.setDate(tempDate.getUTCDate());

	var month = this.getMonth() + numMonths;
	if (month > 11)
	{
		yearsToAdd = Math.floor((month+1)/12);
		month -= 12*yearsToAdd;
		yearsToAdd += numYears;
	}
	
	// add the months
	this.setMonth(month);
	
	// add the years
	this.setFullYear(this.getFullYear() + yearsToAdd);
}

/*
*	Adds years to a given date.
*	startDate - the Date to add to
*	numYears - the number of years to add
*	return - modified Date
*/
Date.prototype.addYear = function(numYears)
{
	this.addDate(0,0,numYears);
}

/*
*	Adds months to a given date.
*	startDate - the Date to add to
*	numMonths - the number of months to add
*	return - modified Date
*/
Date.prototype.addMonth = function(numMonths)
{
	this.addDate(0,numMonths,0);
}

/*
*	Adds days to a given date.
*	startDate - the Date to add to
*	numDays - the number of days to add
*	return - modified Date
*/
Date.prototype.addDay = function(numDays)
{
	this.addDate(numDays,0,0);
}

// GET NUMBER OF DAYS IN MONTH
Date.prototype.getDaysInMonth = function ()  
{
    var days;
    var month = this.getMonth()+1;
    var year  = this.getFullYear();

    if (month==1 || month==3 || month==5 || month==7 || month==8 ||
        month==10 || month==12)  {
        days=31;
    }
    else if (month==4 || month==6 || month==9 || month==11) {
        days=30;
    }
    else if (month==2)  {
        if (((year % 4)==0) && ((year % 100)!=0) || ((year % 400)==0)) {
            days=29;
        }
        else {
            days=28;
        }
    }
    return days;
}

// is this year a leap year
Date.prototype.isLeapYear = function ()  
{
	var year = this.getFullYear();
    if (((year % 4)==0) && ((year % 100)!=0) || ((year % 400)==0)) {
    	return true;
    }
	else {
		return false;
	}
}


Date.prototype.clone = function () {
	return new Date(this.getTime());
}

 /**
 *	Returns a formatted date string formatted according to the given pattern.
 *   parameters:
 *          format - accpets any variation of the following list
 *                 yyyy  is a 4-digit year - i.e., 2002   
 *                 yy    is a 2-digit year - i.e., 02
 *                 month is the full month - i.e., September
 *                 mon   is the first three letters of the month - i.e., Sep
 *                 mmm   is the number of the month - i.e., 9
 *                 hh    is hours - i.e., 3
 *                 mm    is minutes (always 2-digit) - i.e., 05
 *                 ss    is seconds (always 2-digit) - i.e., 08
 *                 ddd   is the first three letters of the day - i.e., Wed
 *                 dd    is the numerical day of the month - i.e, 25
 *                 day   is the full day of the week - i.e., Wednesday
 *                 timezone is the the timezone in hours from GMT - i.e., GMT+5
 *                 time24   is the time based on a 24 hour clock - i.e., 18:24   
 *                 time     is the time based on am/pm - i.e., 6:24PM  
 *	return - A formatted date string
 *   example:
 *           myDate = newDate()
 *           myDate.format("day, month dd, yyyy hh:mm:ss timezone")
 *           would return "Wednesday, September 25, 2002 12:14:11 GMT-5"
 *   note: 
 *           If customizing the dateFormat function be aware that the ordering
 *           of the replace calls
 *   author:
 *           Scott Connelly scottsweep@yahoo.com 1/3/2002
 */ 
Date.prototype.format = function(format) {
   var dateString = format;

   //yyyy  is a 4-digit year - i.e., 2002  
   dateString = dateString.replace( new RegExp("yyyy", "gi"), this.getFullYear() );
   //yy    is a 2-digit year - i.e., 02
   dateString = dateString.replace( new RegExp("yy", "gi"), new String( this.getYear() ).substring(2,4) );
   //month is the full month - i.e., September
   dateString = dateString.replace( new RegExp("month", "gi"), this.Months[this.getMonth()] );
   //mon   is the first three letters of the month - i.e., Sep
   dateString = dateString.replace( new RegExp("mon", "gi"), new String( this.Months[this.getMonth()] ).substring(0,3) );
   //mmm   is the number of the month - i.e., 9
   dateString = dateString.replace( new RegExp("mmm", "gi"), (this.getMonth() + 1) );   
   //hh    is hours - i.e., 3
   dateString = dateString.replace( new RegExp("hh", "gi"), this.getHours() );
   //mm    is minutes (always 2-digit) - i.e., 05
   var mm = new String( this.getMinutes() );
   if (mm.length == 1) mm = "0" + mm; //pad if single digit
   dateString = dateString.replace( new RegExp("mm", "gi"), mm );
   //ss    is seconds (always 2-digit) - i.e., 08
   var ss = new String( this.getSeconds() );
   if (ss.length == 1) ss = "0" + mm; //pad if single digit
   dateString = dateString.replace( new RegExp("ss", "gi"), ss ); 
   //ddd   is the first three letters of the day - i.e., Wed
   dateString = dateString.replace( new RegExp("ddd", "gi"), new String( this.Days[this.getDay()] ).substring(0,3) );
   //dd    is the numerical day of the month - i.e, 25
   dateString = dateString.replace( new RegExp("dd", "gi"), this.getDate() );
   //day   is the full day of the week - i.e., Wednesday
   dateString = dateString.replace( new RegExp("day", "gi"), this.Days[this.getDay()] );

   //timezone is the the timezone in hours from GMT - i.e., GMT+5
   tz = this.getTimezoneOffset();
   timezone = "";
   if (tz < 0)
      timezone = "GMT-" +  tz / 60;
   else if (tz == 0)
      timezone = "GMT";
   else
      timezone = "GMT+" + tz / 60;
   dateString = dateString.replace( new RegExp("timezone", "gi"), timezone );
   
   //time24   is the time based on a 24 hour clock - i.e., 18:24   
   var minutes = new String( this.getMinutes() );
   if (minutes.length == 1) minutes = "0" + minutes; //pad if single digit
   var time24 = new String( this.getHours() + ":" + minutes );
   dateString = dateString.replace( new RegExp("time24", "gi"), time24 );
   
   //time     is the time based on am/pm - i.e., 6:24PM
   var time;
   var ampm;
   var hour = this.getHours();
   if ( hour < 12) {
      if (hour == 0) hour = 12;
         ampm = "AM"
   } else {
      if (hour !=12)
         hour = hour - 12;
      ampm = "PM";   
   }
   time = new String(hour + ":" + minutes + ampm);     
   dateString = dateString.replace( new RegExp("time", "gi"), time );

   return dateString;   
}

