/*
if(typeof bebo == 'undefined') {
	bebo = {};
}
if(typeof bebo.ui == 'undefined') {
	bebo.ui = {};
}
*/

bebo.ui.DatePicker = new Class({
	Implements: [Options, Events],
	
	options: {
		dayChars: 1, // number of characters in day names abbreviation
		dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
		daysInMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
		format: 'mm/dd/yyyy',
		monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
		startDay: 7, // 1 = week starts on Monday, 7 = week starts on Sunday
		yearOrder: 'asc',
		yearRange: 10,
		yearStart: (new Date().getFullYear()),
		hideDelay: 500
	},
	
	initialize: function(input, options) {
		this.input = $(input);
		this.setOptions(options);
		
		// Finds the entered date, or uses the current date
		this.selectedDate = this.input.value==''?this.removeTime(new Date()):new Date(this.input.value);

		this.input.addClass('DatePicker');
		
		this.input.addEvent('focus', this.show.bindWithEvent(this));
		this.input.addEvent('click', this.show.bindWithEvent(this));
		this.input.addEvent('mouseenter', this.mouseEnter.bindWithEvent(this));
		this.input.addEvent('mouseleave', this.mouseLeave.bindWithEvent(this));
	},
	
	mouseEnter : function(event) {
		this.over = true;
	},
	
	mouseLeave : function(event) {
	   this.over = false;
      this.hide.delay(this.options.hideDelay, this);
	},

	show: function() {
      var ele = this.toElement();
      this.position();
      
      if(ele.getStyle('opacity')  == 0) {ele.fade('in');}
	},

	hide: function(force){
	   if(!force && this.over) {return;}
		this.input.blur();
		
		var ele = this.toElement();
      if(ele.getStyle('opacity') == 1) {ele.fade('out');}
	},
	
	position: function() {
	   var c = this.input.getCoordinates();
	   this.toElement().setStyles({'position': 'absolute', 'top': c.top, 'left': c.left});
	},

	toElement: function() {
		if(!this.element) {this.create();}
		return this.element;
	},
	
	removeTime: function(date) {
		return new Date(date.getFullYear(), date.getMonth(), date.getDate());
	},

	create: function() {
		var opt = this.options;
		
		var month = this.selectedDate.getMonth();
		var year = this.selectedDate.getFullYear();
		
		// Hide select boxes while calendar is up
		this.hideSelects();
		
		/* create the outer container */
		this.element = new Element('div', {'class':'dp_container'}).inject('eob-marker', 'before');
		this.element.addEvent('mouseenter', this.mouseEnter.bindWithEvent(this));
		this.element.addEvent('mouseleave', this.mouseLeave.bindWithEvent(this));
		
		/* create the calendar */
		this.calendar = new Element('div', {'class':'dp_cal'}).inject(this.element);
		
		/* create the date object */
		var date = new Date(this.selectedDate.getFullYear(), this.selectedDate.getMonth(), 1);
		
		//this is for leap year, to fix later
		//year % 4 == 0 ? opt.daysInMonth[1] = 29 : opt.daysInMonth[1] = 28;
		
		/* create the month select box */
		this.monthSel = new Element('select', {
			'events': {
				'change': function() {
					this.updateCalendar(this.yearSel.value, this.monthSel.value);
				}.bind(this)
			}
		});
		
		for (var m = 0; m < opt.monthNames.length; m++){
			this.monthSel.options[m] = new Option(opt.monthNames[m], m);
			if (month == m) {this.monthSel.options[m].selected = true;}
		}
		
		/* create the year select box */
		this.yearSel = new Element('select', {
			'events': {
				'change': function() {
					this.updateCalendar(this.yearSel.value, this.monthSel.value);
				}.bind(this)
			}
		});
		
		i = 0;
		
		if (opt.yearOrder == 'desc'){
			for (var y = opt.yearStart; y > (opt.yearStart - opt.yearRange - 1); y--){
				this.yearSel.options[i] = new Option(y, y);
				if(year == y) {this.yearSel.options[i].selected = true;}
				i++;
			}
		} else {
			for (y = opt.yearStart; y < (opt.yearStart + opt.yearRange + 1); y++){
				this.yearSel.options[i] = new Option(y, y);
				if(year == y) {this.yearSel.options[i].selected = true;}
				i++;
			}
		}

		this.calendar.adopt(this.monthSel, this.yearSel);
		
		this.updateCalendar(this.yearSel.value, this.monthSel.value);
	},
	
	updateCalendar: function(year, month) {
		var opt = this.options;
		var selDate = new Date(year, month, 1);
		var curDate = this.removeTime(new Date());
		
		/* get first day of week */
		var firstDay = (1-(7+selDate.getDay()-opt.startDay)%7);
		
		/* remove the old calendar if it still exists */
		var cal = this.calendar.getElement('table');
		if(cal) {cal.destroy();}
		
		/* start creating calendar */
		var calTable = new Element('table');
		var calTableTbody = new Element('tbody');
		
		/* create day names */
		calDayNameRow = new Element('tr');
		for (var i = 0; i < opt.dayNames.length; i++) {
			calDayNameRow.adopt(
				new Element('th', {
					'text': opt.dayNames[(opt.startDay+i)%7].substr(0, opt.dayChars)
				})
			);
		}
		calTableTbody.adopt(calDayNameRow);
		
		/* create the day cells */
		while (firstDay <= opt.daysInMonth[month]) {
			var calDayRow = new Element('tr');
			for (i = 0; i < 7; i++) {
				var date = new Date(year, month, firstDay);
				
				var calDayCell = new Element('td');
				if ((firstDay <= opt.daysInMonth[month]) && (firstDay > 0)) {
					calDayCell.set({
						'text': firstDay,
						'events': {
							'click': this.dateClick.bindWithEvent(this, date),
							'mouseenter': function() {
								this.addClass('hover');
							},
							'mouseleave': function() {
								this.removeClass('hover');								
							}
						}
					});
				} else {
					calDayCell.set({'class':'empty', 'text': ' '});
				}
				calDayRow.adopt(calDayCell);
				
				// Show the previous day
				if(this.input.value != "" && date.getTime() == this.selectedDate.getTime()) {
					calDayCell.addClass('selected');
				}
				
				// Show today
				if (date.getTime() == curDate.getTime()) {
					calDayCell.addClass('today');
				}
				firstDay++;
			}
			calDayRow.inject(calTableTbody);
		}
		
		calTable.adopt(calTableTbody);
		calTable.inject(this.calendar);
	},
	
	hideSelects: function() {
		if(window.ie6) {
			$$('select').addClass('dp_cal_hide');
		}
	},
	
	returnSelects: function() {
		if(window.ie6) {
			$$('select').removeClass('dp_cal_hide');
		}
	},
	
	dateClick: function(event, date) {
		this.calendar.getElements('td').removeClass('selected');
		event.target.addClass('selected');

		this.selectedDate = date;
		this.input.set('value', this.formatDate(date));
		
		this.hide(true);
	},
	
	/* Format the returning date value according to the selected formation */
	formatDate: function(date) {
		var year = date.getFullYear();
		var month = date.getMonth()+1;
		var day = date.getDate();
		
		/* setup the date string variable */
		var dateStr = '';
		
		/* check the length of day */
		if (day < 10) {day = '0' + day;}
		if (month < 10) {month = '0' + month;}
		
		/* check the format & replace parts // thanks O'Rey */
		dateStr = this.options.format.replace( /dd/i, day ).replace( /mm/i, month ).replace( /yyyy/i, year );
		
		/* return the date string value */
		return dateStr;
	}
});
