var MooCal = new Class({
	initialize: function(elementID, options){
		this.setOptions({
			base: 1,
			x:0,
			y:0,
			calendarClass: "calendar",
			todayClass: "today",
			selectedClass: "selected",
			reservedClass: "reserved",
			defaultYear: new Date().getFullYear(),
			defaultMonth: new Date().getMonth(),
			defaultDay: new Date().getDate(),
			dayNames: ["Nd", "Pon", "Wto", "Śro", "Czw", "Pt", "Sob", "Nd"],
			monthNames: ["Sty", "Lut", "Mar", "Kwi", "Maj", "Cze", "Lip", "Sie", "Wrz", "Paź", "Lis", "Gru"]
		}, options);
 
		this.calendarID = null;
		this.visible = true;
		this.displayTimer = 0;
		this.minYear = this.options.defaultYear;
		this.maxYear = this.options.defaultYear;
		this.reservedDays = new Array();
		this.elementID = elementID;
		this.yearElement = $(elementID + "-year");
		this.monthElement = $(elementID + "-month");
		this.dayElement = $(elementID + "-day");
 
		this.chosenDate = new Date();
 
		if(this.yearElement){
			this.year = this.yearElement.getValue();
			if(this.yearElement.get('tag') == "select"){
				var totalOptions = this.yearElement.length - 1;
				if(totalOptions > 0){
					var firstOptionValue = this.yearElement.options[0].value;
					var lastOptionValue = this.yearElement.options[totalOptions].value;
 
					if(firstOptionValue < lastOptionValue){
						this.minYear = firstOptionValue;
						this.maxYear = lastOptionValue;
					} else {
						this.minYear = lastOptionValue;
						this.maxYear = firstOptionValue;
					}
				}
			}
		} else {
			if(/^\d\d\d\d \d\d \d\d$/.test($(elementID).value)){
				this.year = $(elementID).value.substring(0,4);
			}else{
				this.year = this.options.defaultYear;
			}
		}
		this.chosenDate.setYear(this.year);
 
		if(this.monthElement){
			this.month = this.monthElement.getValue() - this.options.base;
		} else {
			if(/^\d\d\d\d \d\d \d\d$/.test($(elementID).value)){
				this.month = $(elementID).value.substring(5,7)-1;
			}else{
				this.month = this.options.defaultMonth;
			}
		}
		this.chosenDate.setMonth(this.month);
 
		if(this.dayElement){
			this.day = this.dayElement.getValue();
		} else {
			if(/^\d\d\d\d \d\d \d\d$/.test($(elementID).value)){
				this.day = $(elementID).value.substring(8,10);
			}else{
				this.day = this.options.defaultDay;
			}
		}
		this.chosenDate.setDate(this.day);
		this.currentDate = this.chosenDate;
 
		this.monthAndYear = null;
 
	},
 
	show: function(x, y) {
		if(this.visible && this.calendarID == null){
			this.calendarID = "calendar_" + Date.parse(new Date());
			this.draw($pick(x, this.options.x), $pick(y, this.options.y));
		} else {
			this.redraw();
			$(this.calendarID).setStyles({
				"display":"block",
				"left":$pick(x, this.options.x),
				"top":$pick(y, this.options.y)
			});
		}
 
		this.visible = true;
	},
 
	hide: function() {
		if(this.visible){
			$(this.calendarID).setStyle("display","none");
			this.visible = false;
			clearTimeout(this.displayTimer);
		}
	},
 
	selectDate: function(e,d) {
		new Event(e).stop();
 
		if($type(d) != "number") 
			return;
 
		this.currentDate.setDate(d);
		this.chosenDate = this.currentDate;
 
		if(this.yearElement)
			this.yearElement.setProperty("value", this.currentDate.getFullYear());
		if(this.monthElement)
			this.monthElement.setProperty("value", this.currentDate.getMonth() + this.options.base);
		if(this.dayElement)
			this.dayElement.setProperty("value", this.currentDate.getDate());
		if(!this.dayElement && !this.monthElement && !this.yearElement && $(this.elementID).get('tag') == "input"){
			//$(this.elementID).setProperty("value", this.currentDate.getDate() + " " + this.options.monthNames[this.currentDate.getMonth()] + " " + this.currentDate.getFullYear());
			$(this.elementID).setProperty("value", this.currentDate.getFullYear() + " " + numberFormat(this.currentDate.getMonth()+1, 0, '', ',', 2) + " " + numberFormat(this.currentDate.getDate(), 0, '', ',', 2));
		}
 
		this.hide();
	},
 
	setDates: function(){
		this.lastMonth = new Date(this.currentDate).setMonth(this.currentDate.getMonth() - 1);
		this.nextMonth = new Date(this.currentDate).setMonth(this.currentDate.getMonth() + 1);
		this.lastYear = new Date(this.currentDate).setFullYear(this.currentDate.getFullYear() - 1);
		this.nextYear = new Date(this.currentDate).setFullYear(this.currentDate.getFullYear() + 1);
		this.today = new Date();
	},
 
	repaint: function(e,d) {
		new Event(e).stop();
		var dateToCheck = new Date(d);
		if(dateToCheck.getFullYear() < this.minYear || dateToCheck.getFullYear() > this.maxYear){
			return;
		}
		this.currentDate = dateToCheck;
		this.setDates();
		this.redraw();
	},
 
	mouseOver: function() {
		clearTimeout(this.displayTimer);
	},
 
	mouseOut: function() {
		this.displayTimer = this.hide.delay(500, this); 
	},
 
	draw: function(x, y) {
		var tableContainer, table, thead, tbody, row, td;
 
		tableContainer = new Element("div",{ 
			"class": this.options.calendarClass,
			"id": this.calendarID,
			"events": {
				"mouseover": this.mouseOver.bind(this),
				"mouseout": this.mouseOut.bind(this)
			}
		})
		.setStyles({
			"position":"absolute",
			"left": x,
			"top": y
		});
 
		table = new Element("table", {
			"id": this.calendarID + "-table",
			"class": this.calendarID + "-table"
		});
		thead = new Element("thead").injectInside(table);
 
			row = new Element("tr").injectInside(thead);
				new Element("a", {
					"href":"#",
					"events":{
						"click": (function(e){ this.repaint(e, this.lastYear); }).bindWithEvent(this)
					},
					"html":"&laquo;" 
				}).injectInside(
					new Element("th", {
						"class": this.options.calendarClass + "-yearswitch"
					}).injectInside(row)
				);
				new Element("a", {
					"href":"#",
					"events":{
						"click": (function(e){ this.repaint(e, this.lastMonth); }).bindWithEvent(this)
					},
					"html":"&#139;"
				}).injectInside(
					new Element("th", {
						  "class": this.options.calendarClass + "-monthswitch"
					}).injectInside(row)
				);
 
				this.monthAndYear = new Element("th", {
					  "colSpan": 3, 
					  "class" : this.options.calendarClass + "-monthandyear"
				}).appendText(this.options.monthNames[this.currentDate.getMonth()] + " " + this.currentDate.getFullYear()).injectInside(row);
 
				new Element("a", {
					"href":"#",
					"events":{
						"click": (function(e){ this.repaint(e, this.nextMonth); }).bindWithEvent(this)
					},
					"html":"&#155;"
				}).injectInside(
					new Element("th", {
						  "class": this.options.calendarClass + "-monthswitch"
					}).injectInside(row)
				);
				new Element("a", {
					"href":"#",
					"events":{
						"click": (function(e){ this.repaint(e, this.nextYear); }).bindWithEvent(this)
					},
					"html":"&raquo;"
				}).injectInside(
					new Element("th", {
						  "class": this.options.calendarClass + "-yearswitch"
					}).injectInside(row)
				);
 
			row = new Element("tr").injectInside(thead);
				for (i = 0; i < 7; i++)	{ 
					new Element("th").appendText(this.options.dayNames[i]).injectInside(row);
				}
 
		tbody = new Element("tbody").injectInside(table);
 
		for(r=0;r<6;r++){
			row = new Element("tr").injectInside(tbody);
			for(c=0;c<7;c++){
				td = new Element("td").injectInside(row);
				new Element("a",{
					"href": "#",
					"html": "&nbsp;"
				}).injectInside(td);
			}
		}
 
		table.injectInside(tableContainer);
		tableContainer.injectInside(document.body);
 
		this.redraw();
	},
 
	redraw: function() {
		this.setDates();
		this.monthAndYear.set('text', this.options.monthNames[this.currentDate.getMonth()] + " " + this.currentDate.getFullYear());
//		var dates = $ES("tbody a", $(this.calendarID));
		var dates = $$('#'+this.calendarID+' tbody a');
 
		var firstDay = new Date(this.currentDate);
		firstDay.setDate(1);
 
		if (firstDay.getDay() > 0) {
			  firstDay.setDate(-firstDay.getDay() + 1);
		}
 
		var currentDay = new Date(firstDay);
		var today = new Date();
 
		for (i = 0; i < dates.length; i++) {	
			var txt = "&nbsp;";
			if (currentDay.getMonth() == this.currentDate.getMonth()) {
				txt = currentDay.getDate();
			}
			$(dates[i]).removeClass(this.options.todayClass);
			$(dates[i]).removeClass(this.options.selectedClass);
 
			$(dates[i]).removeEvents();
			$(dates[i]).addEvent("click", (function(e, day){
				this.selectDate(e, day);
				}).bindWithEvent(this, txt)
			);
 
			$(dates[i]).set('html',txt);
 
			if (currentDay.getDate() == today.getDate() && currentDay.getMonth() == today.getMonth() && currentDay.getFullYear() == today.getFullYear()) {
				$(dates[i]).addClass(this.options.todayClass);
			}
			
			if (this.currentDate.getMonth() == this.chosenDate.getMonth() && currentDay.getDate() == this.chosenDate.getDate() && currentDay.getMonth() == this.chosenDate.getMonth() && currentDay.getFullYear() == this.chosenDate.getFullYear()) {
				$(dates[i]).addClass(this.options.selectedClass);
			}
			
			if( this.reservedDays[currentDay.getMonth()] instanceof Array ){
				if(this.reservedDays[currentDay.getMonth()][currentDay.getDate()]){
					$(dates[i]).addClass(this.options.reservedClass);
				}
			}
			
			currentDay.setDate(currentDay.getDate() + 1);
		}
	}
});
 
MooCal.implement(new Options);
