if (!CD3) var CD3 = {};

CD3.Calendar = Class.create({
	initialize: function(id){
		if (!id || (Object.isString(id) && !$(id))){
			this.container = new Element('div', {id: id || 'calendar', style: 'display: none; position: absolute; z-index: 1000;'});			
			document.body.appendChild(this.container);
		} else {
			this.container = $(id);
		}
		this.container.update(CD3.Calendar._template);
		
		this.calendar	= this.container.down('.calendar ul');
		this.name		= this.container.down('.field');
		this.today 		= new Date();
		this.date		= null;
		this.options	= Object.extend({
			max_date:	false,
			min_date:	false,
			onClick:	null,
			top:		0,
			left:		0
		}, arguments[1] || {});
		
		this.container.select('.prev', '.next').invoke('observe', 'click', function(e){
			var date = new Date(this.date.getFullYear(),
								this.date.getMonth() + (e.findElement('a').hasClassName('prev') ? -1 : 1),
								1); 
			
			if (this.options.max_date && date >= this.options.max_date)
				date = this.options.max_date;
			else if (this.options.min_date && date <= this.options.min_date)
				date = this.options.min_date;
			
			this.render(date);
		}.bind(this));
		
		if (Object.isFunction(this.options.onClick))
			this.calendar.observe('click', function(e){
				var a = e.findElement('a');
				if (!a || !parseInt(a.innerHTML)) return;
				
				if (this.options.max_date || this.options.min_date){
					var date = new Date(this.date.getFullYear(), this.date.getMonth(), parseInt(a.innerHTML)+1);
					if (this.options.max_date && date >= this.options.max_date)
						return;
					if (this.options.min_date && date <= this.options.min_date)
						return;
				}
				
				this.options.onClick.call(this, this.date.getFullYear(), this.date.getMonth()+1, parseInt(a.innerHTML));
				this.hide();
			}.bind(this));
	},
	destroy: function(){
		this.calender.stopObserving();
		this.container.select('.prev', '.next').invoke('stopObserving');
		this.container.destroy();
	},
	show: function(pos) {
		if (!pos) pos = {};
		
		this.container.show();
		this.render();
		this.container.setStyle({
			top:	(pos.top || this.options.top) + 'px',
			left:	(pos.left || this.options.left) + 'px'
		});
		
		(function(){
			document.observe('click', function(e){
				if (!e.findElement('#' + this.container.identify())){
					this.hide();
					e.stop();
				}
			}.bind(this));
		}).bind(this).defer();
	},
	hide: function() {
		this.container.hide();
		document.stopObserving('click');
	},
	toggle: function(pos){
		this[ this.container.visible() ? 'hide' : 'show' ](pos);
	},
	render: function(date){			
		this.date	= date || (date = this.today);
		var month	= date.getMonth();
		var year	= date.getFullYear();
		var code 	= [
			'<li class="head">Mo</li>',
			'<li class="head">Tu</li>',
			'<li class="head">We</li>',
			'<li class="head">Th</li>',
			'<li class="head">Fr</li>',
			'<li class="head">Sa</li>',
			'<li class="head">Su</li>'
		];
		
		var first_week_day = new Date(year, month, 1).getDay() - 1;
		if (first_week_day < 0)	first_week_day = 6;
		for(var i = 0; i < first_week_day; i++)
			code.push('<li>&nbsp;</li>');   

		var days_in_this_month = CD3.Calendar._days[month];
		if (year % 4 == 0 && month == 2) days_in_this_month++;
		if (days_in_this_month > 31) days_in_this_month = 31;
		for(var j = 1; j <= days_in_this_month; j++){	
			code.push('<li><a href="javascript:;"');
			if (this.today.getDate()	 == j  && 
				this.today.getMonth()	 == date.getMonth() && 
				this.today.getFullYear() == date.getFullYear()
			)
				code.push(' class="choosen"');
			code.push('>' + j + '</a></li>');
		}
		
		var rest_days_in_month = 7 - (i+j-1)%7;
		if (rest_days_in_month > 0 && rest_days_in_month < 7)
			for(var i=1; i <= rest_days_in_month; i++)
				code.push('<li>&nbsp;</li>');  
		
		this.name.innerHTML		= month + 1 + '.' + year;
		this.calendar.innerHTML	= code.join('');
	}
});

Object.extend(CD3.Calendar, {
	_template: [
		'<div class="calendar"><ul></ul><div class="clearboth"></div></div>',
		'<div class="clearboth"></div>',
		'<div class="calendarmonth">',
			'<span><a href="javascript:;" class="prev"></a></span>',
			'<div class="field"></div>',
			'<span><a href="javascript:;" class="next"></a></span>',
			'<div class="clearboth"></div>',
		'</div>'].join(''),
	_days: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
});