if (typeof(StoreHours) == "undefined") { StoreHours = {}; }

StoreHours.months = ['Janvier', 'F&eacute;vrier', 'Mars', 'Avril', 'Mai', 'Juin',
	'Juillet', 'Ao&ucirc;t', 'Septembre', 'Octobre', 'Novembre', 'D&eacute;cembre'];

StoreHours.Month = Class.create();
Object.extend(StoreHours.Month.prototype, {
	
	date: null,
	days: null,
	
	initialize: function(year, month) {
		this.date = new Date(year, month);
		this.days = [];
	},
	
	addDay: function(day) {
		this.days[day.getDate() - 1] = day;
	},
	
	getFullYear: function() {
		return this.date.getFullYear();
	},
	
	getMonth: function() {
		return this.date.getMonth();
	},
	
	getDay: function(date) {
		return this.days[date - 1];
	},
	
	isPast: function() {
		
		//this.date is the first of the month with no time component
		var today = new Date();
		today.setDate(1);
		today.setHours(0);
		today.setMinutes(0);
		today.setSeconds(0);
		today.setMilliseconds(0);
		
		return this.date < today;
	},
	
	toString: function() {
		return this.getFullYear() + " " + StoreHours.months[this.getMonth()];
	},
	
	toHTML: function() {
		var header = document.createElement('h4');
		header.innerHTML = StoreHours.months[this.getMonth()];
		
		var dates = $(document.createElement('div'));
		dates.addClassName('grid3col');
		
		var validDays = this.days.findAll(function(d) {
			return !!(d);
		});
		
		var columnCount = 3;
		var columnDensity = [];
		
		if (validDays.length < columnCount) {
			//if we have too few entries, spread the few we have across columns
			for (var i = 0; i < validDays.length; i++) {
				columnDensity.push(1);
			}
		} else {

			var datesPerColumn = Math.floor(validDays.length / columnCount);
			var firstColumnCount = datesPerColumn + (validDays.length % columnCount);

			for (var i = 0; i < validDays.length; i++) {
				if (i == 0) {
					//put extras onto first column
					columnDensity.push(firstColumnCount);
				} else {
					//otherwise evenly divided amongst all rows
					columnDensity.push(datesPerColumn);	
				}
			}
		}
		
		var start = 0;
		for (var i = 0; i < columnCount; i++) {
			var count = columnDensity[i];
			
			var column = $(document.createElement('div'));
			column.addClassName('column');
			if (i == 0) {
				column.addClassName('first');
			} else if (i == columnCount - 1) {
				column.addClassName('last');
			}
			
			for (var j = start; j < count + start; j++) {
				column.appendChild(validDays[j].toHTML());
			}
			dates.appendChild(column);
			start = start + count;
		}
		
		return {header: header, dates: dates};
	}
	
});


StoreHours.Day = Class.create();
Object.extend(StoreHours.Day.prototype, {

	date: null,
	open: null,
	close: null,
	
	initialize: function(date, open, close) {
		this.date = date;
		this.open = open;
		this.close = close;
	},
	
	getFullYear: function() {
		return this.date.getFullYear();
	},
	
	getMonth: function() {
		return this.date.getMonth();
	},
	
	getDate: function() {
		return this.date.getDate();
	},
	
	isOpen: function() {
		return this.open && this.close;
	},
	
	isToday: function() {
		var today = new Date();
		return today.getDate() == this.date.getDate() &&
			today.getMonth() == this.date.getMonth() &&
			today.getYear() == this.date.getYear();
	},
	
	isPast: function() {
		// this.date has no time component so zero it out on today
		var today = new Date();
		today.setHours(0);
		today.setMinutes(0);
		today.setSeconds(0);
		today.setMilliseconds(0);
		
		return this.date < today;
	},
	
	toString: function() {
		
		var date = StoreHours.months[this.getMonth()] + " " + this.date.getDate() + ": ";
		
		if (!this.isOpen()) {
			return date + "FERM&Eacute;"
		}
		
		return date + this.open + " &agrave; " + this.close;
	},
	
	/*
	* <p class="today"><span>December 3:</span> 8:00 a.m. to 6:00 p.m.</p>
	*/
	toHTML: function() {
		
		var date = document.createElement('span');
		date.innerHTML = this.date.getDate()  + " " + StoreHours.months[this.getMonth()] + ": ";
		
		var entry = $(document.createElement('p'));
		
		if (this.isToday()) {
			entry.addClassName('today');
		}
		
		if (!this.isOpen()) {
			entry.innerHTML = " FERM&Eacute;";
		} else {
			entry.innerHTML = " " + this.open.toString() + " &agrave; " + this.close.toString();
		}
		
		entry.insertBefore(date, entry.firstChild);
		return entry;
	}
	
});

StoreHours.Time = Class.create();
Object.extend(StoreHours.Time.prototype, {
	
	hour: null,
	minute: null,
	period: null,
	
	initialize: function(time) {
		
		var timeSegments = time.match(/(\d+):(\d{2})/);
		this.hour = timeSegments[1];
		this.minute = timeSegments[2];
		
		if (this.hour < 12) {
			this.period = 'a.m.';
		} else if (this.hour == 12) {
			this.period = 'midi';
		} else if (this.hour == 24) {
			this.period = 'minuit';
		} else {
			this.period = 'p.m.';
		}
		
		// if (this.hour > 12) {
		//	this.hour = this.hour - 12;
		//}
		
	}
	
});

//Listed here to satisfy IE, was not recognizing the overriding toString
StoreHours.Time.prototype.toString = function() {
	
	if (!this.hour || !this.minute || !this.period) {
		return '';
	}
	
	if (this.hour != 12) {
		return this.hour + ' h ' + this.minute + ' ';
	} else {
		return this.period.capitalize();
	}
}

StoreHours.Application = Class.create();
Object.extend(StoreHours.Application.prototype, {
	
	options: null,
	periods: null,
	
	initialize: function(feed_url, options) {
		
		this.options = options || {};
		
		var requestUrl = feed_url + '?z=' + new Date().getTime(); //TODO not assume there is no query string
		
		var request = new Ajax.Request(requestUrl, {
			method: 'GET',
			onSuccess: this.parse.bind(this),
			onException: this.fail.bind(this),
			onFailure: this.fail.bind(this)})
	},
	
	parse: function(response) {
		var hoursData = eval('(' + response.responseText + ')');
		
		this.periods = [];
		
		for (var i = 0; i < hoursData.length; i++) {
			var entry = hoursData[i];
			
			var date = new Date(entry.date)
			var open = entry.open? new StoreHours.Time(entry.open) : null;
			var close = entry.closed? new StoreHours.Time(entry.closed) : null;
			
			this.periods.push(new StoreHours.Day(date, open, close));
		}
	
		if (typeof(this.options.onSuccess) == 'function') {
			this.options.onSuccess(this.periods);
		}
	},
	
	fail: function() {
		if (typeof(this.options.onFailure) == 'function') {
			this.options.onFailure();
		}
	}
});

StoreHours.render = function(periods) {
	var list = document.createElement('div');
	
	var months = [];
	var currentMonth = null;
	
	for (var i = 0; i < periods.length; i++) {
		var period = periods[i];

		
		if (!currentMonth || currentMonth.getMonth() != period.getMonth()) {
			var newMonth = new StoreHours.Month(period.getFullYear(), period.getMonth());
			months.push(newMonth);
			currentMonth = newMonth;
			newMonth = null;
		}
		
		currentMonth.addDay(period);
	}
	
	for (var i = 0; i < months.length; i++) {
		var month = months[i];
		
		var elements = month.toHTML();
		list.appendChild(elements.header);
		list.appendChild(elements.dates);
	}
	
	return list;
}
