var Filter = {
	neighbourhoods: {},
	register: function(){
		$('#counties, #neighbourhoods').change(Filter.submit);
		var hash, vars = [], hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'), i = 0;
		for(; i < hashes.length; i++){
			hash = hashes[i].split('=');
			if (hash[1]) vars[hash[0]] = hash[1];
		}
		if (vars.deelgemeente){
			$('#counties option[@value=\''+vars.deelgemeente+'\']').attr('selected', 'selected');
			$('#neighbourhoods optgroup').map(function(){
				Filter.neighbourhoods[this.id] = this.cloneNode(true);
				if (this.id == vars.deelgemeente){
					$(this).find('option[@value=\''+vars.wijk+'\']').attr('selected', 'selected');
					return null;
				}
				return this;
			}).remove();
		}
	},
	submit: function(){
		var a = [], c = $('#counties').get(0).value, n = $('#neighbourhoods').get(0).value;
		if (DatePicker.selected()) a.push(DatePicker.output());
		if (c) a.push('deelgemeente='+c);
		if (n && this && this.id != 'counties') a.push('wijk='+n);
		window.location.href = '?'+a.join('&');
	}
}
var DatePicker = {
	from: {day: null, month: null, year: null},
	to: {day: null, month: null, year: null},
	opt: {},
	visible: {month: null, year: null},
	
	register: function(opt){
		// sanity check
		if (!opt) opt = {}
		var curDate = opt.startDate&&opt.startDate.day? new Date(opt.startDate.year, opt.startDate.month-1, opt.startDate.day):new Date();
		DatePicker.visible = {month: curDate.getMonth(), year: curDate.getFullYear()};
		curDate.setDate(1);
		
		// fill in days
		if (!opt.days) opt.days = ['Z','M','D', 'W', 'D', 'V', 'Z'];
		$('div#calendar thead td').map(function(i, el){$(this).text(opt.days[i]);});

		var th = '<tr>';
		for (var i = 0; i < 7; i++)
			th += '<td>'+opt.days[i]+'</td>';
		th += '</tr>';
		$('<table class="calendar-table" cellspacing="0"><thead>'+th+'</thead><tbody></tbody></table>').appendTo('#calendar'); // buggy 'append' method neccecitates this solution 

		// fill in the months
		if (!opt.months) opt.months = ['Januari', 'Februari', 'Maart', 'April', 'Mei', 'Juni', 'Juli', 'Augustus', 'September', 'Oktober', 'November', 'December'];
	
		// create navigation
		$('#yearSelector a:first-child').click(function(){DatePicker.change(-1, 'Y');return false}).next().next().click(function(){DatePicker.change(1, 'Y');return false});
		$('#monthSelector a:first-child').click(function(){DatePicker.change(-1, 'M');return false}).next().next().click(function(){DatePicker.change(1, 'M');return false});
		
		if (opt.preselectedRange){
			var f = opt.preselectedRange.split("-");
			if (f.length == 6){
				DatePicker.from = {day: f[0], month: f[1]-1, year: f[2]};
				DatePicker.to = {day: f[3], month: f[4]-1, year: f[5]};
			}// error: wrong rage format
		}
		
		DatePicker.opt = opt;

		// create calendar body
		DatePicker.createBody(curDate);
	},
	change: function(dir, what){
		DatePicker.visible[what=='Y'?'year':'month'] += dir;
		var d =  new Date(DatePicker.visible.year, DatePicker.visible.month, 1); // "month-overflows" are handled silently (month = -1 -> year-- and month = 12 etc)
		DatePicker.visible = {month: d.getMonth(), year: d.getFullYear()};
		DatePicker.createBody(d);
	},
	createBody: function(date){
		function monthLength(d){
			return 32 - new Date(d.getFullYear(), d.getMonth(), 32).getDate();
		}
		var opt = DatePicker.opt, i, tb = '<tr>', c = date.getDay(), m = monthLength(date)-1, l = m+c+1;
		// alleen februari zou 4 rijen van weken kunnen hebben... (1 feb = zondag)
		for (i=c-1; i >= 0; i--) tb += '<td>'+(opt.otherMonths? m-i:'&nbsp;')+'</td>';
		c--; // omdat over drie (i-c) regels dit nodig is
		for (i=c+1; i < 42; i++){
			if (i%7 == 0 && i>=l) break;
			if (i%7 == 0) tb += '</tr>\n<tr>' // new row
			tb += i<l? '<td class="dayOfWeek"><a href="#">'+(i-c)+'</a></td>': '<td'+(opt.otherMonths?' class="calendar-other-day">'+Math.abs(l-i-1):'>')+'&nbsp;</td>';
		}		
		tb += '</tr>';
		$('div#calendar tbody').html(tb).find('td.dayOfWeek a').click(function(){
			if ($(this.parentNode).hasClass('unselectable')) return false;
			var date = {day: $(this).text(), month: DatePicker.visible.month, year: DatePicker.visible.year};
			/* To set the 'to' attribute for the DatePicker:
			 * 1) The 'range' option must be set and true	ELSE only 'from' is used (pick a date)
			 * 2) The 'from' attribute must be set			ELSE first the start date must be picked
			 * 3) The 'to' is still empty					ELSE the range will be reset
			 */
			if (DatePicker.to.day){
				DatePicker.from.day = null; //force reset when needed
				DatePicker.to.day = null; //force reset when needed
				$('.selected').removeClass('selected');
			}
			$(this.parentNode).addClass('selected');
			DatePicker[DatePicker.opt.range && DatePicker.from.day && !DatePicker.to.day? 'to':'from'] = date;
			if (DatePicker.opt.range){
				if (!DatePicker.to.day){
					$('td.dayOfWeek').filter(function(){
						return parseInt($(this).text()) < DatePicker.from.day;
					}).addClass('unselectable')
				}else{
					$('td.dayOfWeek').filter(DatePicker.select).addClass('selected');
					$('.unselectable').removeClass('unselectable');
					if (DatePicker.opt.onSelect) DatePicker.opt.onSelect();
				}
			}else{
				if (DatePicker.opt.onSelect) DatePicker.opt.onSelect();
			}
			return false;
		});
		if (DatePicker.opt.range &&
			!(	DatePicker.to.day &&
				DatePicker.visible.year >= DatePicker.from.year &&
				DatePicker.visible.year <= DatePicker.to.year)
			){
			if (DatePicker.visible.year < DatePicker.from.year ||
				(DatePicker.visible.year == DatePicker.from.year &&
				 DatePicker.visible.month < DatePicker.from.month)){
				$('#calendar tbody td').addClass('unselectable');
			}else if (DatePicker.visible.year == DatePicker.from.year && DatePicker.visible.month == DatePicker.from.month){
				$('td.dayOfWeek').filter(function(){
					return parseInt($(this).text()) < DatePicker.from.day;
				}).addClass('unselectable')
			}
		}
		$('td.dayOfWeek').filter(DatePicker.select).addClass('selected');
		// set the headings (year and month)
		$('#yearSelector span').text(date.getFullYear());
		$('#monthSelector span').text(opt.months[date.getMonth()]);
	},
	selected: function(){
		return (DatePicker.opt.range && DatePicker.to.day) || (!DatePicker.opt.range && DatePicker.from.day)
	},
	getDate: function(which){
		var d = which && DatePicker[which].day? DatePicker[which]:DatePicker.from;
		return new Date(d.year, d.month, d.day);
	},
	/* select returns whether a day should be selected
	 * to be used with jQuery's 'filter' method
	 * $('.selector').filter(DatePicker.select).addClass('selected');
	 * return boolean
	 */
	select: function(){
		if (!DatePicker.from.day) return false;
		var cur = new Date(DatePicker.visible.year, DatePicker.visible.month, parseInt($(this).text())),from = new Date(DatePicker.from.year, DatePicker.from.month, DatePicker.from.day);
		if (DatePicker.opt.range && DatePicker.to.day) // a range was set !
			return 	DatePicker.compareDate(cur, new Date(DatePicker.to.year, DatePicker.to.month, DatePicker.to.day)) <= 0  &&
					DatePicker.compareDate(cur, from) >= 0;
		else // this is the day
			return DatePicker.compareDate(cur, from) == 0;
	},
	output: function(){
		return DatePicker.opt.output();
	},
	/* compare two dates:
	 * left < right : < 0
	 * left = right : = 0
	 * left > right : > 0
	 */
	compareDate: function(left, right){
		return parseInt(left.getTime() - right.getTime());
	},
	toString: function(){
		var f = DatePicker.from, t = DatePicker.to;
		return DatePicker.from.day+'-'+DatePicker.opt.months[DatePicker.from.month]+'-'+DatePicker.from.year+' tot '+
				DatePicker.to.day+'-'+DatePicker.opt.months[DatePicker.to.month]+'-'+DatePicker.to.year;
	}
}
