  /****************************************************************************/
 /*   vlaCalendar Clientside v1.0.1 extension for vlaCalendar version 2.1    */
/****************************************************************************/
  /*********************************************************/
 /*   vlaCalendar version 2.1 for mootools release 1.2    */
/*********************************************************/

var vlaCalendar = new Class({
	'slideDuration': 500,
	'fadeDuration': 500,
	'transition': Fx.Transitions.Quart.easeOut,
	'startMonday': false,
	'filePath': 'inc/',
	'defaultView': 'month',
	'style': '',
	
	initialize: function(_container, _options) {
		//Add the provided options to this object by extending
		if(_options) $extend(this, _options);
		
		this.loading = false;
		this.container = _container = $(_container);
		var _class = this;
		
		//Insert the base into the container and initialize elements
		var  pars = 'defaultView='+ this.defaultView;
		if(this.picker) {
			if($type(this.prefillDate) == 'object' && this.getInputDate(this.prefillDate)) pars += '&pickedDate='+ this.getInputDate(this.prefillDate);
			if(this.linkWithInput) pars += '&gotoPickedDate=1';
		}
		this.u('base', pars, function() { 
			_class.mainLoader = _container.getElement('div[class=loaderA]');
			_class.tempLoader = _container.getElement('div[class=loaderB]');
			_class.label 	  = _container.getElement('span[class=label]');
			_class.arrowLeft  = _container.getElement('div[class=arrowLeft]');
			_class.arrowRight = _container.getElement('div[class=arrowRight]');				
			_class.initializeCalendarFunctions();
			
			//Prefill/load picker date elements
			if(_class.picker) {
				if($type(_class.prefillDate) == 'object' && _class.getInputDate(_class.prefillDate)) _class.pick(_class.prefillDate);
				else if(_class.prefillDate == true) _class.pick(JSON.decode(_class.label.getProperty('date')));
			}
		}, _container);
	},
	
	initializeCalendarFunctions: function() {
		this.resetArrows();
		
		//Retrieve data (label, timestamp etc) which are stored as a Json string in the table attribute summary
		var vars = JSON.decode(this.mainLoader.getElement('table').getProperty('summary'));
		var _class = this; 
		
		//Change the label
		this.label.removeClass('noHover').set('html', vars.label)
			.onclick = vars.parent ? function() { _class.u(vars.parent, 'ts=' + vars.ts + '&parent=' + vars.current, function() { _class.fade() }) } : null;
			
		//Hide arrows if necessary and add arrow click events
		if(vars.hide_left_arrow) this.hideLeftArrow();
		else if(vars.hide_right_arrow) this.hideRightArrow();
		
		this.arrowLeft.onclick  = function() { _class.u(vars.current, 'ts=' + vars.pr_ts, function() { _class.slideLeft() }) }
		this.arrowRight.onclick = function() { _class.u(vars.current, 'ts=' + vars.nx_ts, function() { _class.slideRight() }) }		
		
		//Add cell click events
		var clickables = this.mainLoader.getElements('td');
		switch(vars.current) {
			case 'month':
				if(this.picker) {
					clickables.each(function(_clickable) {
						_clickable.onclick = function() { 
							_class.pick(JSON.decode(_clickable.getProperty('date')));
							_class.mainLoader.getElements('td').each(function(_clickable) { _clickable.removeClass('selected') });
							this.addClass('selected'); 
						}
					});
				}
				break;
			case 'year':
				clickables.each(function(_clickable) {
					_clickable.onclick = function() { _class.u('month', 'ts=' + _clickable.getProperty('ts'), function() { _class.fade() }) }
				});
				break;
			case 'decade':
				this.label.addClass('noHover');
				clickables.each(function(_clickable) {
					_clickable.onclick = function() { _class.u('year', 'ts=' + _clickable.getProperty('ts') + '&m_ts=' + _clickable.getProperty('m_ts'), function() { _class.fade() }) }
				});
				break;
		}
	},
	
	//Ajax updater function which handles all requests
	u: function(_url, _pars, _onComplete, _id) {
		if(!this.loading && !this.transitioning) {
			var _class = this;
			this.loading = true;
			var element = $(_id ? _id : this.tempLoader);
			_pars += '&picker=' + (this.picker ? 1 : 0) + '&startMonday=' + (this.startMonday ? 1 : 0) + '&style=' +  this.style;
			if(this.picker && this.getInputDate()) _pars += '&pickedDate='+ this.getInputDate();
			new Request({ method: 'post',
						  url: this.filePath + _url + '.php',
						  onComplete: function(data) { element.set('html', data); _onComplete(); _class.loading = false; }
						}).send(_pars);
		}
	},
	
	slideLeft: function() {
		var _class = this;
		this.transitioning = true;	
		this.tempLoader.setStyle('opacity', 1).set('tween', { duration: this.slideDuration, transition: this.transition }).tween('margin-left', [-164, 0]);
		this.mainLoader.setStyle('opacity', 1).set('tween', { duration: this.slideDuration, transition: this.transition, onComplete: function() { _class.transitioning = false } })
			.tween('margin-left', [0, 164]);
		this.switchLoaders();
	},
	
	slideRight: function() {
		var _class = this;
		this.transitioning = true;
		this.mainLoader.setStyle('opacity', 1).set('tween', { duration: this.slideDuration, transition: this.transition }).tween('margin-left', [0, -164]);
		this.tempLoader.setStyle('opacity', 1).set('tween', { duration: this.slideDuration, transition: this.transition, onComplete: function() { _class.transitioning = false } })
			.tween('margin-left', [164, 0]);
		this.switchLoaders();
	},
	
	fade: function(overRuleTrans) {
		var _class = this;
		this.transitioning = overRuleTrans ? false : true;
		this.tempLoader.setStyles({'opacity': 0, 'margin-left': 0});
		this.mainLoader.set('tween', { duration: this.fadeDuration, transition: this.transition}).fade('out');
		this.tempLoader.set('tween', { duration: this.fadeDuration, transition: this.transition, 
			onComplete: function() { 
					_class.tempLoader.setStyles({'opacity': 1, 'margin-left': -999});
					_class.transitioning = false;
				} 
			}).fade('in');
		this.switchLoaders();
	},
	
	switchLoaders: function() {
		this.mainLoader = this.mainLoader.className == 'loaderA' ? this.container.getElement('div[class=loaderB]') : this.container.getElement('div[class=loaderA]');
		this.tempLoader = this.tempLoader.className == 'loaderA' ? this.container.getElement('div[class=loaderB]') : this.container.getElement('div[class=loaderA]');
		this.initializeCalendarFunctions();
	},
	
	resetArrows: function() {
		this.arrowLeft.setStyle('visibility', 'visible');
		this.arrowRight.setStyle('visibility', 'visible');
	},
	
	hideLeftArrow: function() {
		this.arrowLeft.setStyle('visibility', 'hidden');
	},
	
	hideRightArrow: function() {
		this.arrowRight.setStyle('visibility', 'hidden');
	} 
});

var vlaDatePicker = new Class({
	Extends: vlaCalendar,
	
	'separateInput': false,
	'prefillDate': true,
	'linkWithInput': true,
	'leadingZero': true,
	'twoDigitYear': false,
	'separator': '/',
	'format': 'm/d/y',
	'openWith': null,
	'alignX': 'right',
	'alignY': 'inputTop',
	'offset': { 'x': 0, 'y': 0 },
	'style': '',
	'ieTransitionColor' : '#ffffff',
	'toggleDuration': 350,
	'pickEvent': function() {},
	initialize: function(_element, _options) {
		//Add the provided options to this object by extending
		if(_options) $extend(this, _options);
		
		this.element = $(_element);
		if(!this.element) throw 'No (existing) element to create a datepicker for specified: new vlaDatePicker(ELEMENT, [options])';
		
		//Check if the user wants multiple input
		if(this.separateInput) {
			this.element.day   = this.element.getElement('input[name='+ this.separateInput.day +']');
			this.element.month = this.element.getElement('input[name='+ this.separateInput.month +']');
			this.element.year  = this.element.getElement('input[name='+ this.separateInput.year +']');
		}
		
		//Create the picker and calendar and inject in in the body
		this.picker = new Element('div', { 'class': 'vlaCalendarPicker' + (this.style != '' ? ' ' + this.style : '') }).injectTop($(document.body));
		this.pickerContent = new Element('div', { 'class': 'pickerBackground' }).injectTop(this.picker);
		this.parent(this.pickerContent);
		
		//Add events for showing and hiding the picker
		var _class = this;
		(this.openWith ? $(this.openWith) : this.element)
			.addEvent('focus',  function() { _class.show(); })
			.addEvent('click',  function() { _class.openWith ? _class.toggle() : _class.show() })
			.addEvent('change', function() { _class.hide(); });
		
		//If the datepicker is visible an outside click makes it hide
		document.addEvent('mousedown', function(e) { if(_class.outsideHide && _class.outsideClick(e, _class.picker)) _class.hide() });
		
		//linkWithInput
		if(this.linkWithInput) {
			if(this.separateInput) {
				this.element.day.addEvent('keyup',  function() { _class.linkedUpdate() });
				this.element.month.addEvent('keyup',  function() { _class.linkedUpdate() });
				this.element.year.addEvent('keyup',  function() { _class.linkedUpdate() });
			} else {
				this.element.addEvent('keyup',  function() { _class.linkedUpdate() });
			}
		}
		
		this.visible = false;
		this.outsideHide = false;
	},
	
	//Position the picker
	position: function() {
		var top, left;
		
		switch(this.alignX) {
			case 'left':
				left = this.element.getLeft();
				break;
			case 'center':
				var pickerMiddle = this.pickerContent.getStyle('width').toInt() / 2;
				if(pickerMiddle == 0) pickerMiddle = 83;
				left = this.element.getLeft() + (this.element.getSize().x / 2) - pickerMiddle -
						((parseInt(this.pickerContent.getStyle('padding-left')) + parseInt(this.pickerContent.getStyle('padding-right'))) / 2);
				break;
			case 'right': default:
				left = this.element.getLeft() + this.element.getSize().x;
				break;
		}
		
		switch(this.alignY) {
			case 'bottom':
				top = this.getPos(this.element).y + this.element.getSize().y;
				break;
			case 'top': 
				top = this.getPos(this.element).y - parseInt(this.pickerContent.getStyle('height')) - 
					(parseInt(this.pickerContent.getStyle('padding-top')) + parseInt(this.pickerContent.getStyle('padding-bottom')));
				break;
			case 'inputTop': default:
				top = this.getPos(this.element).y;
		}
		
		if(this.isNumber(this.offset.x)) left += this.offset.x;
		if(this.isNumber(this.offset.y)) top += this.offset.y;
		
		this.picker.setStyles({ 'top': top, 'left': left });
	},
	
	show: function() {
		this.position();
		if(!this.visible) {
			this.visible = true;
			var _class = this;
			this.picker.setStyles({ 'opacity': 0, 'display': 'inline' });
			if(Browser.Engine.trident5) this.picker.setStyle('background-color', this.ieTransitionColor); //Ugly transition fix for IE7
			this.picker.set('tween', { onComplete: function() { 
					if(Browser.Engine.trident5) _class.picker.setStyle('background-color', 'transparent');
					_class.outsideHide = true; 
				}, duration: this.toggleDuration }).fade('in');
		}
	},
	
	hide: function() {
		if(this.visible) {
			this.visible = false;
			var _class = this;
			if(Browser.Engine.trident5) this.picker.setStyle('background-color', this.ieTransitionColor); //Ugly transition fix for IE7
			this.picker.set('tween', { onComplete: function() { _class.picker.setStyle('display', 'none'); _class.outsideHide = false; }, duration: this.toggleDuration }).fade('out');
		}
	},
	
	toggle: function() {
		if(this.visible) this.hide();
		else this.show();
	},
	
	pick: function(_date) {
		if(this.leadingZero) {
			if(_date.day < 10)   _date.day = '0' + _date.day;
			if(_date.month < 10) _date.month = '0' + _date.month;
		}
		if(this.twoDigitYear) _date.year = _date.year.toString().substring(2, 4);
		
		if(this.separateInput) {
			if(this.element.day)   this.element.day.set('value', _date.day);
			if(this.element.month) this.element.month.set('value', _date.month);
			if(this.element.year)  this.element.year.set('value', _date.year);
			this.hide();
		} else {
			switch(this.format) {
				case "m/d/y": this.element.set('value', _date.month + this.separator + _date.day + this.separator + _date.year); break;
				case "y/m/d": this.element.set('value', _date.year + this.separator + _date.month + this.separator + _date.day); break;
				case "y/d/m": this.element.set('value', _date.year + this.separator +  _date.day + this.separator + _date.month); break;
				case "d/m/y": default: this.element.set('value', _date.day + this.separator + _date.month + this.separator + _date.year);
			}
			this.hide();
		}
		this.__DATE = _date;
		this.pickEvent();
	},
	
	getInputDate: function(_date) {
		var day, month, year;
		
		if(_date) {
			day = _date.day;
			month = _date.month;
			year = _date.year;
		} else if(this.separateInput) {
			day = this.element.day.get('value').toInt();
			month = this.element.month.get('value').toInt();
			year = this.element.year.get('value').toInt();
		} else {
			var date = this.element.get('value').split(this.separator);
			if(date.length != 3) return null;
			switch(this.format) {
				case "m/d/y": day = date[1]; month = date[0]; year = date[2]; break;
				case "y/m/d": day = date[2]; month = date[1]; year = date[0]; break;
				case "y/d/m": day = date[1]; month = date[2]; year = date[0]; break;
				case "d/m/y": default: day = date[0]; month = date[1]; year = date[2];
			}
		}
		
		if( !this.isNumber(day) || !this.isNumber(month) || !this.isNumber(year) ||	day == 0 || month == 0 || year == '0' ||
		    (this.twoDigitYear && year > 99) || (!this.twoDigitYear && year < 1979) || (!this.twoDigitYear && year > 2030) || month > 12 || day > 31 ) return null;
		
		if(this.twoDigitYear && this.isNumber(year) && year < 100) {
			year = year.toInt();
			if(year < 10) year = '200'+  year;
			else if(year < 70) year = '20'+  year;
			else if(year > 69) year = '19'+  year;
			else year = new Date().getFullYear();
		}
		
		return day +'/'+ month +'/'+ year;
	},
	
	//This function is being called on keyup event if linkWithInput is set to true and when a date is picked
	//If the full date is inserted the picker will change itself to that specific date (month view)
	linkedUpdate: function() {
		var _class = this;
		var date = this.getInputDate();
		if(date && this.pickedDate != date) {
			this.u('month', 'gotoPickedDate=1', function() { _class.fade(true) });
			this.pickedDate = date;
		}
	},
	
	outsideClick: function(_event, _element) {
		var mousePos = this.getMousePos(_event);
		var elementData = _element.getCoordinates();
		return (mousePos.x > elementData.left && mousePos.x < (elementData.left + elementData.width)) &&
			   (mousePos.y > elementData.top  && mousePos.y < (elementData.top + elementData.height)) ? false : true;
	},
	
	getMousePos: function(_event) {
		if(document.all) {
			return { 'x': window.event.clientX + window.getScrollLeft(),
					 'y': window.event.clientY + window.getScrollTop() };
		} else {
			return { 'x': _event.page['x'],
					 'y': _event.page['y'] };
		}
	},
	
	isNumber: function(_number) {
		if(_number == '') return false;
		return (_number >= 0) || (_number < 0) ? true : false;
	},
	
	//Retrieving positition funtions (like getCoordinates, getTop etc) don't seem to return correct values in some situations in mootools 1.2; 
	//Opera returns wrong values, IE returns too small values. This function returns the correct coordinates.
	getPos: function(_element) { 
		var x, y = 0;
		if(_element.offsetParent) {
			do {
				x += _element.offsetLeft;
				y += _element.offsetTop;
			} while(_element = _element.offsetParent);
		} else if(_element.x) {
			x += _element.x;
			y += _element.y;
		}
		return { 'x': x, 'y': y };
	}
});

Date.implement({
	getWeek: function() {
		var oneJan = new Date(this.getFullYear(), 0, 1);
		return Math.ceil((((this - oneJan) / 86400000) + oneJan.getDay()) / 7);
	},
	
	getTs: function() {
		return parseInt((this.getTime() / 1000));
	},
	
	getMonthNo: function() {
		return (this.getMonth() + 1);
	}
});

vlaCalendar.implement({
	//New vars
	'weekDayLabels': ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
	'monthLabels': ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
	'monthSmallLabels': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
	
	//Replaced functions
	u: function(_url, _pars, _onComplete, _id) {
		if(!this.loading && !this.transitioning) {
			this.loading = true;
			var _class = this;
			var element = $(_id ? _id : this.tempLoader);
			_pars += '&defaultView='+  _url;
			_pars += '&picker='+ (this.picker ? 1 : 0) +'&startMonday='+ (this.startMonday ? 1 : 0) +'&style='+ this.style;
			if(this.picker && this.getInputDate()) _pars += '&pickedDate='+ this.getInputDate();
			element.set('html', this.getHTML(_pars));
			_onComplete();
			this.loading = false;
		}
	},
	
	//New functions
	getHTML: function(args) {
		var pars = {};
		vars = args.split('&').each(function (e) {
			param = e.split('=');
			if(!pars[param[0]]) pars[param[0]] = param[1];
		});
		
		pars.startMonday = pars.startMonday.toInt();
		pars.picker = pars.picker.toInt();
		if(pars.gotoPickedDate) pars.gotoPickedDate = pars.gotoPickedDate.toInt();
		
		var pickedDate = null;
		if($defined(pars.pickedDate)) {
			if(pars.pickedDate == 't') {
				pickedDate = this.mkdate();					
				this.setDate(pickedDate);
			} else {
				match = pars.pickedDate.split('/');
				
				if(match != null) {
					if(match.length > 0) {
						pickedDate = this.mkdate(match[2], match[1] - 1, match[0]);
						if(pickedDate.getMonthNo() != match[1]) {
							pickedDate = this.mkdate(match[2], match[1] - 1, this.daysInMonth(match[2], match[1] - 1));
							this.setDate(pickedDate);
						}
					}
				}
			}
		}
		if(pickedDate == null) pickedDate = this.mkdate();
			
		if($defined(pars.ts)) {
			var date = new Date();
			date.setTime(parseInt(pars.ts) * 1000);
			ts = date.getTs();
		} else {
			ts = this.mktime(pickedDate.getFullYear(), pickedDate.getMonth(), 1);
		}
		
		pars.ts = ts;
		pars['pickedDate'] = pickedDate;
		
		if(pars.defaultView == 'decade') var picker = this.getDecadeHTML(pars);
		else if(pars.defaultView == 'year') var picker = this.getYearHTML(pars);
		else var picker = this.getMonthHTML(pars);
		
		if(!$defined(this.createContainer)) {
			this.createContainer = false;
			div  = '<div class="vlaCalendar'+ ($defined(args.style) ? ' '+ args.style : '') +'">';
				div += '<span class="indication"><div class="arrowRight"></div><div class="arrowLeft"></div>';
					div += '<span class="label" date="';
						div += "{'day': '"+ pickedDate.getDate() +"', 'month': '"+ pickedDate.getMonthNo() +"'";
						div += ", 'year': '"+ pickedDate.getFullYear() +'\'}">&nbsp;';
					div += '</span>';
				div += '</span>';
				div += '<div class="container">';
					div += '<div class="loaderB"></div>';
					div += '<div class="loaderA">'+ picker +'</div>';
				div += '</div>';
			div += '</div>';
			return div;
		} else return picker;
	},

	getMonthHTML: function(args) {
		var ts = this.ts2date(args.ts);
		var ts_year = ts.getFullYear();
		var ts_month = ts.getMonth();
		var ts_month_name = this.monthLabels[ts_month];
		var ts_nrodays = this.daysInMonth(ts.getFullYear(), ts.getMonth());
		
		var pr_date = this.mkdate(ts_year, ts_month-1, 1);
		var nx_date = this.mkdate(ts_year, ts_month+1, 1);
		
		var wdays_counter = ts.getDay() - (args.startMonday ? 1 : 0);
		if(wdays_counter == -1) wdays_counter = 6;
		
		ts = ts.getTs();
		var t = '<table class="month'+ (args.picker ? ' picker' : '') +'" cellpadding="0" summary="{';
			t += "'ts': '"+ ts +"', 'pr_ts': '"+ pr_date.getTs() +"', 'nx_ts': '"+ nx_date.getTs() +"', 'label': '"+ ts_month_name +", "+ ts_year +"'";
			t += ", 'current': 'month', 'parent': 'year'";
		t += '}">';
		t += '<tr>';
		
		if(args.startMonday) {
			var last_day = 6;
		} else {
			t += '<th>'+ this.weekDayLabels[6] +'</th>';
			var last_day = 5;
		}
		for(i = 0; i <= last_day; i++) {
			t += '<th>'+ this.weekDayLabels[i] +'</th>';
		}
		t += '</tr>';
		t += '<tr class="firstRow">';
		
		var row = 0;
		
		//Add days for the beginning non-month days
		for(i = 0; i < wdays_counter; i++) {
			last_day = this.daysInMonth(pr_date.getFullYear(), pr_date.getMonth());
			var day = last_day - (wdays_counter-i) + 1;
			i_date = this.mkdate(ts_year, ts_month-1, day, ts_year);
			t += '<td class="outsideDay" date="'+"{";
			t += "'day': '"+ day +"', 'month': '"+ i_date.getMonthNo() +"', 'year': '"+ i_date.getFullYear() +"'}";
			t += '">'+ day +'</td>';
		}
		
		//Add month days
		var pd_ts = args.pickedDate.getTs();
		for(i = 1; i <= ts_nrodays; i++) {
			i_date = this.mkdate(ts_year, ts_month, i); 
			i_ts = i_date.getTs();
			t += '<td'+ (i_ts == pd_ts ? ' class="selected"' : '');
			t += ' '+"date=\"{'day': '"+ i +"', 'month': '"+ i_date.getMonthNo() +"', 'year': '"+ ts_year +"'}\">";
			t += i; 
			t += '</td>';
			
			if(wdays_counter == 6) {
				// && (i - 1) != ts_nrodays) {
				week_num = i_date.getWeek() + 1;
				t += "</tr><tr>";
				wdays_counter = -1;
				row++;
			}
			wdays_counter++;
		}
		
		//Add outside days
		var a = 1;
		if(wdays_counter !== 0) {
			for(i = wdays_counter; i < 7; i++) {
				i_date = this.mkdate(ts_year, ts_month + 1, a); 
				i_ts = i_date.getTs();
				t += '<td class="outsideDay" date="'+"{'day': '"+ a +"', 'month': '"+ i_date.getMonthNo() +"', 'year': '"+ i_date.getFullYear() +"'}"+'">'+ a +'</td>';
				a++;
			}
			row++;
		}
		
		//Always have 6 rows
		if(row == 4 || row == 5) {
			if(wdays_counter !== 0) { t += "</tr><tr>"; }
			for(i = 0; i < (row == 5 ? 7 : 14); i++) {
				i_date = this.mkdate(ts_year, ts_month + 1, a); 
				t += '<td class="outsideDay" date="'+"{'day': '"+ a +"', 'month': '"+ i_date.getMonthNo() +"', 'year': '"+ i_date.getFullYear() +"'}"+'">'+ a +'</td>';
				a++;
				if(i == 6) { t += "</tr><tr>"; }
			}
		}	
		
		t += '</tr>';
		t += '</table>';
		return t;
	},

	getYearHTML: function(args) {
		var ts = this.ts2date(args.ts);
		if(args.parent == 'month') var m_ts = this.mktime(ts.getFullYear(), ts.getMonth(), 1); //Selected month timestamp
		else var m_ts = '';
		
		var pickedDate = args.pickedDate;
		
		var ts_year	= ts.getFullYear();
		var pr_ts = this.mktime(ts_year-1, 0, 1);
		var nx_ts = this.mktime(ts_year+1, 0, 1);
		
		ts = ts.getTs();
		var t = '<table class="year" cellpadding="0" summary="';
		t += "{'ts': '"+ ts +"', 'pr_ts': '"+ pr_ts +"', 'nx_ts': '"+ nx_ts +"', 'label': '";
			t += ts_year +"', 'current': 'year', 'parent': 'decade'";
		t += '}">';
		
		//Add years
		var m = 0;
		for(i = 0; i < 3; i++) {
			t += "<tr>";
			for(y = 0; y < 4; y++) {
				i_date = this.mkdate(ts_year, m, 1);
				i_ts = i_date.getTs();
				var current = (pickedDate.getMonthNo() == i_date.getMonthNo() && pickedDate.getFullYear() == i_date.getFullYear());
				t += '<td ts="'+ i_ts +'" class="'+ (m_ts == i_ts ? 'selected' : '') + (current ? 'current' : '') +'">'+ this.monthSmallLabels[i_date.getMonth()] +'</td>';
				m++;
			}
			t += "</tr>";
		}
		t += '</table>';
		return t;
	},

	getDecadeHTML: function(args) {
		var ts = this.ts2date(args.ts);
		var ts_year	= parseInt(ts.getFullYear());
		var decade = [ts_year-5, ts_year+5];
		
		var y_ts = this.mktime(ts.getFullYear(), 0, 1); 
		var m_ts = args.m_ts;
		
		var pr_ts = this.mktime(ts_year - 12, 0, 1);
		var nx_ts = this.mktime(ts_year + 12, 0, 1);
		
		var t = '<table class="year" cellpadding="0" summary="{';
		t += "'ts': '"+ ts.getTs() +"', 'pr_ts': '"+ pr_ts +"', 'nx_ts': '"+ nx_ts +"', 'label': '";
		t += (decade[0]) +' - '+ (decade[1]+1) +"', 'current': 'decade'"; 
		t += '}">';
		
		//Add decades
		var year = decade[0];
		for(i = 0; i < 3; i++) {
			t += "<tr>";
			for(y = 0; y < 4; y++) {
				i_ts = this.mktime(year, 0, 1);
				i_date = this.mkdate(year, 0, 1);
				t += '<td ts="'+ i_ts +'" m_ts="'+ m_ts +'" class="'+ (args.parent && y_ts == i_ts ? 'selected' : '') + (args.pickedDate.getFullYear() == i_date.getFullYear() ? 'current' : '') +'">'+ year +'</td>';
				year++;
			}
			t += "</tr>";
		}
		t += '</table>';
		
		return t;
	},
	
	setDate: function(jsdate) {
		this.pick({day: jsdate.getDate(), month: jsdate.getMonthNo(), year: jsdate.getFullYear()});
	},
	
	daysInMonth: function(iYear, iMonth) {
		return 32 - new Date(iYear, iMonth, 32).getDate();
	},

	mkdate: function(year, month, day) {
		var date = new Date();
		if($defined(year)) date.setYear(year);
		if($defined(month)) date.setMonth(month);
		if($defined(day)) date.setDate(day);
		
		date.setHours(0);
		date.setMinutes(0);
		date.setSeconds(0);
		date.setMilliseconds(0);
		return date;
	},

	ts2date: function(ts) {
		var date = new Date();
		date.setTime(parseInt(ts) * 1000);
		return date;
	},

	mktime: function(year, month, day) {
		var date = this.mkdate(year, month, day);
		return date.getTs();
	}
});