/*document.observe('dom:loaded', function(){
	$$(".date_picker").each(function(containerBox){
		new DatePicker(containerBox, {icon:'css/icons/date_picker1.gif',
						calendarClass:'calendar_class',
						defaultSystemDate: true,
						defaultDay: 24,
						defaultMonth: 11,
						defaultYear: 2001,
						autoUpdate: true,
						fullMonthName: true,
						fullDayName: true,
						cellWidth: 22,
						cellHeight: 22,
						callBack: null,
						dateFormat: 'dd-mm-yyyy'
					});
	}); //$$
});//document.observe*/


//************************************************************************************

Calendar = Class.create({
initialize: function(container, options) {
	//Capturar parametros:
    this.container = $(container);
	this.options = options;
	this.options.defaultSystemDate = options.defaultSystemDate;
	this.options.defaultDay = options.defaultDay || 1;
	this.options.defaultMonth = options.defaultMonth || 1;
	this.options.defaultYear = options.defaultYear || 2010;
	this.options.fullMonthName = options.fullMonthName || false;
	this.options.cellWidth = options.cellWidth || 20;
	this.options.cellHeight= options.cellHeight || 20;
	this.options.callBack = options.callBack || null;
	this.options.dateFormat= options.dateFormat || "d/m/yyyy";

	//establecer estilos al container ppal:
	this.container.setStyle({width:(7*this.options.cellWidth)+'px'});

	this.currDay = new Date().getDate();
	this.currMonth = new Date().getMonth()+1;
	this.currYear = new Date().getFullYear();
	if(!this.options.defaultSystemDate){
		this.currDay = this.options.defaultDay;
		this.currMonth = this.options.defaultMonth;
		this.currYear = this.options.defaultYear;
	}

	//definir arreglos y vars. internas:
	var isLeapYear = function(anio) {
		return new Date(anio,1,29).getDate()==29;
	}//isLeapYear

	this.arr_monthNames=["Gennaio","Febbraio","Marzo","Aprile","Maggio","Giugno","Luglio","Agosto","Settembre","Ottobre","Novembre","Dicembre"];
	this.arr_monthDays=[31,28,31,30,31,30,31,31,30,31,30,31];
	if(isLeapYear(this.currYear)) this.arr_monthDays[1]=29;
	this.arr_dayOfWeek=["Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato","Domenica"];

	this.showCalendar(this.currDay,this.currMonth,this.currYear);
},//initialize


showCalendar: function(day, month, year){
	//Capturar parametros:
	this.currDay = day;
	this.currMonth=month;
	this.currYear=year;

	//Remover todo el contenido del calendario:
	$(this.container).descendants().each(function(elem){elem.remove();});

	//Obtener el dia de semana del 1er. dia del mes corriente (this.startDayOfWeek):
	//hacer que this.startDayOfWeek sea 0=Lunes, 1=Martes, ..., 5=Sabado, 6=Domingo
	this.startDayOfWeek = new Date(this.currYear,this.currMonth-1,1).getDay();
	if(this.startDayOfWeek==0) 
		this.startDayOfWeek=7; //pasar el domingo para el final
	this.startDayOfWeek--;

	//crear cabecera con el mes y anio:
	var header = new Element("div");
	header.addClassName(this.container.className+'_header');
	if(this.options.fullMonthName)
		header.insert(this.arr_monthNames[this.currMonth-1]+" de "+this.currYear);
	else
		header.insert(this.arr_monthNames[this.currMonth-1].substr(0,3)+" de "+this.currYear);
	this.container.insert(header);

	//fila con controles:
	var controls = new Element("div");
	this.container.insert(controls);

	//Crear los controles y sus observers:
	//-----------------------------------
	//control de año anterior:
	var cell = new Element("div");
	cell.addClassName(this.container.className+'_controls');
	cell.setStyle({float:'left',width:this.options.cellWidth+'px',textAlign:'left'});
	var link = new Element("a").insert("&lt;&lt;");
	link.setStyle({cursor:'pointer'});

//  Observar el link:
//	lo siguiente hubiera andado asi: (llamado dsde afuera de la clase)
//	link.observe("click",function(event){mical.prevYear()});
//  obviamente no queremos nombrar una instancia en particular, entonces si la llamamos asi:
//  link.observe("click", this.prevYear());
//  no funciona ya que this seria el propio link y no tiene ese metodo.

//  Por lo tanto debe usarse asi:
	link.stopObserving("click");
    link.observe("click", this.prevYear.bind(this));
//  para "atar" (bind) el metodo al objeto this.
//  asi tampoco ya que this hace referencia a la propia funcion:
//    link.observe("click", function(){this.prevYear.bind(this)});
	cell.insert(link);
	controls.insert(cell);

	//control de mes anterior:
	var cell = new Element("div");
	cell.addClassName(this.container.className+'_controls');
	cell.setStyle({float:'left',width:this.options.cellWidth+'px',textAlign:'center'});
	var link = new Element("a").insert("&lt;");
	link.setStyle({cursor:'pointer'});
	link.stopObserving("click");
    link.observe("click", this.prevMonth.bind(this));
	cell.insert(link);
	controls.insert(cell);

	//control de hoy:
	var cell = new Element("div");
	cell.addClassName(this.container.className+'_controls');
	cell.setStyle({float:'left',width:(3*this.options.cellWidth)+'px',textAlign:'center'});
	var link = new Element("a").insert("oggi");
	link.setStyle({cursor:'pointer'});
	link.stopObserving("click");
    link.observe("click", this.showCalendar.bind(this,new Date().getDate(),1+new Date().getMonth(),new Date().getFullYear()));
	cell.insert(link);
	controls.insert(cell);

	//control de mes siguiente:
	var cell = new Element("div");
	cell.addClassName(this.container.className+'_controls');
	cell.setStyle({float:'left',width:this.options.cellWidth+'px',textAlign:'center'});
	var link = new Element("a").insert("&gt;");
	link.setStyle({cursor:'pointer'});
	link.stopObserving("click");
    link.observe("click", this.nextMonth.bind(this));
	cell.insert(link);
	controls.insert(cell);

	//control de año siguiente:
	var cell = new Element("div");
	cell.addClassName(this.container.className+'_controls');
	cell.setStyle({float:'left',width:(1*this.options.cellWidth)+'px',textAlign:'right'});
	var link = new Element("a").insert("&gt;&gt;");
	link.setStyle({cursor:'pointer'});
	link.stopObserving("click");
    link.observe("click", this.nextYear.bind(this));
	cell.insert(link);
	controls.insert(cell);


	//cambiar de fila
	var dayCell = new Element("div");
	dayCell.setStyle({clear:'both'});
	this.container.insert(dayCell);

	//crear titulo con los nombres de los dia de semana:
	for(var dow=0;dow<=6;dow++){
		var dayCell = new Element("div");
		dayCell.addClassName(this.container.className+'_week');
		dayCell.setStyle({float:'left',width:this.options.cellWidth+'px',height:this.options.cellHeight+'px',textAlign:'center'});
		dayCell.insert(this.arr_dayOfWeek[dow].substr(0,2));
		this.container.insert(dayCell);
	}

	//cambiar de fila
	var dayCell = new Element("div");
	dayCell.setStyle({clear:'both'});
	this.container.insert(dayCell);

	//1er fila: completar celdas vacias hasta el dia actual:
	var cellCount=0;
	for(var dayCol=0;dayCol<this.startDayOfWeek;dayCol++){
		var dayCell = new Element("div");
		dayCell.setStyle({float:'left',width:this.options.cellWidth+'px',height:this.options.cellHeight+'px'});
		dayCell.className=this.container.className+'_day';
		this.container.insert(dayCell);
		cellCount++;
	}//for

	//completar todo el mes:
	var day=1;
	while(day<=this.arr_monthDays[this.currMonth-1]){
		var dayCell = new Element("div");

		if(day==new Date().getDate() && this.currMonth == (new Date().getMonth()+1) && this.currYear == new Date().getFullYear())
			dayCell.addClassName(this.container.className+'_today');
		else
			if(day==this.options.defaultDay && this.options.defaultMonth==this.currMonth && this.options.defaultYear==this.currYear)
				dayCell.addClassName(this.container.className+'_day_default');
			else
				dayCell.addClassName(this.container.className+'_day');
		dayCell.setStyle({float:'left',width:this.options.cellWidth+'px',height:this.options.cellHeight+'px',textAlign:'center',cursor:'pointer'});
		dayCell.insert(day);
		this.container.insert(dayCell);

		//observar el mouseover y el mouseout
		//ambos eventos responden a las clases css:
		//.calendar_class_day, .calendar_class_day_mouseover y .calendar_class_today
		var classThis=this; //salvar el this de la clase para evitar confundir con el this de la funcion:
		this.lastClassName=''; //controla el nombre de la ultima clase que paso el mouse encima de los nros de dias
		dayCell.stopObserving("mouseover");
	    dayCell.observe("mouseover", function(){
			classThis.lastClassName=this.className;
			this.className=classThis.container.className+'_day_mouseover';
		});
		dayCell.stopObserving("mouseout");
	    dayCell.observe("mouseout", function(){	this.className=classThis.lastClassName;});

		cellCount++;
		day++;
		if(cellCount%7==0){//se llego al domingo? => nueva fila
			var dayCell = new Element("div");
			dayCell.setStyle({clear:'both'});
			this.container.insert(dayCell);
		}
	}//while

	//completar las celdas vacias que faltan:
	while(cellCount%7!=0){
		var dayCell = new Element("div");
		dayCell.setStyle({float:'left',width:this.options.cellWidth+'px',height:this.options.cellHeight+'px'});
		dayCell.className=this.container.className+'_day';
		this.container.insert(dayCell);
		cellCount++;
	}//while


	//Observar las celdas con dias:
	var this_tmp =this;
	//se usa la var. this_tmp porque despues el this se confunde dentro de la funcion
	$$('.'+this.container.className+'_day', '.'+this.container.className+'_today').each(function(elem){
		elem.stopObserving("click");
		elem.observe("click", this_tmp.dateClicked.bind(this_tmp,elem.innerHTML));
	})

},//showCalendar


removeCalendar: function(){
	//Remover todo el contenido del calendario:
	$(this.container).descendants().each(function(elem){elem.remove();});
	$(this.container).remove();
},//removeCalendar


nextMonth: function(){
	if(this.currMonth<12) this.currMonth++;
	else this.currMonth=1;	
	this.showCalendar(this.currDay,this.currMonth,this.currYear);
},//nextMonth


prevMonth: function(){
	if(this.currMonth>1) this.currMonth--;
	else this.currMonth=12;	
	this.showCalendar(this.currDay,this.currMonth,this.currYear);
},//prevMonth


nextYear: function(){
	this.currYear++;
	this.showCalendar(this.currDay,this.currMonth,this.currYear);
},//nextYear


prevYear: function(){
	this.currYear--;
	this.showCalendar(this.currDay,this.currMonth,this.currYear);
},//prevYear


formatDate: function(){
	var dateFormat = this.options.dateFormat;
	//se mira el dateFormat y se cuentan cuantos digitos tiene c/componente (dia, mes y anio):
	var d_count = dateFormat.str_count('d');
	var m_count = dateFormat.str_count('m');
	var y_count = dateFormat.str_count('y');
	//se crear cadenas de patterns:
	var d_patt = str_repeat('d', d_count);
	var m_patt = str_repeat('m', m_count);
	var y_patt = str_repeat('y', y_count);
	//se crean cadenas rellenas con 0's a la izquierda con c/componente:
	var d_str = String(this.currDay).lpad('0', d_count);
	var m_str = String(this.currMonth).lpad('0', m_count);
	var y_str = String(this.currYear).lpad('0', y_count);
	//se arma la fecha de salida:
	dateFormat = dateFormat.str_replace(d_patt, d_str);
	dateFormat = dateFormat.str_replace(m_patt, m_str);
	dateFormat = dateFormat.str_replace(y_patt, y_str);
	return dateFormat;
},//formatDate


dateClicked: function(dayCliqued){
	this.currDay = dayCliqued;
	if(this.options.callBack!=null)
		this.options.callBack(this.formatDate());
	this.removeCalendar();	
}//dateClicked
});// Calendar = Class.create

//***********************************************************************

DatePicker = Class.create({
initialize: function(containerBox, DatePickerDefaults) {
	this.DatePickerDefaults = DatePickerDefaults;
	var textBox = $(containerBox).down();
	if(!textBox.id)//si la caja de texto no tiene id, forzar uno:
		textBox.writeAttribute("id", textBox.identify());

	//crear el icono del DatePicker con el id=textBox + '_icon':
	var iconElem = new Element("img", {id:textBox.identify()+'_icon'});
	this.iconId = iconElem.identify();
	iconElem.src = this.DatePickerDefaults.icon;
	var left = parseInt(textBox.offsetLeft)+parseInt(textBox.offsetWidth);
	var top = parseInt(textBox.offsetTop);
	iconElem.setStyle({position:'relative',left:'0px',top:'6px',cursor:'pointer',zIndex:100});
	$(containerBox).insert(iconElem); //el $() es porque en IE sino no anda
	iconElem.observe("click", this.openDatePicker.bind(this, iconElem));
},//initialize


getTextBoxId:function(iconElem){
//retorna el id del textbox asociado al icono iconElem:
var iconElemId = iconElem.id;
//quitar el "_icon" del id del icono para obtener el id del textbox:
var textBoxId = iconElemId.substr(0,iconElemId.length-5);
return textBoxId;
}, //getTextBoxId


UnFormatDate: function(value, dateFormat, func_output){
//obtiene el dia, mes y año a partir de value con el formato dateFormat:
//Si value=09-12-2010 y dateFormat=dd-mm-yyyy => day=9, month=12, year=2010
//Si value=9-6-2010 y dateFormat=m-d-yyyy => day=6, month=9, year=2010
//los parametros de salida estan dentro de func_output
var d_count=dateFormat.str_count('d');
var m_count=dateFormat.str_count('m');
var y_count=dateFormat.str_count('y');
var d_pos=dateFormat.indexOf(str_repeat('d',d_count));
var m_pos=dateFormat.indexOf(str_repeat('m',m_count));
var y_pos=dateFormat.indexOf(str_repeat('y',y_count));

if(value.length==dateFormat.length){
	func_output.day = parseInt(value.substr(d_pos,d_count),10);
	func_output.month = parseInt(value.substr(m_pos,m_count),10);
	func_output.year = parseInt(value.substr(y_pos,y_count),10);
}
else{
	func_output.day = new Date().getDate();
	func_output.month = new Date().getMonth()+1;
	func_output.year = new Date().getFullYear();
}
},//UnFormatDate


openDatePicker: function(iconElem){
	//abrir el date picker:
	this.calendarIsOpen = true;
	//crear un contenedor para el calendario:
	this.calendarContainer = new Element("div");
	this.calendarContainer.addClassName(this.DatePickerDefaults.calendarClass);

	var pos = this.findPos(iconElem);
	var left = pos[0];
	var top  = pos[1];
	this.calendarContainer.setStyle({	position:'absolute',
									left:(left+iconElem.offsetWidth)+'px',
									top:top+'px',
									zIndex:101});

	//insertar el contenedor del calendario en el body:
	$(document.body).insert(this.calendarContainer);

	//hacer draggable el contenedor del calendariO:
	new Draggable(this.calendarContainer);

	if(this.DatePickerDefaults.autoUpdate){
		var textBoxValue = $(this.getTextBoxId(iconElem)).value;
		var func_output = {};
		this.UnFormatDate(textBoxValue, this.DatePickerDefaults.dateFormat, func_output);
		this.DatePickerDefaults.defaultDay = func_output.day;
		this.DatePickerDefaults.defaultMonth = func_output.month; 
		this.DatePickerDefaults.defaultYear = func_output.year;
	}

	//crear instancia de calendario:
	this.calendar = new Calendar(this.calendarContainer, this.DatePickerDefaults);

	if(this.DatePickerDefaults.callBack==null){
	//Forzar el callBack del calendario con el metodo closeDatePicker():
	var closeFunc=this.closeDatePicker;
	var classThis=this; //copia de this para pasarle a closeFunc():
	this.DatePickerDefaults.callBack = function(datePicked){
		closeFunc(classThis, datePicked, iconElem); 
		//se usa una var. local 'closeFunc' para no confundir
		//el this de la clase con el de la funcion
	};
	}
	//observar c/vez que se pulsa el mouse:
	$(document.body).stopObserving("mousedown");
	$(document.body).observe('mousedown', this.mouseDown.bind(this));
},//openDatePicker


closeDatePicker: function(classThis, datePicked, iconElem){
//este metodo es llamado al clickear sobre un dia del calendario.
//es la funcion de callBack del calendario
//classThis es el this de la clase DatePicker
$(document.body).stopObserving("mousedown");
$(classThis.getTextBoxId(iconElem)).value=datePicked;

},//closeDatePicker


mouseDown: function(event){
//si se pulsa el mouse fuera del date picker (siempre que este esté abierto!), cerrarlo:
var x=Event.pointerX(event);
var y=Event.pointerY(event);
var x0=parseInt(this.calendarContainer.offsetLeft);
var x1=parseInt(this.calendarContainer.offsetLeft)+parseInt(this.calendarContainer.offsetWidth);
var y0=parseInt(this.calendarContainer.offsetTop);
var y1=parseInt(this.calendarContainer.offsetTop)+parseInt(this.calendarContainer.offsetHeight);
var okx = (x>=x0 && x<=x1);
var oky = (y>=y0 && y<=y1);
if(this.calendarIsOpen && (!okx || !oky)){
	$(document.body).stopObserving("mousedown");
	this.calendar.removeCalendar();
	this.calendarIsOpen=false;
}
},//mouseDown

findPos:function(obj) {
var curleft = curtop = 0;
if (obj.offsetParent) {
do {
    curleft += obj.offsetLeft;
    curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
}
return [curleft,curtop];
}//findPos

});//DatePicker = Class.create


