function DatePicker(element)
{
	// Create the datepicker HTML
	this._initializeHtml(element);
	
	// Dropdowns for month and year are shown by default.
	this.showDropdown(true);
	
	// Hide the footer by default
	this.showFooter(false);
	
	// Show navigation by default
	this.showNavigation(true);

	// Create the event properties
	this.onselect = null;
	this.ongotodate = null;
	this.onhide = null;
	this.ondblclick = null;

	this.autoFollow = true;

	// The non linear mode allows the user the modify the date in any order. For instance, to select 1 juni 1979, the user may select "1" first,
	// then "juni" and then "1979". This mode is disabled by default (mainly for backwards compatibility).
	this.nonLinear = false;

	// By default, no date is selected
	this._selectedDate = null;

	// Set the initial date to now
	this.gotoDate(new Date());
}

DatePicker.prototype.days = new Array('Zo', 'Ma', 'Di', 'Wo', 'Do', 'Vr', 'Za');
DatePicker.prototype.months = new Array('januari', 'februari', 'maart', 'april', 'mei', 'juni', 'juli', 'augustus', 'september', 'oktober', 'november', 'december');

DatePicker.prototype.setPosition = function(left, top)
{
	this._element.style.position = "absolute";
	this._element.style.left = left + "px";
	this._element.style.top = top + "px";
}

DatePicker.prototype.show = function()
{
	this._element.style.display = "block";
}

DatePicker.prototype.hide = function(invokeOnHide)
{
	this._element.style.display = "none";
	
	if(invokeOnHide && this.onhide != null)
	{
		this.onhide(this);
	}
}

DatePicker.prototype.showFooter = function(bool)
{
	this._footer.style.display = bool ? "" : "none";
}

DatePicker.prototype.showDropdown = function(bool)
{
	this._yearDropdown.style.display = bool ? "" : "none";
	this._monthDropdown.style.display = bool ? "" : "none";
	this._monthSpan.style.display = bool ? "none" : "";
}

DatePicker.prototype.showNavigation = function(bool)
{
	if(bool)
	{
		this._left.className = "prev-month";
		this._left.onclick = this._left.ondblclick = new Function("this.datepicker.gotoPreviousMonth(true);");
		this._right.className = "next-month";
		this._right.onclick = this._right.ondblclick = new Function("this.datepicker.gotoNextMonth(true);");	
	}
	else
	{
		this._left.className = "";
		this._left.onclick = this._left.ondblclick = null;
		this._right.className = "";
		this._right.onclick = this._right.ondblclick = null;
	}
}

DatePicker.prototype._redraw = function()
{
	var month = this._visibleDate.getMonth();
	var year = this._visibleDate.getFullYear();
	
	for(var i=0; i<this._yearDropdown.options.length; i++)
	{
		if(this._yearDropdown.options[i].value == year)
		{
			this._yearDropdown.selectedIndex = i;
			break;
		}
	}

	for(var i=0; i<this._monthDropdown.options.length; i++)
	{
		if(this._monthDropdown.options[i].value == month)
		{
			this._monthDropdown.selectedIndex = i;
			break;
		}
	}

	this._monthSpan.innerHTML = this.months[month]+" "+year;

	for(var i=0; i<6; i++)
	{
		var r = this._table.rows[i+2];
		for(var j=0; j<7; j++)
		{	
			var c = r.cells[j];
			c.innerHTML = '&nbsp;';
			c.className = "";
			c.style.fontWeight = "normal";
			c.onclick = null;
		}
	}

	var date = new Date(year, month, 1);
	var today = new Date();
	var row = 2;

	while(date.getMonth() == month)
	{
		var day = date.getDate();
		var weekday = date.getDay();
		
		var cell = this._table.rows[row].cells[weekday];
		
		cell.innerHTML = day;
		
		if(this._selectedDate != null && day == this._selectedDate.getDate() && month == this._selectedDate.getMonth() && year == this._selectedDate.getFullYear())
		{
			cell.className = "selected";
		}

		if(day == today.getDate() && month == today.getMonth() && year == today.getFullYear())
		{
			cell.style.fontWeight = "bold";
		}
		
		cell.onclick = new Function("this.datepicker.selectDate(new Date("+date.valueOf()+"), true);");
		
		if(weekday == 6) row++;
		
		// go to the next day...
		date.setDate(day+1);			
	}

	if(row == 6 || row == 7 && weekday == 6) 
		this._table.rows[7].style.display = 'none';
	else
		this._table.rows[7].style.display = '';
}

DatePicker.prototype.selectDate = function(date, invokeOnSelect)
{
	if(date == null)
	{
		this._selectedDate = null;
	}
	else
	{
		this._selectedDate = new Date(date.valueOf());
		
		if(this.autoFollow)
		{
			this._visibleDate = new Date(this._selectedDate.getFullYear(), this._selectedDate.getMonth(), 1);
		}
	}
	
	this._redraw();
	
	if(invokeOnSelect && this.onselect !=  null)
	{
		this.onselect(this);
	}
}

DatePicker.prototype.getSelectedDate = function()
{
	return this._selectedDate;
}

DatePicker.prototype.gotoDate = function(date, invokeOnGotoDate)
{
	this._visibleDate = new Date(date.getFullYear(), date.getMonth(), 1);
	
	if(invokeOnGotoDate && this.ongotodate != null)
	{
		this.ongotodate(this);
	}
	
	this._redraw();
}

DatePicker.prototype.getVisibleDate = function()
{
	return this._visibleDate;
}

DatePicker.prototype._gotoYear = function(year)
{
	this._visibleDate.setFullYear(year);
	
	if(this.nonLinear && this._selectedDate)
		this._selectedDate.setFullYear(year);

	this.gotoDate(this._visibleDate, true);
}

DatePicker.prototype._gotoMonth = function(month)
{
	this._visibleDate.setMonth(month);

	if(this.nonLinear && this._selectedDate)
	{
		var numberOfDays = this.getDaysInMonth(this._selectedDate.getFullYear(), month);
		
		if(numberOfDays < this._selectedDate.getDate())
			this._selectedDate.setDate(numberOfDays);
		
		this._selectedDate.setMonth(month);
	}

	this.gotoDate(this._visibleDate, true);
}

DatePicker.prototype.gotoPreviousMonth = function(invokeOnGotoDate)
{
	this._visibleDate.setMonth(this._visibleDate.getMonth() - 1);
	this.gotoDate(this._visibleDate, invokeOnGotoDate);
}

DatePicker.prototype.gotoNextMonth = function(invokeOnGotoDate)
{
	this._visibleDate.setMonth(this._visibleDate.getMonth() + 1);
	this.gotoDate(this._visibleDate, invokeOnGotoDate);
}

DatePicker.prototype._initializeHtml = function(element)
{
	if(element != null)
	{
		// An element is already given. Use this element.
		this._element = element;
	}
	else
	{
		// Create a new element, and give it absolute postition.
		this._element = document.createElement("div");
		document.body.appendChild(this._element);
		this.setPosition(0,0);
	}

	this._element.className = "datepicker";
	this._element.onclick = function(e)
	{
		e = e || window.event;

		e.cancelBubble = true;

		if (e.stopPropagation) 
			e.stopPropagation();
	};
	
	this._element.ondblclick = (function(datepicker)
	{
		return function()
		{
			if(datepicker.ondblclick)
				datepicker.ondblclick(datepicker);
		};
	})(this);
	
	this._table = document.createElement("table");
	this._table.border = 0;
	this._table.cellPadding = 0;
	this._table.cellSpacing = 0;
	
	this._element.appendChild(this._table);
	
	// Create the header
	var header = this._table.insertRow(-1);
	this._left = header.insertCell(-1);
	var center = header.insertCell(-1);
	this._right = header.insertCell(-1);
	
	header.className = "datepicker-header";
	this._left.datepicker = this;
	center.colSpan = 5;
	center.style.height = 22;
	this._right.datepicker = this;

	// Initialize the listboxes
	this._yearDropdown = document.createElement("select");
	this._monthDropdown = document.createElement("select");
	this._monthSpan = document.createElement("span");
	
	for(var i=0; i<12; i++)
	{
		this._monthDropdown.options.add(new Option(this.months[i], i));
	}

	for(var i=1900; i<2030; i++)
	{
		this._yearDropdown.options.add(new Option(i,i));
	}	

	this._yearDropdown.style.width = 50;
	this._monthDropdown.style.width = 78;
	
	this._yearDropdown.datepicker = this;
	this._monthDropdown.datepicker = this;
	
	this._yearDropdown.onchange = new Function("this.datepicker._gotoYear(this.options[this.selectedIndex].value);");
	this._monthDropdown.onchange = new Function("this.datepicker._gotoMonth(this.options[this.selectedIndex].value);");

	center.appendChild(this._yearDropdown);
	center.appendChild(this._monthDropdown);
	center.appendChild(this._monthSpan);
	
	// Create the weekdays
	var weekdays = this._table.insertRow(-1);
	weekdays.className = "weekdays";
	
	for(var i=0; i<7; i++)
	{
		var day = weekdays.insertCell(-1);
		day.appendChild(document.createTextNode(this.days[i]));
	}
	
	// Create the day-cells
	for(var i=0; i<6; i++)
	{
		row = this._table.insertRow(-1);
		
		for(var j=0; j<7; j++)
		{
			var cell = row.insertCell(-1);
			cell.innerHTML = "&nbsp;";	
			cell.datepicker = this;
			cell.setAttribute("unselectable", "on");
		}
	}
	
	// Create the footer
	this._footer = this._table.insertRow(-1);
	this._footer.className = "datepicker-footer";
	
	var noDateCell = this._footer.insertCell(-1);
	
	noDateCell.colSpan = 6;
	noDateCell.appendChild(document.createTextNode("lege datum"));
	noDateCell.datepicker = this;
	noDateCell.onclick = new Function("this.datepicker.selectDate(null, true);");
	
	var closeCell = this._footer.insertCell(-1);
	
	closeCell.datepicker = this;
	closeCell.innerHTML = "&nbsp;";
	closeCell.className = "close";
	closeCell.onclick = new Function("this.datepicker.hide(true);");
}

DatePicker.prototype.getDaysInMonth = function(year, month)
{
	return 32 - (new Date(year, month, 32)).getDate();	
};