/*
date.js: useful extensions to the JavaScript Date object.
Copyright (C) 1999-2000 Jan Wessely <info@jawe.net>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
Version 2 as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
or browse to http://www.gnu.org/copyleft/gpl.html.

created: 25 June 1998
last modified: 17 Jan 2000
*/

// literals *******************************************************************

// used as param unit in Date.add()
Date.MILLI = 1;
Date.SECOND = Date.MILLI * 1000;
Date.MINUTE = Date.SECOND * 60;
Date.HOUR = Date.MINUTE * 60;
Date.DAY = Date.HOUR * 24;
Date.MONTH = -1;
Date.YEAR = -2;

Date.DAYS_IN_MONTH = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

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;

// methods ********************************************************************

// Fix for Mozilla returning a year of, e.g., 2003 -> 103.
Date.prototype.GetY2kYear = function ()
{
    var year = parseInt(this.getYear());
    if (year < 1000)    {   year += 1900;   }
    return year;
}

/****************************** dateformat.js *********************************
 *
 * Object Extension for Date object
 *   description:
 *          -Stores day and month arrays in Date object 
 *          -Provides a format function to 'pretty' print
 *           the date in custom formats
 *   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  
 *   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
 ******************************************************************************/ 
 
 function dateFormat(format) {
   var dateString = format;

   //yyyy  is a 4-digit year - i.e., 2002  
   dateString = dateString.replace( new RegExp("yyyy", "gi"), this.GetY2kYear() );
   //yy    is a 2-digit year - i.e., 02
   dateString = dateString.replace( new RegExp("yy", "gi"), new String( this.GetY2kYear() ).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 = d.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;   
}

function _Date_toCanonString()
{
	return this.getFullYear() +
			 _pad(this.getMonth() + 1) + 
			 _pad(this.getDate());
}

function _Date_getFullYear()
{
	var y = this.getYear();
	if(y < 100 && y > 0)
		y += 1900;
	return y;
}

function _Date_setFullYear(val)
{
	this.setYear(val);
}

function _Date_compareTo(other)
{
	return Date.compare(this, other);
}

function _Date_isLeapYear()
{
	return Date.leapYear(this.getFullYear());
}

function _Date_add(date, unit, amount)
{
	return Date.addDate(this, date, unit, amount);
}

function _Date_getDaysInMonth()
{
	return Date.daysInMonth(this.getFullYear(), this.getMonth());
}

// utility functions **********************************************************

function _isLeapYear(year)
{
	return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
}

function _compareDate(d1, d2)
{
	return (new Date(d1)).getTime() - (new Date(d2)).getTime();
}

function _addDate(date, unit, amount)
{
	if(unit == Date.MONTH)
		date.setMonth(date.getMonth() + amount);
	else if(unit == Date.YEAR)
		date.setFullYear(date.getFullYear() + amount);
	else
		date.setTime(date.getTime() + (unit * amount));
	return date;
}

function _getDaysInMonth(year, month)
{
	return month == 1 && Date.leapYear(year) ? 29 : Date.DAYS_IN_MONTH[month];
}

function _pad(n)
{
	return (n < 10 ? "0" : "") + n;
}

// initialization *************************************************************

Date.prototype.toCanonString = _Date_toCanonString;
if(!Date.prototype.getFullYear)
{
	Date.prototype.getFullYear = _Date_getFullYear;
	Date.prototype.setFullYear = _Date_setFullYear;
}
Date.prototype.isLeapYear = _Date_isLeapYear;
Date.prototype.compareTo = _Date_compareTo;
Date.prototype.add = _Date_add;
Date.prototype.getDaysInMonth = _Date_getDaysInMonth;

Date.leapYear = _isLeapYear;
Date.compare = _compareDate;
Date.addDate = _addDate;
Date.daysInMonth = _getDaysInMonth;

//Parse a standard date.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function ParseDate(dateStringOrObject, blnDateOnly)
{
    var stdDate = dateStringOrObject.toString().match(/^([0-9]+)-(...)-([0-9]+) ([0-9]+):([0-9]+)/);
    if ((stdDate)&&(stdDate.length > 0))
    {
		// Now, parse the date.
        var parsed = new Date();
        parsed.setYear(stdDate[3]);
        parsed.setMonth(0); // A little hack to ensure that setting the day value doesn't
							// cause problems in a month with less than that number of days. 
        parsed.setDate(stdDate[1]);
		if (!blnDateOnly) {
        	parsed.setHours(stdDate[4]);
        	parsed.setMinutes(stdDate[5]);
		}
		// Need to set the month last to avoid pathological case of 29-31 Feb, which gets
		// translated to March ...
		var month = stdDate[2].toLowerCase();
		for (i=0; i<months.length; i++) {
			if ( month == months[i].toLowerCase() ) parsed.setMonth(i);
		}
		return (parsed);		
    }
	else {
		return (null);
	}
}
