/* ReservationDate constructor */
/* month in all of these functions is off by one, Jan = 0, Feb = 1,etc. */
function ReservationDate(year,month,day)
{
	var y = parseInt(year);
	var m = parseInt(month);
	var d = parseInt(day);
	if(y == null || m == null || d == null || isNaN(y) ||isNaN(m) || isNaN(d))
	{
		var now = new Date();
		y = now.getFullYear();
		m = now.getMonth();
		d = now.getDate();
	}
	this.getFullYear = function() { return y; }
	this.getMonth = function() { return m; }
	this.getDate = function() { return d; }
	this.setFullYear = function(new_year) { var ny = parseInt(new_year); if(ny >= 0) y = ny; }
	this.setMonth = function(new_month) { var nm = parseInt(new_month); if(nm >= 0 && nm <= 11) m = nm; }
	this.setDate = function(new_day) { var nd = parseInt(new_day); var num_days = ReservationDate.NumDaysInMonth(y,m); if(nd >= 1 && nd <= num_days) d = nd; }
}
ReservationDate.prototype.Between = function(first,second)
{
	var f = first;
	var s = second;
	if(s.LessThanOrEqual(f))
	{
		var t = f;
		f = s;
		s = t;
	}
	if(this.LessThanOrEqual(s) && f.LessThanOrEqual(this))
		return true;

	return false;
}
ReservationDate.prototype.LessThanOrEqual = function(other)
{
	if(other.getFullYear() < this.getFullYear())
		return false;
	if(other.getFullYear() == this.getFullYear())
	{
		if(other.getMonth() < this.getMonth())
			return false;
		if(other.getMonth() == this.getMonth())
		{
			if(other.getDate() < this.getDate())
			{
				return false;
			}
		}
	}
	return true;
}
ReservationDate.prototype.Equal = function(other)
{
	if(other.getFullYear() != this.getFullYear() || other.getMonth() != this.getMonth() || other.getDate() != this.getDate())
		return false;
	return true;
}
ReservationDate.prototype.MoveToNextDay = function(day)
{
	var todays_day = ReservationDate.GetDayOfTheWeek(this.getMonth(),this.getDate(),this.getFullYear());
	var int_day = ReservationDate.DayToInteger(day);
	var next = 0;
	if(todays_day > int_day)
		next = (7-todays_day)+int_day;
	else if(todays_day < int_day)
		next = int_day-todays_day;
	this.Add(next);	
}

ReservationDate.prototype.Add = function(num_days)
{
	var nd = parseInt(num_days);
	if(nd > 0)
	{
		var last_day = ReservationDate.NumDaysInMonth(this.getFullYear(),this.getMonth());
		var new_day = this.getDate()+nd;
		/* if off the end of this month, add one to month */
		if(new_day > last_day)
		{
			this.setDate(new_day%last_day);
			var nm = this.getMonth()+1;
			/* if month is off the end, add a year */
			if(nm >= 12)
			{
				this.setMonth(0);
				this.setFullYear(this.getFullYear()+1);
			}
			else
				this.setMonth(nm);
		}
		else
			this.setDate(new_day);
	}
}
ReservationDate.prototype.ToString = function()
{
	//return this.getMonth() + "/" + this.getDate() + "/" + this.getFullYear();
	return this.getFullYear() + "-" + (this.getMonth()+1) + "-" + this.getDate();
}

//caculate what day of the week a day is
//see - http://en.wikipedia.org/wiki/Calculating_the_day_of_the_week
ReservationDate.GetDayOfTheWeek = function(month,day,year)
{
	var months_lookup_table;
	if(parseInt(year) % 4 == 0)
		months_lookup_table = new Array(6,2,3,6,1,4,6,2,5,0,3,5);
	else
		months_lookup_table = new Array(0,3,3,6,1,4,6,2,5,0,3,5);
	var centuries_lookup_table = new Array(4,2,0,6);

	var centuries_val = centuries_lookup_table[(parseInt(stripzeros((year+"").substr(0,2)))-1)%4];
	var year_digits = parseInt(stripzeros((year+"").substr(2,2)));
	var year_fract = parseInt(year_digits/4);
	var month_val = months_lookup_table[parseInt(month)];
	return (centuries_val+year_digits+year_fract+month_val+parseInt(day))%7;
}
/* convert string day into integer representation */
ReservationDate.DayToInteger = function(day)
{
	if(day == "Sun")
		return 0;
	else if(day == "M")
		return 1;
	else if(day == "T")
		return 2;
	else if(day == "W")
		return 3;
	else if(day == "Th")
		return 4;
	else if(day == "F")
		return 5;
	else if(day == "Sat")
		return 6;
	return -1;
}
ReservationDate.IsReservationDate = function(date_str)
{
	/* parse the reservation date string we are given */
	var ret = ReservationDate.ParseReservationDate(date_str);

	/* if unable to parse, it is not a reservation date */
	if(ret == null)
		return false;
	return true;
}
/* month is off by one - Jan = 0, Feb = 1, etc. */
ReservationDate.NumDaysInMonth = function(year,month)
{
	var days = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
	var y = parseInt(year);
	var m = parseInt(month);
	/* if leap year and Feb */
	if(y % 4 == 0 && m == 1)
		return 29;
	return days[m];
}
/* Convert date string into Javascript date */
/* input looks like - 2009-09-22 */
ReservationDate.ParseReservationDate = function(date_str)
{
	if(date_str == null || date_str == "")
		return null;

	var s = date_str.split("-");
	if(s.length != 3)
		return null;
	/* stripzeros is used to remove any unnecessary preceeding zeros */
	/* 09 is changed to just 9 */
	var year = parseInt(stripzeros(s[0]));
	var month = parseInt(stripzeros(s[1]));
	var day = parseInt(stripzeros(s[2]));
	
	if(!(isWholeInt(year) && isWholeInt(month) && isWholeInt(day)))
		return null;
	if(date_str.substr(4,1) != "-" || date_str.substr(7,1) != "-" && date_str.length == 10)
		return null;
	if(date_str.substr(4,1) != "-" || date_str.substr(6,1) != "-" && date_str.length == 8)
		return null;


	/* check year, month and day ranges */
	if(year < 0 || month < 1 || month > 12)
		return null;
	var num_days = ReservationDate.NumDaysInMonth(year,month-1);
	if(day > num_days || day < 1)
		return null;

	/* months are from 0 to 11, therefore subtract one */
	return new ReservationDate(year,month-1,day);
}
