/**
 * Copyright (c) 2010 - Great West Newspapers LP (http://www.greatwest.ca)
**/
(function($){
	$.fn.Calendar = function(opts) {
		this.each(
			function() {
				if (!this.Calendar) {
					this.Calendar = new calendar(opts);
					this.Calendar._render(this);
					this.Calendar._bindEvents(this);
				};
			}
		);
		this.setDates = function(d) {
			this.each(function() {
				this.Calendar.s.selectedDates = d;
				this.Calendar._datesChanged(this);
			});
		};
		this.parseDates = function(d) {
			this.each(function() {
				this.Calendar.s.selectedDates = d.split(",");
				this.Calendar._datesChanged(this);
			});
		};
		this.addDate = function(d) {
			this.each(function() {
				this.Calendar.s.selectedDates[this.Calendar.s.selectedDates.length] = d;
				this.Calendar._datesChanged(this);
			});
		};
		this.removeDate = function(d) {
			this.each(function() {
				var s = this.Calendar.s.selectedDates.join(",");
				if (s.indexOf(d) > -1) { s = s.replace(d, '').replace(',,',','); }
				this.Calendar.s.selectedDates = s.split(",");
				this.Calendar._datesChanged(this);
			});
		};
		return this;
	};
	
	function calendar(opts) {
		this.s = {
			selectedDates : [],
			templates : {
				head	: '<table class="gwnCalendarHeader"><tr><td class="Prev">{0}</td><td class="Month">{1}</td><td class="Next">{2}</td></tr></table>',
				lnkPrev : '<a href="#" class="gwnCalPrev">&nbsp;</a>',
				lnkNext	: '<a href="#" class="gwnCalNext">&nbsp;</a>',
				table	: '<table class="gwnCalendar">{0}</table>',
				days : '<table class="gwnCalendarDays"><tr><td>S</td><td>M</td><td>T</td><td>W</td><td>T</td><td>F</td><td>S</td></tr></table>',
				row	: '<tr>{0}</tr>',
				cell	: '<td class="{0}">{1}</td>'
			}
		};
		this.firstEvent = new Date();
		this.lastEvent = new Date();
		this.s = $.extend(true, {}, this.s, opts);
		if (this.s.selectedDates.length > 0) {
			this.firstEvent.fromFormat(this.s.selectedDates[0], "yyyymmdd");
			this.lastEvent.fromFormat(this.s.selectedDates[this.s.selectedDates.length-1], "yyyymmdd");
		};
		this.month = this.firstEvent.getMonth();
		this.year = this.firstEvent.getFullYear();
	};
	$.extend(calendar.prototype, {
		_render : function(el) {
			var m = new Date(this.year, this.month, 1, 12, 0, 0);
			var fdo = Date.firstDayOfWeek - m.getDay() + 1;
			if (fdo > 1) { fdo -= 7; }
			var wks = Math.ceil(((-1*fdo+1)+m.getDaysInMonth())/7);
			var cd = m.Clone().addDays(fdo-1).Clone();
			var w=0, r='';
			while (w++<wks){
				var c='';
				for (var i=0;i<7;i++) {
					var inMonth = cd.getMonth() == this.month;
					if (inMonth) {
						var style = (this._isSelected(cd) ? 'Selected' : '');
						c+= this.s.templates.cell.split('{0}').join(style).split('{1}').join(cd.getDate());
					} else {
						c+= this.s.templates.cell.split('{0}').join('').split('{1}').join("&nbsp;");
					};
					cd.addDays(1);
				};
				r+= this.s.templates.row.split('{0}').join(c);
			};
			var ch = this.s.templates.head
				.split('{0}').join(this._enablePrev() ? this.s.templates.lnkPrev : '')
				.split('{1}').join(Date.getMonthName(this.month, false) + ' ' + this.year)
				.split('{2}').join(this._enableNext() ? this.s.templates.lnkNext : '');
			var ct = this.s.templates.table.split('{0}').join(r);
			$(el).empty();
			$(el).append(ch);
			$(el).append(this.s.templates.days);
			$(el).append(ct);
		},
		_movePrevMonth : function(el) {
			if (this.month == 0) { this.month=11; this.year--; } else { this.month--; };
			this._rerender(el);
		},
		_moveNextMonth : function(el) {
			if (this.month == 11) { this.month = 0; this.year++; } else { this.month++; };
			this._rerender(el);
		},
		_enablePrev : function(el) {
			if (this.firstEvent.getFullYear() < this.year) {
				return true;
			} else {
				return this.firstEvent.getMonth() < this.month;
			};
		},
		_enableNext : function() {
			if (this.lastEvent.getFullYear() > this.year) {
				return true;
			} else {
				return this.lastEvent.getMonth() > this.month;
			};
		},
		_isSelected : function(d) {
			return $.inArray(d.toFormat("yyyymmdd"), this.s.selectedDates) > -1;
		},
		_bindEvents : function(el) {
			var controller = this;
			if (this._enablePrev()) {
				$(el).find("a.gwnCalPrev").bind("click", function(e) {
					e.preventDefault();
					controller._movePrevMonth(el);
				});
			};
			if (this._enableNext()) {
				$(el).find("a.gwnCalNext").bind("click", function(e) {
					e.preventDefault();
					controller._moveNextMonth(el);
				});
			};
		},
		_unBindEvents : function(el) {
			if (this._enablePrev()) { $(el).find("a.gwnCalPrev").unbind("click"); };
			if (this._enableNext()) { $(el).find("a.gwnCalNext").unbind("click"); };
		},
		_datesChanged : function(el) {
			this.firstEvent = new Date();
			this.lastEvent = new Date();
			if (this.s.selectedDates.length > 0) {
				this.s.selectedDates.sort();
				this.firstEvent.fromFormat(this.s.selectedDates[0], "yyyymmdd");
				this.lastEvent.fromFormat(this.s.selectedDates[this.s.selectedDates.length-1], "yyyymmdd");
			};
			this.month = this.firstEvent.getMonth();
			this.year = this.firstEvent.getFullYear();
			this._rerender(el);
		},
		_rerender : function(el) {
			this._unBindEvents(el);
			this._render(el);
			this._bindEvents(el);
		}
	});

})(jQuery);
