//new Calendar();
Calendar = Class.create();
Object.extend(Calendar.prototype,{
	initialize:function(options) {
		Object.extend(this,Object.extend({
			type:'',
			month:new Date().getMonth() + 1,
			year:new Date().getFullYear(),
			date:'',
			target:null,
			_days:new Array(),
			onMonthChange:function() { },
			onSelectDay:function() { },
			onSelectWeek:function() { },
			onSelectMonth:function() {},
			onMouseOverDay:function() { },
			onMouseOutDay:function() { }
		},options || { }));
		this._createTable();
		if (this.target) {
			this.show();
		}
	},
	_createTable:function() {
		this.table = Element.create("table",{cellSpacing:0,cellPadding:0});
		Element.addClassName(this.table,'CalTable'+this.type);
			a = Element.create("tbody");
				b = Element.create("tr");
					c = Element.create("td",{innerHTML:'&lt;'});
					Element.addClassName(c,'CalArrow');
					Event.observe(c,"click",this._monthLeft.bind(this));
					
					this._monthCell = Element.create("td",{colSpan:5});
					Event.observe(this._monthCell,"click",this.onSelectMonth.bind(this));
					Element.addClassName(this._monthCell,'CalMonth');
					
					d = Element.create("td",{innerHTML:'&gt;'});
					Element.addClassName(d,'CalArrow');
					Event.observe(d,"click",this._monthRight.bind(this));
					
					b.appendChild(c);
					b.appendChild(this._monthCell);
					b.appendChild(d);
				a.appendChild(b);
				this._rows = new Array();
				for(var w=0;w<7;w++) {
					b = Element.create("tr");
						this._rows[w] = new Array();
						for(var d=0;d<7;d++) {
							c = Element.create("td",{width:'14%'});
							if (w == 0) {
								c.innerHTML = this._DayName(d);
								Element.addClassName(c,'CalDayName');
							} else {
								Element.addClassName(c,'CalDay'+this.type);
							}
							this._rows[w][d] = c;
							c.Day = new CalendarDay(this,null,c);
							this._days[this._days.length] = c.Day;							
							b.appendChild(c);
						}
					a.appendChild(b);
				}
			this.table.appendChild(a);
			this._showMonth();
	},
	getMonthName:function() {
		return this._MonthName(this.month-1);
	},
	getYear:function() {
		return this.year;
	},
	_MonthName:function(month) {
		var months = ['January','February','March','April','May','June','July','August','September','October','November','December']
		return months[month];
	},
	_DaysInMonth:function(month,year) {
		var days = [31,28,31,30,31,30,31,31,30,31,30,31];
		if (month == 1) {
			if (year % 4 == 0) {
				if (year % 100 == 0 && year % 400 != 0) {
					return 28;
				}
				return 29;
			}
			return 28;
		} else {
			return days[month];
		}
	},
	_DayName:function(day) {
		var days = ['Su','M','Tu','W','Th','F','Sa'];
		return days[day];
	},
	_monthRight:function() {
		this._changeMonth(1);
		this.onMonthChange.bind(this)(this.month);
	},
	_monthLeft:function() {
		this._changeMonth(-1);
		this.onMonthChange.bind(this)(this.month);
	},
	_changeMonth:function(x) {
		var date = new Date(this.year,this.month - 1,1);
		date.setMonth(date.getMonth() + x);
		this.month = date.getMonth() + 1;
		this.year = date.getFullYear();
		this._setDays();
		this._showMonth();
	},
	_showMonth:function() {
		this._monthCell.innerHTML = this._MonthName(this.month-1)+'&nbsp;'+this.year
	},
	_setDays:function() {
		var date,firstDay,lastDay,row,rownum,td,i,day = 1;
		date = new Date(this.year,this.month - 1,1);
		firstDay = date.getDay();
		lastDay = this._DaysInMonth(this.month - 1,this.year);
		for (rownum=1;rownum<7;rownum++) {
			row = this._rows[rownum];
			for (i=0;i<7;i++) {
				td = row[i];
				if (rownum == 6 && day > lastDay) {
					// last row, but not needed.  just make all tds here empty
					td.Day.SetDate(null);
					Element.removeClassName(td,'CalDayOff'+this.type);
				} else if ( (rownum == 1 && i < firstDay) || ( day > lastDay ) ) {
					// before beginning of month or after the end
					td.Day.SetDate('&nbsp;');
					Element.addClassName(td,'CalDayOff'+this.type);
				} else {
					td.Day.SetDate(new Date(this.year,this.month - 1,day));
					day++;
					Element.removeClassName(td,'CalDayOff'+this.type);
				}
			}
		}
	},
	mouseOver:function(day) {
		if (day.date && day.date.getDate && day.cell) {
			Element.addClassName(day.cell,'CalDayOver');
			Element.addClassName(day.cell.parentNode,'CalWeekOver');
			var f = this.onMouseOverDay.bind(day);
			f();
		}
	},
	mouseOut:function(day) {
		if (day.cell) {
			Element.removeClassName(day.cell,'CalDayOver');
			Element.removeClassName(day.cell.parentNode,'CalWeekOver');
			var f = this.onMouseOutDay.bind(day);
			f();
		}
	},
	show:function() {
		if (!this.target) return;
		this._setDays();
		this.target.appendChild(this.table);
	},
	getMonthAsArray:function() {
		thisArray = new Array();
		var date,firstDay,lastDay,row,rownum,td,i,day = 1;
		date = new Date(this.year,this.month - 1,1);
		firstDay = date.getDay();
		lastDay = this._DaysInMonth(this.month - 1,this.year);
		for (rownum=1;rownum<7;rownum++) {
			row = this._rows[rownum];
			newrow = new Array();
			for (i=0;i<7;i++) {
				if (rownum == 6 && day > lastDay) {
					newrow.push('&nbsp;');
				} else if ( (rownum == 1 && i < firstDay) || ( day > lastDay ) ) {
					newrow.push('&nbsp;');
				} else {
					newrow.push(day);
					day++;
				}
			}
			thisArray.push(newrow);
		}
		return thisArray;
	},
	daysInMonth:function() {
		return this._DaysInMonth(this.month-1,this.year);
		
	},
	clickDate:function(dtObj) {
		if (dtObj.date && dtObj.date.getDate) {
			this.onSelectDay.bind(this)(dtObj.date);
		}
	}
});

CalendarDay = Class.create();
Object.extend(CalendarDay.prototype,{
	initialize:function(calendar,date,cell) {
		this.calendar = calendar;
		this.date = date;
		this.cell = cell;
		this._observe();
	},
	_observe:function() {
		if (this.cell) {
			Event.observe(this.cell,'mouseover',this._mouseOver.bind(this));
			Event.observe(this.cell,'mouseout',this._mouseOut.bind(this));
			Event.observe(this.cell,'click',this._click.bind(this));
		}
	},
	_mouseOver:function() {
		this.calendar.mouseOver(this);
	},
	_mouseOut:function() {
		this.calendar.mouseOut(this);
	},
	_click:function() {
		this.calendar.clickDate(this);
	},
	_dayOff:function(onOff) {
		if (this.cell) {
			onOff = (onOff) ? 'add' : 'remove'
			var f = eval('Element.'+onOff+'ClassName');
			f(this.cell,'CalDayOff'+this.calendar.type);
		}
	},
	SetDate:function(date) {
		this.date = date;
		if (date && date.getDate) {
			this.cell.innerHTML = date.getDate();
			this._dayOff(false);
		} else if (date && date.toString().length) {
			this.cell.innerHTML = date;
			this._dayOff(true);
		} else {
			this.cell.innerHTML = '';
			this._dayOff(false);
		}
	}
});

DatePicker = Class.create();
ActiveDatePicker=null;
//new DatePicker('field','container',{defaultDate:'mm/dd/yyyy'});
Object.extend(DatePicker.prototype,{
	initialize:function(id,target,options) {
		this.id=id;
		this.target=$(target);
		this.active=false;
		options.floating = options.floating || false;
		if (options.floating) {
			this.floatingDiv = Element.create('div');
			Element.addClassName(this.floatingDiv,'floating');
			this.floatingDiv.style.display='none';
			this.target.appendChild(this.floatingDiv);
			defaultTarget=this.floatingDiv;
			this.floating=true;
		} else {
			defaultTarget=this.target;
			this.floating=false;
		}
		var options = Object.extend({mode:'field',target:defaultTarget,defaultDate:'',onSelectDay:this.returnDay.bind(this)},options || { });
		this.mode = options.mode;
		if (this.mode == 'field') {
			this.inputField = Element.create('input',{type:'text',size:10,maxLength:15,id:this.id,name:this.id,value:options.defaultDate});
			this.target.appendChild(this.inputField);
			this.calImage = Element.create('img',{src:'images/icon_calendar.gif'});
			Element.addClassName(this.calImage,'pointer');
			Event.observe(this.calImage,'click',this.show.bind(this));
			this.target.appendChild(this.calImage);
			
			this.calendar = new Calendar(options);
			this.keyPressEvent = this.keyPress.bindAsEventListener(this);
		}
	},
	keyPress:function(event) {
		if (this.active) {
			switch(event.keyCode) {
				case Event.KEY_ESC:
					this.hide();
					break;
				case Event.KEY_LEFT:
					this.calendar._monthLeft();
					event.cancelBubble=true;
					Event.stop(event);
					return false;
					break;
				case Event.KEY_RIGHT:
					this.calendar._monthRight();
					event.cancelBubble=true;
					Event.stop(event);
					return false;
					break;
			}
		}
	},
	returnDay:function(date) {
		if (!date) return;
		if (this.mode == 'field') {
			this.inputField.value = eval(date.getMonth()+1)+'/'+date.getDate()+'/'+date.getFullYear();
		}
		if (this.floating) {
			this.hide();
		}
	},
	show:function() {
		Position.clone(this.calImage,this.floatingDiv,{setWidth:false,setHeight:false});
		if (ActiveDatePicker) ActiveDatePicker.hide();
		Element.addClassName(this.inputField,'activeField');
		this.floatingDiv.style.display='';
		this.active=true;
		Event.observe(document,'keypress',this.keyPressEvent);
		ActiveDatePicker=this;
	},
	hide:function() {
		Element.removeClassName(this.inputField,'activeField');
		this.floatingDiv.style.display='none';
		this.active=false;
		Event.stopObserving(document,'keypress',this.keyPressEvent);
		ActiveDatePicker=null;
	}
});

