/*
* Great west newspapers Date Prototype Extension
*/
/*
Constants
*/
Date.dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
Date.abbrDayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
Date.monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
Date.abbrMonthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
Date.firstDayOfWeek = 0;
Date.format = 'yyyymmdd';
//Date.format = 'mm/dd/yyyy';
//Date.format = 'dd/mm/yyyy';
//Date.format = 'yyyy-mm-dd';
//Date.format = 'dd mmm yy';
Date.fullYearStart = '20';
Date.getDayName = function(d,a) {var t = new Date();return t.getDayName(a,d);};
Date.getMonthName = function(d,a){var t = new Date();return t.getMonthName(a,d);};
Date.getNthDayOfMonth = function(n,d,m,y) {
	var dt = [];
	var s = new Date(y, m, 1, 0, 0, 0, 0);
	if (s.getDay() != d) {
		var a = (s.getDay() > d) ? (7+d)-s.getDay() : (d-s.getDay());
		s.addDays(a);
	};
	while (s.getMonth() == m) {
		dt[dt.length] = s.Clone();
		s.addDays(7);
	};
	if (n>dt.length) { return dt[dt.length-1]; } else { return dt[n-1]; }
};
Date.formatTime = function(t,format) {
	if (t.length == 3) { t = '0'+t; };
	var s = '' + t;
	var h = Number(s.substring(0,2));
	var m = Number(s.substring(2,2));
	var ap = 'am';
	if (h > 12) { h = h -12; ap='pm' };
	if (m > 10 || m == 0) { m = '0'+m; }
	var ts = h+":"+m+ap;
	return ts;
};
(function() {
	Date.prototype.isLeapYear = function() {
		var y = this.getFullYear();
		return (y%4==0 && y%100!=0) || y%400==0;
	};
	Date.prototype.isWeekend = function() {
		return this.getDay()==0 || this.getDay()==6;
	};
	Date.prototype.isWeekDay = function() {
		return !this.isWeekend();
		};
	Date.prototype.getDaysInMonth = function() {
		return [31,(this.isLeapYear() ? 29:28),31,30,31,30,31,31,30,31,30,31][this.getMonth()];
	};
	Date.prototype.getDayName = function(abbreviated, d) {
		if (d) {
			return abbreviated ? Date.abbrDayNames[d] : Date.dayNames[d];
		} else {
			return abbreviated ? Date.abbrDayNames[this.getDay()] : Date.dayNames[this.getDay()];
		};
	};
	Date.prototype.getMonthName = function(abbreviated, d) {
		if (d) {
			return abbreviated ? Date.abbrMonthNames[d] : Date.monthNames[d];
		} else {
			return abbreviated ? Date.abbrMonthNames[this.getMonth()] : Date.monthNames[this.getMonth()];
		};
	};
	Date.prototype.getDayOfYear = function() {
		var tmpdtm = new Date("1/1/" + this.getFullYear());
		return (Math.floor((this.getTime() - tmpdtm.getTime()) / 86400000)+1);
	};
	Date.prototype.getWeekOfYear = function() {
		return Math.ceil(this.getDayOfYear() / 7);
	};
	Date.prototype.getNthDayOfMonth = function(n,d) {
		var dt = [];
		this.setDate(1);
		if (this.getDay() != d) { this.addDays((this.getDay() > d) ? (7+d)-this.getDay() : (d-this.getDay())); };
		var m = this.getMonth();
		while (this.getMonth() == m) { dt[dt.length] = this.Clone(); this.addDays(7); };
		if (n>dt.length) {  n = dt.length; };
		n = n -1;
		if (n<0) { n = 0; };
		this.setFullYear(dt[n].getFullYear());
		this.setMonth(dt[n].getMonth());
		this.setDate(dt[n].getDate());
		return this;
	};
	Date.prototype.setDayOfYear = function(d) {
		this.setMonth(0);
		this.setDate(d);
		return this;
	};
	Date.prototype.addYears = function(n) {
		this.setFullYear(this.getFullYear() + n);
		return this;
	};
	Date.prototype.addMonths = function(m) {
		var t = this.getDate();
		this.setMonth(this.getMonth() + m);
		if (t > this.getDate()) { this.addDays(-this.getDate()); }
		return this;
	};
	Date.prototype.addDays = function(d) {
		//this.setDate(this.getDate()+d);
		this.setTime(this.getTime() + (d*86400000) );
		return this;
	};
	Date.prototype.addHours = function(h) {
		this.setHours(this.getHours() + h);
		return this;
	};
	Date.prototype.addMinutes = function(m) {
		this.setMinutes(this.getMinutes() + num);
		return this;
	};
	Date.prototype.addSeconds = function(s) {
		this.setSeconds(this.getSeconds() + num);
		return this;
	};
	Date.prototype.zeroTime = function(d) {
		this.setMilliseconds(0);
		this.setSeconds(0);
		this.setMinutes(0);
		this.setHours(0);
		return this;
	};
	Date.prototype.toFormat = function(f) {
		var r = f || Date.format;
		r = r
			.split('yyyy').join('!000').split('yy').join('!001')
			.split('mmmm').join('!002').split('mmm').join('!003').split('mm').join('!004').split('m').join('!005')
			.split('dddd').join('!006').split('ddd').join('!007').split('dd').join('!008').split('d').join('!009')
			.split('hh').join('!010').split('h').join('!011')
			.split('nn').join('!012').split('n').join('!013')
			.split('ss').join('!014').split('s').join('!015')
			.split('ap').join('!016');
		r = r
			.split('!000').join(this.getFullYear())
			.split('!001').join((this.getFullYear()+'').substring(2))
			.split('!002').join(this.getMonthName(false))
			.split('!003').join(this.getMonthName(true))
			.split('!004').join(_zeroPad(this.getMonth()+1))
			.split('!005').join(this.getMonth()+1)
			.split('!006').join(this.getDayName(false))
			.split('!007').join(this.getDayName(true))
			.split('!008').join(_zeroPad(this.getDate()))
			.split('!009').join(this.getDate())
			.split('!010').join(_zeroPad(this.getHours()))
			.split('!011').join(this.getHours())
			.split('!012').join(_zeroPad(this.getMinutes()))
			.split('!013').join(this.getMinutes())
			.split('!014').join(_zeroPad(this.getSeconds()))
			.split('!015').join(this.getSeconds());
		var h = this.getHours();
		var ap = '';
		if ((r.indexOf('!016') > -1) && (h>12)) { h = h - 12; ap='pm' } else { ap = 'am' };
		r = r.split('!010').join(_zeroPad(h)).split('!011').join(h);
		r = r.split("!016").join(ap);
		return r;
	};
	Date.prototype.fromFormat = function(s, format) {
		var f = format || Date.format;
		var d = new Date('01/01/1977');
		var mLength = 0;

		var iM = f.indexOf('mmmm');
		if (iM > -1) {
			for (var i=0; i<Date.monthNames.length; i++) {
				var mStr = s.substr(iM, Date.monthNames[i].length);
				if (Date.monthNames[i] == mStr) {
					mLength = Date.monthNames[i].length - 4;
					break;
				};
			};
			d.setMonth(i);
		} else {
			iM = f.indexOf('mmm');
			if (iM > -1) {
				var mStr = s.substr(iM, 3);
				for (var i=0; i<Date.abbrMonthNames.length; i++) {
					if (Date.abbrMonthNames[i] == mStr) break;
				};
				d.setMonth(i);
			} else {
				d.setMonth(Number(s.substr(f.indexOf('mm'), 2)) - 1);
			};
		};
		var iY = f.indexOf('yyyy');

		if (iY > -1) {
			if (iM < iY) { iY += mLength; };
			d.setFullYear(Number(s.substr(iY, 4)));
		} else {
			if (iM < iY)	{ iY += mLength; };
			// TODO - this doesn't work very well - are there any rules for what is meant by a two digit year?
			d.setFullYear(Number(Date.fullYearStart + s.substr(f.indexOf('yy'), 2)));
		};
		var iD = f.indexOf('dd');
		if (iM < iD)
		{
			iD += mLength;
		};
		d.setDate(Number(s.substr(iD, 2)));
		if (isNaN(d.getTime())) {
			return false;
		};
		this.setTime(Date.parse(d.toString()));
		return d;
	};
	Date.prototype.IsLessOrEqual = function(d) {
		var ret = false;
		if (this<d) {
			ret = true;
		} else {
			if (this.getFullYear()==d.getFullYear() && this.getMonth()==d.getMonth() && this.getDate()==d.getDate()) { ret = true; };
		};
		return ret;
	};
	Date.prototype.Clone = function() {
		return new Date(this.toString());
	};
		
	var _zeroPad = function(n) { 
		var s='0'+n;
		return s.substring(s.length-2);
	};
})();
