/*
Author:
	luistar15, <leo020588 [at] gmail.com>
License:
	MIT-style license.
 
Class
	datePicker
Arguments:
	input - DOM element
	options - see Options below
Options:
	startDate - [YYYY,MM(0-11),DD] or null | Default: (actual Date)
	position - object | Default: {x:'left',y:'bottom'}
	format - return date format | Default: '%d/%m/%Y'
		'%d	: day of the month(1-31)
		'%DD	: full textual representation of the week day (Lunes, Martes, ...)
		'%D	: short representation of the week day (Lun, Mar,...)
		'%m	: numeric representation of a month (1-12)
		'%MM	: full textual representation of the month (Enero, Febrero, ...)
		'%M	: short representation of month (Ene, Feb,...)
		'%y	: 2 digits representation of year (06,07,...)
		'%Y	: 4 digits representation of year (2006,20707,...)
	days - array with names of days | Default: spanish names
	months - array with names of months | Default: spanish names
	today - format to see today text | Default: false
	css_class - css class to assign to dataPicker box | Default: 'datePicker'
	offset - object with x and y distances from the input | Default: {x:0,y:2}
	marginYear - limits from show "years select" | Default: [-4,4]
	draggabñe - boolean | default: false
*/ 
var datePicker = new Class({
	options:{
		startDate: null,
		position: {x:'left',y:'bottom'},
		format: '%d/%m/%Y',
		days: ['Domingo','Lunes','Martes','Miércoles','Jueves','Viernes','Sábado'],
		months: ['Enero','Febrero','Marzo','Abril','Mayo','Junio','Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'],
		today: false,
		css_class: 'datePicker',
		offset: {x:0,y:0},
		marginYear: [-4,4],
		draggable: false
	},

	initialize:function(input,options){
		this.setOptions(options);
		this.current = new Date();
		if(this.options.startDate) this.current.setFullYear(this.options.startDate[0],this.options.startDate[1],this.options.startDate[2]);
		this.lastDates = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
		this.dp = new Element('div',{'class':this.options.css_class+' hidden'}).inject($E('body'));
		if(this.options.draggable) this.dp.makeDraggable({handle:new Element('div',{'class':'handle'}).inject(this.dp)});
		this.month = new Element('span',{'class':'month','events':{'click':this.displayMonths.bind(this)}}).setHTML(this.options.months[this.current.getMonth()]).inject(this.dp);
		this.year = new Element('span',{'class':'year','events':{'click':this.displayYears.bind(this)}}).setHTML(this.current.getFullYear()).inject(this.dp);
		new Element('span',{'class':'close','events':{'click':this.hide.bind(this)}}).setHTML('X').inject(this.dp);
		var dayTitles = ''; for(var i=0;i<this.options.days.length;i++) dayTitles+='<b>'+this.options.days[i].substr(0,1)+'</b>';
		new Element('div').setHTML(dayTitles).inject(this.dp);
		this.daysBox = new Element('div').inject(this.dp);
		if(this.options.today){
			this.today = new Date();
			var todayText = this.parseDate(this.today,this.options.today);
			new Element('a',{'href':'//'+todayText,'class':'today','events':{'click':this.setToday.bind(this)}}).setHTML(todayText).inject(this.dp);
		}
		this.input = input.addEvents({'click':this.show.bind(this),'focus':this.show.bind(this)});
		this.build();
	},
	
	build:function(){
		this.lastDates[1] = this.current.getFullYear()%4>0?28:29;
		if(this.current.getDate()>this.lastDates[this.current.getMonth()]) this.current.setDate(this.lastDates[this.current.getMonth()]);
		this.daysBox.innerHTML='';
		var currentMonth = this.current.getMonth();
		var startDay = this.current.getDay()-(this.current.getDate()%7); startDay+=startDay<0?8:1;
		var from = startDay<7?0-startDay:0;
		var to = this.lastDates[currentMonth]+startDay; if(to%7>0) to=to+(7-to%7); to-=startDay;
		var previousMonth = currentMonth==0?11:currentMonth-1;
		var previousStartDate = this.lastDates[previousMonth]-startDay+1;
		var firstNextDate = 1;
		for(var i=from;i<to;i++)
			if(i<0) new Element('span').setHTML(previousStartDate++).inject(this.daysBox);
			else if(i>this.lastDates[currentMonth]-1) new Element('span').setHTML(firstNextDate++).inject(this.daysBox);
			else new Element('a',{'href':'//day:'+(i+1),'class':i+1==this.current.getDate()?'selected':'','events':{'click':this.setDate.bind(this)}}).setHTML(i+1).inject(this.daysBox);
	},

	displayMonths:function(){
		this.selectMonth = new Element('p',{'class':'selectMonth','events':{'mouseleave':function(){this.remove()}}}).inject(this.dp);
		var handle = $E('.handle',this.dp);
		if(handle) this.selectMonth.setStyle('top',(handle.offsetHeight+handle.getStyle('margin-bottom').toInt())+'px');
		for(var i=0;i<12;i++) new Element('a',{'href':'//'+this.options.months[i],'value':i,'class':i==this.current.getMonth()?'selected':'','events':{'click':this.setMonth.bind(this)}}).setHTML(this.options.months[i]).inject(this.selectMonth);
	},

	displayYears:function(){
		this.selectYear = new Element('p',{'class':'selectYear','events':{'mouseleave':function(){this.remove()}}}).inject(this.dp);
		var handle = $E('.handle',this.dp);
		if(handle) this.selectYear.setStyle('top',(handle.offsetHeight+handle.getStyle('margin-bottom').toInt())+'px');
		for(var i=this.current.getFullYear()+this.options.marginYear[0];i<=this.current.getFullYear()+this.options.marginYear[1];i++) new Element('a',{'href':'//year:'+i,'class':i==this.current.getFullYear()?'selected':'','events':{'click':this.setYear.bind(this)}}).setHTML(i).inject(this.selectYear);
		new Element('a',{'href':'//increase-year','class':'more','events':{'click':this.decreaseYear.bind(this)}}).setHTML('-').injectTop(this.selectYear);
		new Element('a',{'href':'//decrease-year','class':'more','events':{'click':this.increaseYear.bind(this)}}).setHTML('+').inject(this.selectYear);
	},
	
	decreaseYear:function(event){
		new Event(event).stop();
		var el = event.target || event.srcElement;
		var year = el.getNext().innerHTML.toInt()-1;
		el.getParent().getLast().getPrevious().remove();
		new Element('a',{'href':'//year:'+year,'class':year==this.current.getFullYear()?'selected':'','events':{'click':this.setYear.bind(this)}}).setHTML(year).injectAfter(el);
	},

	increaseYear:function(event){
		new Event(event).stop();
		var el = event.target || event.srcElement;
		var year = el.getPrevious().innerHTML.toInt()+1;
		el.getParent().getFirst().getNext().remove();
		new Element('a',{'href':'//year:'+year,'class':year==this.current.getFullYear()?'selected':'','events':{'click':this.setYear.bind(this)}}).setHTML(year).injectBefore(el);
	},

	setYear:function(event){
		new Event(event).stop();
		var el = event.target || event.srcElement;
		if(el.innerHTML.toInt()==this.current.getFullYear()) return;
		this.year.setHTML(el.innerHTML);
		this.current.setFullYear(el.innerHTML.toInt());
		this.selectYear.remove();
		this.build();
	},
	
	setMonth:function(event){
		new Event(event).stop();
		var el = event.target || event.srcElement;
		if(el.getProperty('value').toInt()==this.current.getMonth()) return;
		this.month.setHTML(el.innerHTML);
		this.current.setMonth(el.getProperty('value').toInt());
		this.selectMonth.remove();
		this.build();
	},

	setDate:function(event){
		this.hide();
		new Event(event).stop();
		var el = event.target || event.srcElement;
		this.current.setDate(el.innerHTML.toInt());
		this.input.setProperty('value',this.parseDate(this.current,this.options.format));
		var prevSelected = $E('a.selected',this.dp); if(prevSelected) prevSelected.removeClass('selected');
		el.addClass('selected');
	},
	
	setToday:function(event){
		this.hide();
		new Event(event).stop();
		var year = this.today.getFullYear();
		var month = this.today.getMonth();
		var date = this.today.getDate();
		this.current.setFullYear(year,month,date);
		this.input.setProperty('value',this.parseDate(this.current,this.options.format));
		this.year.setHTML(year);
		this.month.setHTML(this.options.months[month]);
		$ES('div a',this.dp).each(function(el){if(el.hasClass('selected')) el.removeProperty('class'); else if(el.innerHTML==date) el.addClass('selected')});
	},

	show:function(){
		if(this.input.getProperty('prevent')) return;
		var pos = this.input.getCoordinates();
		this.dp.setStyles('top:'+(eval('pos.'+this.options.position.y).toInt()+this.options.offset.y)+'px;left:'+(eval('pos.'+this.options.position.x).toInt()+this.options.offset.x)+'px').removeClass('hidden');
	},
	
	hide:function(){
		this.dp.addClass('hidden');
	},
	
	parseDate:function(dateObject,format){
		return format.
		replace('%d',dateObject.getDate()).
		replace('%DD',this.options.days[dateObject.getDay()]).
		replace('%D',this.options.days[dateObject.getDay()].substr(0,3)).
		replace('%m',dateObject.getMonth()+1).
		replace('%MM',this.options.months[dateObject.getMonth()]).
		replace('%M',this.options.months[dateObject.getMonth()].substr(0,3)).
		replace('%y',('s'+dateObject.getFullYear()).substr(3)).
		replace('%Y',dateObject.getFullYear())
	}
	
});

datePicker.implement(new Options);