/*
  rangeselector.js (c)2007 Ludomedia Marc Chappuis Switzerland
*/

Function.prototype.bind = function(object) {
	var __method = this;
	return function() {
		return __method.apply(object, arguments);
	}
}

function addEvent(obj, evType, fn) {
	if (obj.addEventListener){
    	obj.addEventListener(evType, fn, true);
		return true;
	} else if (obj.attachEvent){
		var r = obj.attachEvent("on"+evType, fn);
		return r;
	} else {
		return false;
	}
}

function CalendarGrid(container, date, callback, txtDays, txtMonth) {
	container.calendar = this;
	this.container = container;
	this.txtDays = txtDays;
	this.txtMonth = txtMonth;
	this.callback = callback;
	//this.container.style.display = 'none';
	this.setDate(date);
}

CalendarGrid.prototype.setDate = function(date) {
	this.date = date;
	this.viewdate = new Date(date);
	this.update();
}

CalendarGrid.prototype.show = function() {
	if(this.toclear) for(var i=0;i<this.toclear.length;i++) { document.getElementById(this.toclear[i]).style.visibility = 'hidden'; }
	this.container.style.display = 'block';
}

CalendarGrid.prototype.hide = function() {
	if(this.toclear) for(var i=0;i<this.toclear.length;i++) document.getElementById(this.toclear[i]).style.visibility = 'visible';
	this.container.style.display = 'none';
}

CalendarGrid.prototype.toggle = function() {
	if(this.container.style.display=='none') this.show();
	else this.hide();
}

CalendarGrid.prototype.doclick = function() {
	var calendar = this.calendar;
	switch(this.action) {
	case 'prevYear': calendar.viewdate.setFullYear(calendar.viewdate.getFullYear()-1); break;
	case 'nextYear': calendar.viewdate.setFullYear(calendar.viewdate.getFullYear()+1); break;
	case 'prevMonth': calendar.viewdate.setMonth(calendar.viewdate.getMonth()-1); break;
	case 'nextMonth': calendar.viewdate.setMonth(calendar.viewdate.getMonth()+1); break;
	case 'select': 
		calendar.date = new Date(this.args);
		calendar.update();
		calendar.callback(calendar); 
		return;
	}
	calendar.update();
}

CalendarGrid.prototype.buildCell = function(html, css_class, action, args) {
	var e = document.createElement('td');
	e.innerHTML = html;
	if(css_class) e.className = css_class;
	if(action) {
		e.onclick = this.doclick;
		e.calendar = this;
		e.action = action;
		if(args) e.args = args;
	}
	return e;
}

CalendarGrid.prototype.buildNav = function(leftAction, caption, rightAction) {
	var rowgroup, row, cell;
	table = document.createElement('table');	
	rowgroup = document.createElement('tbody');
	table.appendChild(rowgroup);
	row = document.createElement('tr');
	rowgroup.appendChild(row);
	row.appendChild(this.buildCell('&lt;', 'button', leftAction)); 
	cell = this.buildCell(caption);
	cell.setAttribute('width', '100%');
	row.appendChild(cell);
	row.appendChild(this.buildCell('&gt;', 'button', rightAction)); 
	return table;
}

CalendarGrid.prototype.buildGrid = function() {
	var currentMonth = this.viewdate.getMonth();
	var tmp = new Date(this.viewdate);
	tmp.setDate(1);
	stamp = tmp.getTime() - tmp.getDay() * 86400000;
	var table, rowgroup, row, cell;
	table = document.createElement('table');
	rowgroup = document.createElement('thead');
	table.appendChild(rowgroup);
	row = document.createElement('tr');
	rowgroup.appendChild(row);
	for(var x=0;x<7;x++) {
		cell = this.buildCell(this.txtDays[x].charAt(0));
		cell.title = this.txtDays[x];
		row.appendChild(cell);
	}
	table.appendChild(rowgroup);
	rowgroup = document.createElement('tbody');

	var sel = Math.floor(this.date.getTime() / 86400000);
	for(var y=0;y<5;y++) {
		row = document.createElement('tr');
		rowgroup.appendChild(row);
		for(var x=0;x<7;x++) {
			var d = new Date(stamp);
			var day = d.getDate();
			c = d.getMonth()!=currentMonth ? 'out' : 'in';
			if(Math.floor(stamp / 86400000)==sel) c += ' sel';
			if(x==0 || x==6) c += ' we';
			row.appendChild(this.buildCell(day, 'clc ' + c, 'select', stamp)); 
			stamp += 86400000;
		}
	}
	table.appendChild(rowgroup);
	return table;
}

CalendarGrid.prototype.buildRow = function(content) {
	var row, cell;
	row = document.createElement('tr');
	cell = document.createElement('td');
	cell.appendChild(content);
	row.appendChild(cell);
	return row;
}

CalendarGrid.prototype.update = function() {
	var table, rowgroup;

	table = document.createElement('table');
	rowgroup = document.createElement('thead');
	rowgroup.appendChild(this.buildRow(this.buildNav('prevYear', this.viewdate.getFullYear(), 'nextYear')));
	rowgroup.appendChild(this.buildRow(this.buildNav('prevMonth', this.txtMonth[this.viewdate.getMonth()], 'nextMonth')));
	table.appendChild(rowgroup);

	rowgroup = document.createElement('tbody');
	rowgroup.appendChild(this.buildRow(this.buildGrid()));
	table.appendChild(rowgroup);

	this.container.innerHTML = '';
	this.container.appendChild(table);
}

/** permet de sélectionner une date avec des liste déroulante ou une grille de calendrier */
function DateRangeSelector(containerID, daySelectID, yearmonthSelectID, defaultDate, lists, txtDays, txtMonth) {
	this.container = document.getElementById(containerID);
	this.daysel = document.getElementById(daySelectID);
	this.ymsel = document.getElementById(yearmonthSelectID);
	this.date = new Date(defaultDate);
	this.txtDays = txtDays;
	this.txtMonth = txtMonth;
	// conteneur pour le calendrier
	var gridcont = document.createElement('div');
	gridcont.className = 'cal';
	gridcont.instance = this;
	gridcont.style.display = 'none';
	this.container.insertBefore(gridcont, this.daysel);

	// bouton pour ouvrir le calendrier
	var button = document.createElement('img');
	button.className = 'button';
	button.setAttribute('src', 'images/ico-calendar2.gif');
	button.instance = this;
	button.onclick = this.buttonOnClick;
	this.container.insertBefore(button, gridcont);

	this.calendarGrid = new CalendarGrid(gridcont, defaultDate, this.gridOnChange.bind(this), txtDays, txtMonth);
	this.calendarGrid.toclear = lists;
	this.bindEvents();
	this.updateSelectors();
	//prompt('', this.container.innerHTML);
}

DateRangeSelector.prototype.unbindEvents = function() {
	this.daysel.onchange = function() {};
	this.ymsel.onchange = function() {};
}

DateRangeSelector.prototype.bindEvents = function() {
	this.daysel.onchange = this.selectOnChange.bind(this);
	this.ymsel.onchange = this.selectOnChange.bind(this);
}

DateRangeSelector.prototype.updateSelectors = function() {
	this.buildDays();
	var now = new Date();
	var limit = Math.max(now.getTime(), this.date.getTime()) + 400 * 86400000;
	this.buildMonth(now, new Date(limit));
}

DateRangeSelector.prototype.buttonOnClick = function() {
	this.instance.calendarGrid.toggle();
}

DateRangeSelector.prototype.selectOnChange = function(calendarGrid) {
	var j = this.daysel.options[this.daysel.selectedIndex].value;
	var ym = this.ymsel.options[this.ymsel.selectedIndex].value;
	var d = new Date();
	d.setMonth(ym.substring(4));
	d.setFullYear(ym.substring(0, 4));
	d.setDate(j);
	this.date = new Date(d);
	this.calendarGrid.setDate(d);
	this.updateSelectors();
}

DateRangeSelector.prototype.gridOnChange = function(calendarGrid) {
	calendarGrid.hide();
	this.date = new Date(calendarGrid.date);
	this.updateSelectors();
}

DateRangeSelector.prototype.buildDays = function() {
	//var list = document.createElement('select');
	var list = this.daysel;
	list.innerHTML = '';
	for(var i=1;i<=31;i++) {
		var option = document.createElement('option');
		option.setAttribute('value', i);
		if(this.date.getDate()==i) option.setAttribute('selected', 'selected');
		option.innerHTML = i;
		list.appendChild(option);
	}
	//this.daysel.parent.appendChild(list);
}

DateRangeSelector.prototype.appendMonthOption = function(list, d, sel) {
	var m = d.getMonth();
	if(m<10) m = '0' + m;
	var value = (d.getFullYear() + '') + m;
	var caption = this.txtMonth[d.getMonth()] + ' ' + d.getFullYear();

	var o = document.createElement('option');
	o.appendChild(document.createTextNode(caption));
	o.setAttribute('value', value);
	if(sel) o.setAttribute('selected', 'selected');
	list.appendChild(o);
}

DateRangeSelector.prototype.buildMonth = function() {
	//var list = document.createElement('select');
	var list = this.ymsel;
	list.innerHTML = '';
	var d = new Date();
	var miss = true;
	d.setDate(1);
	for(var i=0;i<20;i++) {
		var sel = this.date.getMonth()==d.getMonth() && this.date.getFullYear()==d.getFullYear();
		if(sel) miss = false;
		this.appendMonthOption(list, d, sel);
		d.setMonth(d.getMonth()+1);
	}
	if(miss) this.appendMonthOption(list, this.date, true);
}
