/*
	MooCal v0.2 - A simple and easy to use calendar control built upon mooTools
	by Chris Martin (http://www.redantdesign.com/) - MIT-style license.
	
	The draw function is modified from a date picker control written by David Kelly 
	* Copyright 2007 David Kelly for CJD Systems Limited
	* version 0.1 - 21st May 2007
	* url - http://ng100.cjdsystems.co.uk/moo/dates/DateTimePicker.htm

*/

var MooCal = new Class({
	initialize: function(elementID, options){
		this.setOptions({
			base: 1,
			x:0,
			y:0,
			calendarClass: "calendar",
			todayClass: "today",
			selectedClass: "selected",
			defaultYear: new Date().getFullYear(),
			defaultMonth: new Date().getMonth(),
			defaultDay: new Date().getDate(),
			dayNames: ["Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat", "Sun"],
			monthNames: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
		}, options);
		
		this.calendarID = null;
		this.visible = true;
		this.displayTimer = 0;
		this.minYear = this.options.defaultYear;
		this.maxYear = this.options.defaultYear;
		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.getTag() == "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 {
			this.year = this.options.defaultYear;
		}
		this.chosenDate.setYear(this.year);
		
		if(this.monthElement){
			this.month = this.monthElement.getValue() - this.options.base;
		} else {
			this.month = this.options.defaultMonth;
		}
		this.chosenDate.setMonth(this.month);
		
		if(this.dayElement){
			this.day = this.dayElement.getValue();
		} 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).getTag() == "input"){
			$(this.elementID).setProperty("value", this.currentDate.getDate() + " " + this.options.monthNames[this.currentDate.getMonth()] + " " + this.currentDate.getFullYear());
		}
		
		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)
					}
				}).setHTML("&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)
					}
				}).setHTML("&#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)
					}
				}).setHTML("&#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)
					}
				}).setHTML("&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": "#"
				}).setHTML("&nbsp;").injectInside(td);
			}
		}
			
		table.injectInside(tableContainer);
		tableContainer.injectInside(document.body);
		
		this.redraw();
	},
	
	redraw: function() {
		this.setDates();
		this.monthAndYear.setText(this.options.monthNames[this.currentDate.getMonth()] + " " + this.currentDate.getFullYear());
		var dates = $ES("tbody a", $(this.calendarID));

		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]).setHTML(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);
			}
			currentDay.setDate(currentDay.getDate() + 1);
		}
	}
});

MooCal.implement(new Options);
