[code]
/**
 * @author Eris
 * @version 0.2.0 (Beta)
 * @date 09-01-2007
 * @download http://www.schipbreukeling.nl/docs/scripts/kalender.html 
 * @license GPL http://www.schipbreukeling.nl/docs/license.html or license.txt
 *  Creates a layer with a calender where the user can select one date.
 *  Copyright (C) 2007  Eris
 *  
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *  
 *  See readme.txt for more info.
 */

/*Config setting*/
//create a data object for the date now so we don't need to change it next year. (today.getFullYear() to get the current year) Offcourse you can set a "own" value 
var today = new Date();
var start_year = today.getFullYear();
//end year
var end_year =  today.getFullYear() + 5;
//location of the "close" cross
var delete_cross = '/images/scripts/calendar/delete.png';

//language settings. 
var calendar = 'Calendar';
//month names
var month_names = new Array('January','February','March','April','May','June','July','August','September','October','November','December');
//names of the days. 0 = sunday, 6 = saturday
//we don't care about "logic" values because the user will not see it. If they will see it he/she got enough knowlege about browsers and their quirks
var day_names = new Array('Sun','Mon','Tue','Wen','Thu','Fri','Sat');

//default config arrays please do not change!
//array with the days (0 = January 11 = December)
var days = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
//we don't take care about leap year. This will be done later
//W3C  Dom support . Prevent browser errors. 
if(document.getElementsByTagName && document.createElement){
var w3c = true;
}else{
var w3c = false;
}
/**
 * function show_calendar(e)
 * @param e
 * @return nothing
 * @id show_calendar
 * Create a DHTML Layer. Add the basic elements and runs one time generate_table()
 * Do not use this function when you want to use a inline onclick action!
 */

function show_calendar(e){
  if(!w3c) return;
	if (!e) var h = window.event.srcElement;
	else var h = e.target;
	if (h.nodeType == 3) // defeat Safari bug
		h = h.parentNode;
	//small short cut
	var d = document;
	if(!d.getElementById('calendar')){
	//create a div element
	var div = d.createElement('div');
    //insert div inside the dom tree
	d.body.appendChild(div);
		div.id = 'calendar';
		//before we forget we need to add a reminder. Otherwise the script will forget which input field should be field.
	var hidden = d.createElement('input');
	hidden.type = 'hidden';
	hidden.id= 'id';
	//behind this line you need to edit the location of the "input field"
	//When you want to add a onclick on the field h.id is enough
	//When you want to add a image (See example) you need to change it to:
	//h.previousSibling.id; Find by testing and just general knowlege of the dom structure
	hidden.value = h.previousSibling.id;
	div.appendChild(hidden);
	var mouseY = findPosY(h);
	var mouseX = findPosX(h);

	//placing block
	mouseY = mouseY + 20;
	div.style.top = mouseY +'px';
    div.style.left = mouseX +'px';
	//everything is ready continu to fill the div
	finish_div();
}
}



/**
 * function show_calendar_inline()
 * @param {element)
 * @return null
 * @id show_calendar_inline()
 * Description: the inline version of the show calendar
 * Call it like onclick="show_calender_inline(this)" 
 */
function show_calendar_inline(element){
  if(!w3c) return;
	//if the onclick is add to a other element the input we should move to there. Other whis use var h = element;
  h = element.previousSibling;
	//small short cut
	var d = document;
	if(!d.getElementById('calendar')){
	//create a div element
	var div = d.createElement('div');
    //insert div inside the dom tree
	d.body.appendChild(div);
		div.id = 'calendar';
		//before we forget we need to add a reminder. Otherwise the script will forget which input field should be field.
	var hidden = d.createElement('input');
	hidden.type = 'hidden';
	hidden.id= 'id';
	hidden.value = h.id;
	div.appendChild(hidden);
	var mouseY = findPosY(element);
	var mouseX = findPosX(element);

	//placing block
	mouseY = mouseY + 20;
	div.style.top = mouseY +'px';
    div.style.left = mouseX +'px';
	//every thing is ready now finish the div
	finish_div();
}
}
/**
 * function finish_div
 * @param null
 * @return null
 * @id finish_div
 * Description: Finish the div element
 */
function finish_div(){
  if(!w3c) return;
	var d = document;
	var div = d.getElementById('calendar');
		var title = div.appendChild(d.createElement('div'));
		  title.className = 'title';
		  title.innerHTML = '<div class="float_right"><img src="'+delete_cross+'" alt="Close" id="close"/></div>'+calendar;
		  	d.getElementById('close').onclick = close_window;
	//maak een date object
	var now = new Date();

	//create a selectbox with monts
	var select1 = d.createElement('select');
	select1.id = 'month';
	for( i = 0; i < month_names.length; i++){
		var option = d.createElement('option');
		option.value = i;
		option.appendChild(document.createTextNode(month_names[i]));
		if(now.getMonth() == i){
			option.selected = 'selected';
		}
		select1.appendChild(option);
	}
	//make now a select box for the curent year and the next year.)
	var select2 = d.createElement('select');
	select2.id = 'year';
	for( i = start_year; i < (end_year + 1); i++){
			var option = d.createElement('option');
		if(now.getFullYear() == i){
			option.selected = 'selected';
		}
		option.value = i;
		option.appendChild(document.createTextNode(i));
		select2.appendChild(option);
	}
	//add a onchange action
	select1.onchange = generate_table;
	select2.onchange = generate_table;
	
	div.appendChild(select1);
	div.appendChild(select2);

	//now we generate a table. This is done by a second function so I don't have to copy past it twice.
	generate_table();
}

/**
 * function generate_table()
 * @param null
 * @return null
 * @id generate_table
 * Description: Generates a html table with all dates. Starting with the Sunday (Inside JS as 0 and end on Saturday as 6)
 * date and year will fetched from the input fields earlier generated. By default Client side date / time. Or user set. 
 * output will become a HTML tabel maximum 7 cols and 6 rows ( Sunday, Monday, Tuesday, Wendsday, Thursday, Friday, Saturday)
 * Rows Days of the week, (th)
 */
function generate_table(){
  if(!w3c) return;
	//look inside the div calendar if there exits a table. If true we trash it.
	if(document.getElementById('table')){
	//its exits trash it!
		document.getElementById('calendar').removeChild(document.getElementById('table'));
	}
	var table = document.createElement('table');
	var tbody = table.appendChild(document.createElement('tbody'));
	if(!document.getElementById('calendar').appendChild(table)){
		alert('Error');
	}
	table.id = 'table';

	var month = document.getElementById('month');
	var year = document.getElementById('year');
	//now look for the values
	var m = month.options[month.selectedIndex].value;
	var y = year.options[year.selectedIndex].value;
	//we just now generate a date
	var dates = new Date();
	dates.setYear(y);
	dates.setMonth(m);
	dates.setDate(1);
	//traceback first day of the month 
	var firstDay = dates.getDay();
	//create a tr with day names
	var tr = document.createElement('tr');
	for(i = 0; i < day_names.length;i++){
		var th = document.createElement('th');
		th.innerHTML = day_names[i];
		tr.appendChild(th);
		
	}
	tbody.appendChild(tr);
	//we got maybe a leap year lets check it. 
	//I don't care about the leap years each 100 years because its then no leap...  
	//(2100, 2200 and 2300) because this will happen 3 times every 400 year
	// it will be a not a leap year. Script will show only 1 day wrong
	if(dates.getFullYear() % 4 == 0){
		//leap year
		//februari 
		days[1] = 29; 
	}

	//we now just loop trough the the var firstDay (string) till we have reached the first day. If so stop script
	//create a element tr
	var tr = document.createElement('tr');
	for(i = 0; i < firstDay;i++){
		var td = document.createElement('td');
		//should be empty
		td.innerHTML = '';
		tr.appendChild(td);
	}
	//because the maxium value will be 6 we don't need to create a new row. Next for list we have to
	var w = 0;
	for(i = 1; i <= days[m];i++){
		var td = document.createElement('td');
		td.innerHTML = i;
		//add a onclick event
		td.onclick = close_return;
		tr.appendChild(td);
		if((i + firstDay) % 7 == 0){
			//save tr in table
			tbody.appendChild(tr);
			//create a new tr
			var tr = document.createElement('tr');
			w = -1;
		}
	 w++;
	}	
	for(w;w % 7 > 0;w++ ){
			var td = document.createElement('td');
		//should be empty
		td.innerHTML = '';
		tr.appendChild(td);
	}
	table.appendChild(tr);
	
}
/**
 * function close_return()
 * @param null
 * @return null
 * @id close_return
 * Description: Return the selected date back to the input field
 */
function close_return(e){
  if(!w3c) return;
	if (!e) var h = window.event.srcElement;
	else var h = e.target;
	if (h.nodeType == 3) // defeat Safari bug
		h = h.parentNode;
	var id = document.getElementById('id').value;
	//create the date
	var d = h.innerHTML;
	if(d.length == 1){
		d = '0' + d;
	}
	var month = document.getElementById('month');
	var year = document.getElementById('year');
	//now look for the values
	//it seems to be that the month was a string instead of a int. Multiply m with 1 and add 1 . Then check to add a leading zero.
	var m = month.options[month.selectedIndex].value * 1 + 1;
	m = m.toString();
	
	if(m.length == 1){
		m = '0' + m;
	}
	var y = year.options[year.selectedIndex].value;
  //d = day
  //m = month
  //y = year
	var wanted_date = d + '-' + m + '-' + y;
	document.getElementById(id).value = wanted_date;
	
	close_window();
}

/**
 * function close_window()
 * @param null
 * @return null
 * @id close_close_window
 * Description: Remove DHTML layer
 */
function close_window(){
  if(!w3c)  return;
			document.body.removeChild(document.getElementById('calendar'));
}

/**
 * function findPosX()
 * @param {obj}
 * @return {int}
 * @id findPosX
 * @author PPK
 * Description: Find the X position of a element
 */
function findPosX(obj)
{

	var curleft = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}
/**
 * function findPosY()
 * @param {obj}
 * @return {int}
 * @id findPosY
 * @author PPK
 * Description: Find the Y position of a element
 */
function findPosY(obj)
{
	var curtop = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
}
[/code]