if (!calendar)
	var calendar = {};

calendar = {
	deviation: 1,
	className: "calendar",
	near: {
		id: "month",
		obj: null
	},
	_language: 'en', 
	_date: null,
	year: null,
	month: null,
	day: null,
	weekday: null,
	current: {
		day: null,
		month: null,
		year: null,
		time: null
	},
	end: {
		day: null,
		weekday: null
	},
	start: {
		day: null,
		weekday: null
	},
	names: {
		days: {
			en: ["M", "T", "W", "T", "F", "S", "S"], 
			es: ["L", "M", "M", "J", "V", "S", "D"], 
			it: ["L", "M", "M", "G", "V", "S", "D"], 
			de: ["M", "D", "M", "D", "F", "S", "S"], 
			fr: ['L', 'M', 'M', 'J', 'V', 'S', 'D']
		},
		months: {
			en: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
			es: ["Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"],
			it: ["Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"],
			de: ["Jan", "Feb", "Mar", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"],
			fr: ['Jan', 'Fev', 'Mar', 'Avr', 'Mai', 'Jui', 'Jui', 'Aou', 'Sep', 'Oct', 'Nov', 'Dic']
		}, 
		_close: {
			en: 'CLOSE',
			es: 'CERRAR',
			it: 'CHIUDI',
			de: 'SCHLIESSEN',
			fr: 'FERMER'
		}
	},
	components: {
		iframe: null,
		div: null,
		table: {
			tbody: null,
			row: null,
			cell: null
		}
	},
	active: false,
	parent: null,
	field_id: "destination",
	get: {
		_date: function(_date) {
			calendar.get.current();
			
			if (!_date)
				calendar._date = new Date(calendar.current.year, calendar.current.month, 1);
			else {
				_date = _date.split("/");
				calendar._date = new Date(_date[2], _date[1]-1, _date[0]);
			}
			
			calendar.get.year();
			calendar.get.month();
			calendar.get.day();
			calendar.weekday = calendar.get.weekday(calendar._date.getDay());
			calendar.get.end();
			calendar.get.start();
		},
		weekday: function(weekday) {
			//weekday = calendar._date.getDay();
			return weekday - calendar.deviation + 1 == 0 ? 6 : weekday - calendar.deviation;
		},
		year: function() {
			calendar.year = calendar._date.getFullYear();
		},
		month: function() {
			calendar.month = calendar._date.getMonth();
		},
		day: function() {
			calendar.day = calendar._date.getDate();
		},
		end: function() {
			var _date = new Date(calendar.year, (calendar.month + 1), 0);
			calendar.end.day = _date.getDate();
			calendar.end.weekday = calendar.get.weekday(_date.getDay());
		},
		start: function() {
			var _date = new Date(calendar.year, calendar.month, 1);
			calendar.start.day = _date.getDate();
			calendar.start.weekday = calendar.get.weekday(_date.getDay());
		},
		current: function() {
			var _date = new Date();
			calendar.current.day = _date.getDate();
			calendar.current.month = _date.getMonth();
			calendar.current.year = _date.getFullYear();
			
			_date.setHours(0);
			_date.setMinutes(0);
			_date.setSeconds(0);
			calendar.current.time = _date.getTime();
		},
		nodes: function(nodes, tag) {
			var n = nodes.length;
			var snodes = Array()	;
			var j = 0;
			for (var i = 0; i < n; i++) {
				if (nodes[i].nodeName == tag.toUpperCase()) {
					snodes[j] = nodes[i];
					j++;
				}
			}
			return snodes;
		}
	},
	set: function(day) {
		var set = function(nodes, val) {
			var n = nodes.length;
			for (var i = 0; i < n; i++) {
				if (nodes[i].selected &&  nodes[i].value != val)
					nodes[i].selected = false;
				else if (nodes[i].value == val)
					nodes[i].selected = true;
			}
		}
		
		var year = calendar.get.nodes(document.getElementById("year").childNodes, "option");
		set(year, calendar.year);
		
		var month = calendar.get.nodes(document.getElementById("month").childNodes, "option");
		set(month, (calendar.month+1));
		
		recalculate(true, (calendar.month+1));
		
		var day_node = calendar.get.nodes(document.getElementById("day").childNodes, "option");
		set(day_node, day);
		
		recalculate(false);
		
		calendar.clear();
	},
	display: function(_date) {
		if (calendar.active) {
			calendar.clear();
			//return false;
		}
		calendar.active = true;
		
		calendar.get._date(_date);
		calendar.parent = document.body;
		
		calendar.construct.iframe();
		calendar.construct.div();
		
		calendar.construct.months();
		calendar.construct.years();
		calendar.construct.content();
		calendar.construct.footer();
	},
	clear: function() {
		calendar.components.iframe.parentNode.removeChild(calendar.components.iframe);
		calendar.components.div.parentNode.removeChild(calendar.components.div);
		calendar.active = false;
	},
	construct: {
		iframe: function () {
			calendar.components.iframe = document.createElement("iframe");
			calendar.parent.appendChild(calendar.components.iframe);
			//calendar.components.iframe = iframe;
			calendar.components.iframe.className = calendar.className + "_iframe";
			calendar.components.iframe.zIndex = -1;
			calendar.components.iframe.src = "javascript: false;";
			
			calendar.near.obj = document.getElementById(calendar.near.id);
			calendar.components.iframe.style.left = get_left(calendar.near.obj) + "px";
			calendar.components.iframe.style.top = get_top(calendar.near.obj) + "px";
		},
		div: function() {
			calendar.components.div = document.createElement("div");
			calendar.parent.appendChild(calendar.components.div);
			calendar.components.div.className = calendar.className + "_div";
			calendar.components.div.zIndex = 1;
			
			calendar.components.div.style.left = get_left(calendar.near.obj) + "px";
			calendar.components.div.style.top = get_top(calendar.near.obj) + "px";
		},
		months: function() {
			var div = document.createElement("div");
			calendar.components.div.appendChild(div);
			div.className = "upper";
			
			calendar.components.months = document.createElement("select");
			div.appendChild(calendar.components.months);
			//calendar.components.months.setAttribute("onchange", function() { calendar.display(calendar.day + "/" + this.value + "/" + calendar.year); })
			calendar.components.months.onchange = function() { calendar.display(calendar.day + "/" + this.value + "/" + calendar.year); };
			
			var opt;
			for (var i = 0; i < 12; i++) {
				opt = document.createElement("option");
				calendar.components.months.appendChild(opt);
				
				if (calendar.month == i)
					opt.selected = true;
				
				calendar.construct.txt(calendar.names.months[calendar._language][i], opt);
				opt.value = i+1;
			}
		},
		years: function() {
			var div = document.createElement("div");
			calendar.components.div.appendChild(div);
			div.className = "upper";
			
			calendar.components.years = document.createElement("select");
			div.appendChild(calendar.components.years);
			
			var opt;
			//for (var i = calendar.year; i < calendar.year + 2; i++) {
			for (var i = calendar.current.year; i < calendar.current.year + 2; i++) {
				opt = document.createElement("option");
				calendar.components.years.appendChild(opt);
				//calendar.components.years.setAttribute("onchange", function() { calendar.display(calendar.day + "/" + (calendar.month+1) + "/" + this.value); });
				calendar.components.years.onchange = function() { calendar.display(calendar.day + "/" + (calendar.month+1) + "/" + this.value); };
				
				if (calendar.year == i)
					opt.selected = true;
				opt.value = i;
				calendar.construct.txt(i, opt);
			}
		},
		content: function() {
			var div = document.createElement("div");
			calendar.components.div.appendChild(div);
			div.className = "content";
			
			var table = document.createElement("table");
			table.cellSpacing = 0;
			div.appendChild(table);
			
			calendar.components.table.tbody = document.createElement("tbody");
			table.appendChild(calendar.components.table.tbody);
			
			var i_max = calendar.end.day + (6 - calendar.end.weekday + calendar.start.weekday);
			var i, time, _date, j = 0;
			
			calendar.construct.table.row("day_name");
			for (i = 0; i < 7; i++) {
				calendar.construct.txt(calendar.names.days[calendar._language][i], calendar.construct.table.cell());
			}
			
			for (i = 0; i < i_max; i++) {
				if (i % 7 == 0) {
					calendar.construct.table.row();
				}
				
				if (i >= calendar.start.weekday) {
					j++;
				}
				
				calendar.construct.txt(j != 0 && j <= calendar.end.day ? j : "", calendar.construct.table.cell());
				//calendar.components.table.cell.setAttribute("onmouseover", function() { calendar.cls.add(this, 'highlight'); })
				//calendar.components.table.cell.setAttribute("onmouseout", function() { calendar.cls.remove(this, 'highlight'); })
				calendar.components.table.cell.onmouseover = function() { calendar.cls.add(this, 'highlight'); };
				calendar.components.table.cell.onmouseout = function() { calendar.cls.remove(this, 'highlight'); };
				if (j > 0 && j < (calendar.end.day+1)) {
					_date = new Date(calendar.year, calendar.month, j);
					time = _date.getTime();
					if (calendar.current.time - 86400 > time)
						calendar.cls.add(calendar.components.table.cell, "past");
					else
						calendar.components.table.cell.onclick = function() { calendar.set(this.innerHTML); }
					
					if (((i+1) % 7 == 0) || ((i+2) % 7 == 0)) {
						calendar.cls.add(calendar.components.table.cell, 'weekend');
					}
				}
			}
		},
		table: {
			row: function(cls) {
				calendar.components.table.row = document.createElement("tr");
				calendar.components.table.tbody.appendChild(calendar.components.table.row);
				if (cls)
					calendar.cls.add(calendar.components.table.row, cls);
			},
			cell: function() {
				if (!calendar.components.table.row)
					calendar.construct.table.row();
				calendar.components.table.cell = document.createElement("td");
				calendar.components.table.row.appendChild(calendar.components.table.cell);
				return calendar.components.table.cell;
			}
		},
		txt: function(txt, parent) {
			var t = document.createTextNode(txt);
			parent.appendChild(t);
		},
		footer: function() {
			var div = document.createElement("div");
			calendar.components.div.appendChild(div);
			div.className = "footer";
			calendar.construct.txt(calendar.names._close[calendar._language], div);
			//div.setAttribute("onclick", function() { calendar.clear(); });
			//div.setAttribute("onmouseover", function() { calendar.cls.add(this, 'footer_highlight'); });
			//div.setAttribute("onmouseout", function() { calendar.cls.remove(this, 'footer_highlight'); });
			div.onclick =  function() { calendar.clear(); };
			div.onmouseover = function() { calendar.cls.add(this, "footer_highlight"); };
			div.onmouseout = function() { calendar.cls.remove(this, "footer_highlight"); };
		}
	},
	cls: {
		add: function(elem, cls) {
			elem.className += " " + cls;
		},
		remove: function(elem, cls) {
			var cls_match = new RegExp("\\b" + cls + "\\b", "g");
			if (cls_match.test(elem.className))
				elem.className = elem.className.replace(cls, " ");
		}
	}
}
