document.observe('dom:loaded', function()
{
	window.filter_selection = [];

	if ($('searchForm'))
	{
		/* Desactivar autocompletado */
		$('searchForm').writeAttribute({ autocomplete : 'off' });

		$('arrival').onchange = function(){setNewArrival($F(this));};
		$('departure').onchange = function(){setNewDeparture($F(this));};

		initDatePicker();

		/* Filtrar la entrada de fechas y noches */
		$('arrival').observe('keydown', function(event){filterInput(event); setNewArrival($F(event.element()), event.element());});
		$('arrival').observe('keyup', filterInput);

		$('departure').observe('keydown', function(event){filterInput(event); setNewDeparture($F(event.element()), event.element());});
		$('departure').observe('keyup', filterInput);

	}

	/* Procesar los datos de hoteles para el paginado y filtrado */
	if ($$('div.results-hotel'))
	{
		$$('div.results-hotel').each(function(element)
		{
			element.data = {};
			if (element.down('input[name=data-name]'))
			{
				element.data.orderName = element.down('input[name=data-name]').value.toLowerCase();
				element.data.orderPrice = parseInt(element.down('input[name=data-orderprice]').value, 10);
				element.data.zone = element.down('input[name=data-zone]').value;
				element.data.mainzone = element.down('input[name=data-mainzone]').value;
				element.data.category = element.down('input[name=data-category]').value;
				element.data.facilities = element.down('input[name=data-facilities]').value.split(',');
			}
		});
	}

	/* Preparar shadowbox */
	if ($$('a[rel=shadowboxPictures]').length)
	{
		Shadowbox.setup($$('a[rel=shadowboxPictures]'), {
			gallery:'Pictures',
			title:$('gallery_title').innerHTML,
			continuous:true
		});
	}

	/* Cuadro de búsqueda flotante */
	if ($('searchForm'))
	{
		Element.observe(window, 'scroll', searchFormScroll);
		searchFormScroll();
	}

	/* YUI History */
	if (window.YAHOO && YAHOO.util.History)
	{
		//YAHOO.util.History.register("filters", YAHOO.util.History.getBookmarkedState("filters") || "||", filtersModuleStateChange);
		YAHOO.util.History.register("page", YAHOO.util.History.getBookmarkedState("page") || "1", pageModuleStateChange);
		//YAHOO.util.History.register("order", YAHOO.util.History.getBookmarkedState("order") || "", orderModuleStateChange);

		YAHOO.util.History.initialize("yui-history-field", "yui-history-iframe");

		/* Restaurar el estado de la página y los filtros */
		YAHOO.util.History.onReady(function()
		{
			var filters = readCookie('filters');
			var pageState = YAHOO.util.History.getCurrentState('page');

			if (filters && pageState)
			{
				pageModuleStateChange(pageState, true);
				filtersModuleStateChange(filters, true);
			}
			else if (pageState)
			{
				pageModuleStateChange(pageState, false);
			}
		});
	}
	else
	{
		/* Restaurar el estado de los filtros */
		var filters = readCookie('filters');
		if (filters)
		{
			filtersModuleStateChange(filters, true);
		}
	}
});

/* Registra un nuevo estado de la página */
function navigate(module, identifier)
{
	if (window.YAHOO && YAHOO.util.History)
	{
		YAHOO.util.History.navigate(module, identifier);
	}
	else if (module === 'page')
	{
		pageModuleStateChange(identifier);
	}
}

/*
 * Evento al cambiar los filtros
 * Recoge los datos de la url y los restaura en el formulario
 * El orden es zone|category|facility
 */
function filtersModuleStateChange(str_filters, startup)
{
	$('filters').select('input.all').each(function(input){input.checked = true;});
	$('filters').select('input.one').each(function(input){input.checked = false;});

	str_filters.split(',').each(function(filter)
	{
		if ($(filter))
		{
			var type = filter.split('_')[0];
			$(filter).checked = true;
			showFilters(type, startup);
			toggleFilters($(filter), startup);
		}
	});
}

/* Evento al cambiar la paginación */
function pageModuleStateChange(state, noapply)
{
	var page = state.split('|')[0];
	var items = state.split('|')[1];
	var order = state.split('|')[2];

	if (page)
	{
		if ($('page_offset').down('option[value='+page+']'))
		{
			$('page_offset').setValue(page);
		}
		else
		{
			$('page_offset').selectedIndex = 1;
		}
	}

	if (items)
	{
		if ($('items_per_page').down('option[value='+items+']'))
		{
			$('items_per_page').setValue(items);
		}
		else
		{
			$('items_per_page').selectedIndex = 1;
		}
	}

	if (order)
	{
		if ($('ordering').down('option[value='+order+']'))
		{
			$('ordering').setValue(order);
		}
		else
		{
			$('ordering').selectedIndex = 1;
		}
	}

	if (!noapply)
	{
		applyFilters((order !== null), true);
	}
}

/* Despliega un grupo de filtros */
function showFilters(type, startup)
{
	$('filter_group_title_' + type).addClassName('filter-group-title-open');

	if (startup)
	{
		$('filter_group_' + type).show();
	}
	else
	{
		new Effect.toggle($('filter_group_' + type), 'slide', {
			duration:0.4,
			afterUpdate:searchFormScroll,
			afterFinish:function()
			{
				if (!$('filter_group_' + type).visible())
				{
					$('filter_group_title_' + type).removeClassName('filter-group-title-open');
				}
			}
		});
	}
}

/* Evento al modificar un filtro */
function toggleFilters(element, startup)
{

	/* Acciones sobre el grupo del check que se ha clickado */
	if (element && element.id)
	{
		var type = element.id.split('_')[0];
		var code = element.id.split('_')[1];

		var inputs = $('filters').select('input.one[id^='+type+'_]');

		/* Al marcar "Todos", desmarcar el resto */
		if (code === 'all' && element.checked)
		{
			inputs.each(function(element)
			{
				element.checked = false;
			});
		}

		/* Marcar "Todos" cuando no esté marcado ningún filtro del grupo */
		$(type+'_all').checked = !inputs.any(function(element, index){return element.checked;});

		/* Generamos las etiquetas de los filtros activos */
		if (element.checked && code !== 'all')
		{
			window.filter_selection.push(element.id);
		}
		else if (element.checked && code === 'all')
		{
			for (var i = 0; i < window.filter_selection.length; i++)
			{
				if (window.filter_selection[i].split('_')[0] === type)
				{
					window.filter_selection.splice(i, 1);
					i--;
				}
			}
		}
		else
		{
			window.filter_selection.spliceValue(element.id);
		}
	}

	/* Empezamos vaciando las etiquetas */
	$('filter-selection').update().hide();

	str_filters = [];

	/* Creamos etiquetas en orden */
	if (window.filter_selection)
	{
		window.filter_selection.each(function(filterId, idx)
		{
			$('filter-selection').show();

			var newFilter = new Element('span', {'class':'filter', 'rel':filterId}).update($(filterId).readAttribute('title'));
			var a = new Element('a', {'class':'remove', href:'#'});
			a.observe('click', function(event){
				event.stop();
				$(filterId).checked = false;
				toggleFilters($(filterId));
			});
			newFilter.insert({top:a});
			$('filter-selection').insert(newFilter);

			if (idx === window.filter_selection.length - 1)
			{
				newFilter.addClassName('last');
			}
		});
	}

	createCookie('filters', window.filter_selection.join(','), document.location.pathname + document.location.search);

	//filtersModuleStateChange(str_filters.join(','));

	applyFilters(startup, startup);
}

/* Cambia la página y actualiza el listado */
function changePage(diff, order)
{
	var max_page = parseInt($('page_offset').select('option').last().value, 10);

	if (diff && parseInt($F('page_offset'), 10) + diff >= 1 && parseInt($F('page_offset'), 10) + diff <= max_page)
	{
		$('page_offset').setValue(parseInt($F('page_offset'), 10) + diff);
	}

	var pagination = [$F('page_offset'), $F('items_per_page')];

	pagination.push($F('ordering'));

	navigate('page', pagination.join('|'));

	return false;
}

/* Aplica los filtros seleccionados */
function applyFilters(reorder, repage)
{
	var hotels = $$('div.results-hotel');

	/* Si solo hay un hotel no se filtra */
	if (hotels.length <= 1)
	{
		return {};
	}

	/* Reordenar los hoteles */
	if (reorder)
	{
		var order = $F('ordering').split('_')[0];
		var direction = $F('ordering').split('_')[1] || 'asc';

		if (order === 'price')
		{
			hotels.sort(function(a, b)
			{
				if (a.data.orderPrice === 0)
				{
					return 1;
				}
				else if (b.data.orderPrice === 0)
				{
					return -1;
				}
				else if (direction === 'asc')
				{
					return (a.data.orderPrice < b.data.orderPrice) ? -1 : 1;
				}
				else if (direction === 'des')
				{
					return (a.data.orderPrice < b.data.orderPrice) ? 1 : -1;
				}
			});
		}
		else if (order === 'name')
		{
			hotels.sort(function(a,b)
			{
				return (
					(direction === 'asc' && a.data.orderName > b.data.orderName) ||
					(direction === 'des' && a.data.orderName < b.data.orderName)
				);
			});
		}

		hotels.each(function(element)
		{
			element.up().insert({bottom:element});
		});
	}

	/* Empezamos con todos los hoteles activos y sin filtros */
	var hotels_part = [hotels, []];
	var active_filters = {zone:[], category:[], facility:[]};
	$('filters').select('input.one').invoke('enable');

	/* Para cada filtro seleccionado, buscamos hoteles activos y deshabilitamos los filtros que no estén disponibles */
	window.filter_selection.each(function(filter)
	{
		var type = filter.split('_')[0];
		var code = filter.split('_')[1];

		active_filters[type].push(code);

		/* Hoteles activos para esta iteración */
		hotels_part = hotels.partition(function(hotel)
		{
			return (
				(!active_filters.zone.length || active_filters.zone.any(function(code){return hotel.data.zone === code || hotel.data.subzone === code;})) &&
				(!active_filters.category.length || active_filters.category.any(function(code){return hotel.data.category === code;})) &&
				(!active_filters.facility.length || active_filters.facility.any(function(code){return hotel.data.facilities.any(function(hf){return hf === code;});}))
			);
		});

		/* Cada filtro deshabilita filtros de otros grupos */
		if (type !== 'zone')
		{
			$('filter_group_zone').select('input.one').invoke('disable');
		}
		if (type !== 'category')
		{
			$('filter_group_category').select('input.one').invoke('disable');
		}
		if (type !== 'facility')
		{
			$('filter_group_facility').select('input.one').invoke('disable');
		}

		/* Habilitamos los filtros disponibles en los hoteles activos */
		hotels_part[0].each(function(hotel)
		{
			if ($('zone_'+hotel.data.zone))
			{
				$('zone_'+hotel.data.zone).enable();
			}

			if ($('zone_'+hotel.data.mainzone))
			{
				$('zone_'+hotel.data.mainzone).enable();
			}

			if ($('category_'+hotel.data.category))
			{
				$('category_'+hotel.data.category).enable();
			}

			hotel.data.facilities.each(function(facility)
			{
				if ($('facility_'+facility))
				{
					$('facility_'+facility).enable();
				}
			});
		});
	});

	/* Finalmente, aplicamos cambios de estilo a los filtros */
	$('filters').select('input').each(function(filter)
	{
		if (filter.disabled)
		{
			filter.up('li').setOpacity(0.3);
		}
		else
		{
			filter.up('li').setOpacity(1);
		}
	});

	/* Valores de paginación */
	var items_per_page = parseInt($F('items_per_page'), 10);
	var pages = Math.max(1, Math.ceil(hotels_part[0].length / items_per_page));
	var page = Math.max(1, Math.min(pages, parseInt($F('page_offset'), 10)));

	/* Aplicamos el valor corregido */
	$('page_offset').setValue(page);

	/* Actualizar el número de resultados */
	if (hotels_part[0].length === 1)
	{
		$('results_total').update(hotels_part[0].length + " " + messages.hotel_available);
	}
	else
	{
		$('results_total').update(hotels_part[0].length + " " + messages.hotels_available);
	}

	/* Actualizar el selector de página */
	if ($('page_offset').options.length > pages)
	{
		$('page_offset').select('option').each(function(option)
		{
			if (option.value > pages)
			{
				option.remove();
			}
		});
	}
	else
	{
		for (var i = $('page_offset').options.length; i < pages; i++)
		{
			$('page_offset').insert(new Element('option', {value:i+1}).update(i+1));
		}
	}

	/* Mostrar u ocultar los botones de cambio de página */
	if (page === 1)
	{
		$('prevPage').addClassName('disabled');
	}
	else
	{
		$('prevPage').removeClassName('disabled');
	}

	if (page === pages)
	{
		$('nextPage').addClassName('disabled');
	}
	else
	{
		$('nextPage').removeClassName('disabled');
	}

	/* Actualizar el listado según la página actual */
	if (reorder)
	{
		$$('div.results-hotel').invoke('hide');
	}
	var delay = 0;
	var duration = repage ? 0 : 0.2;

	/* Mostrar los hoteles que pasan el filtro */
	hotels_part[0].each(function(element, index)
	{
		if ((Math.floor(index / items_per_page) + 1) === page)
		{
			if (!element.visible())
			{
				if (reorder)
				{
					/* Desplegado progresivo */
					element.setStyle({visibility:'hidden'}).show();
					Element.setStyle.delay(delay++ / 8, element, {visibility:'visible'});
				}
				else
				{
					element.blindDown({duration:duration});
				}

				/* Cargar la imagen principal si no estaba cargada */
				var mainPicture = element.down('.main-picture');
				if (mainPicture && mainPicture.readAttribute('src').empty())
				{
					mainPicture.writeAttribute('src', mainPicture.readAttribute('defer_src'));
				}
			}
		}
		else
		{
			if (element.visible())
			{
				element.blindUp({duration:duration});
			}
		}
	});

	/* Ocultar los hoteles que no pasan el filtro */
	hotels_part[1].each(function(element)
	{
		if (element.visible())
		{
			element.blindUp({duration:duration});
		}
	});

	/* Scroll al princpio del listado */
	if (repage && $('main').viewportOffset().top < 0)
	{
		$('main').scrollTo();
	}

	/* Devolvemos la lista de filtros aplicados */
	//return {zones:filters.zone, categories:filters.category, facilities:filters.facility};
}

/* Consulta la disponibilidad según las fechas del formulario */
function searchHotelsAvailability(arrival, departure, form)
{
	form = $(form) || $('detailsSearchForm') || $('searchForm');

	if (arrival && arrival.isDate() && departure && departure.isDate())
	{
		form.arrival.value = arrival;
		form.departure.value = departure;
	}
	else if(!$F(form.arrival).isDate() || !$F(form.departure).isDate())
	{
		form.arrival.value = '';
		form.departure.value = '';
	}

	if (($F(form.arrival).empty() || $F(form.arrival).isDate()) && ($F(form.departure).empty() || $F(form.departure).isDate()))
	{
		/* loader y efectos */
		if ($('search-loader'))
		{
			$('search-loader').show();
			$('search-results').setStyle({top: -$('search-loader').getHeight() + 'px'});
		}
		if ($('search-results'))
		{
			$('search-results').blindUp({duration:0.5, afterUpdate:searchFormScroll});
		}

		/* Reconstruir el action del formulario */
		var requests = [];
		
		/* Esto es para evitar el bug de prototype con los <input name="id"> */
		var input_id = $(form).getInputs().find(function(element){return element.name == 'id';});

		if (input_id)
		{
			requests.push('id='+input_id.value);
		}
		if ($(form).down('input[name=uid]'))
		{
			requests.push('uid='+$(form).down('input[name=uid]').value);
		}
		if (!$F(form.arrival).empty())
		{
			requests.push('arrival='+$F(form.arrival));
		}
		if (!$F(form.departure).empty())
		{
			requests.push('departure='+$F(form.departure));
		}

		$(form).writeAttribute('action', $(form).action.split('?')[0] + (requests.length ? '?'+requests.join('&') : ''));

		$(form).submit();
	}
}

/* Actualiza los precios de un hotel */
function updatePrices(hotelPosition)
{
	if ($F('arrival').isDate() && $F('departure').isDate())
	{
		/* ¿Hay alguna habitación seleccionada? */
		if ($$('#rooms_'+hotelPosition+' select[id^=quantity_]').any(function(element){ return $F(element) > 0;}))
		{
			/* Borrar los precios de las habitaciones que se actualicen */
			$$('#rooms_'+hotelPosition+' select[id^=quantity_]').each(function(element)
			{
				if ($F(element) > 0)
				{
					element.up('ul').down('.price').update('---');
				}
			});
			$$('#hotelForm_'+hotelPosition+' span[id^=total_price_]')[0].update('---');

			if ($('myPriceLoading'))
			{
				$('myPriceLoading').show();
			}

			$(document.body).addClassName('loading');

			var request = new Ajax.Request
			(
				'/ajax-price?id=' + $('hotelForm_'+hotelPosition).id.value,
				{
					asynchronous:true,
					parameters: $('hotelForm_'+hotelPosition).serialize(), // + '&ignore_weekdays=1',
					onComplete: function() {
						Element.removeClassName.delay(0.3, $(document.body), 'loading');
					},
					onSuccess: function(transport) {
						if (transport.responseJSON)
						{
							updatePricesSuccess(transport.responseJSON, hotelPosition);
						}
						else
						{
							alert('Error JSON');
						}
					},
					onFailure: function()
					{
						updatePricesFailure();
					}
				}
			);

			return request.success();
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
}

/* Actualizar los precios del formulario con los datos de Ajax */
function updatePricesSuccess(data, hotelPosition)
{
	/* Actualizar precio de habitaciones */
	data.breakdown.each(function(breakdown)
	{
		$('price_' + breakdown.id).update(breakdown.days[0].final);
	});

	if (data.errorCode.empty())
	{
		/* Actualizar precio total */
		if ($('total_price_'+hotelPosition).innerHTML === '---')
		{
			$('total_price_'+hotelPosition).update(data.price);
		}
		else
		{
			$('total_price_'+hotelPosition).updateEffect(data.price);
		}
	}
	else
	{
		$('total_price_'+hotelPosition).update('---');
	}
}

function changeBoard(hotelPosition, roomId)
{
	if ($('price_'+roomId))
	{
		$('price_'+roomId).update($('board_'+roomId).down('option[value='+$('board_'+roomId).value+']').readAttribute('title'));
	}

	updatePrices(hotelPosition);
}

/* Muestra el calendario de disponibilidad de una habitación no disponible */
function calendarAvailability(roomId, date, offset)
{
	if (roomId && date.isDate())
	{
		$('unavailableRoom_'+roomId).show();
		var calendarContainer = $('unavailableRoom_'+roomId).down('.calendar');

		//calendarContainer.update();
		calendarContainer.addClassName('calendar-loading').show();

		new Ajax.Updater(calendarContainer, '/ajax-availability-calendar',
		{
			parameters :
			{
				roomid : roomId,
				date   : date,
				offset : offset
			},
			onSuccess : function(transport)
			{
				calendarContainer.removeClassName('calendar-loading');
			},
			onComplete : function()
			{
				var month, width;

				if ($$('.month.hide_left')[0])
				{
					month = $$('.month.hide_left')[0];
					month.removeClassName('hide_left');
					width = month.getWidth() + parseInt(month.getStyle('marginLeft'), 10) + parseInt(month.getStyle('marginRight'), 10);
					new Effect.Move(month.up('div.months'), {x:-width, y:0, duration:0.5});
				}
				if ($$('.month.show_right')[0])
				{
					month = $$('.month.show_right')[0];
					month.removeClassName('show_right');
					month.show();
					width = month.getWidth() + parseInt(month.getStyle('marginLeft'), 10) + parseInt(month.getStyle('marginRight'), 10);
					month.up('div.months').setStyle({left:-width+'px'});
					new Effect.Move(month.up('div.months'), {x:width, y:0, duration:0.5});
				}
			}
		});
	}

	return false;
}

/* Valida el formulario y lo envía al siguiente paso */
function nextStep()
{
	var anyRooms = $$('select[id^=quantity_]').any(function(el){return el.value > 0;});
	var totalPrice = parseFloat($('totalPrice').innerHTML);

	if (manyNights() < 1)
	{
		alert(messages.error_nights);
	}
	else if (!anyRooms)
	{
		alert(messages.error_num_rooms);
	}
	else if (!totalPrice)
	{
		return;
	}
	else if (!readCookie('PHPSESSID'))
	{
		alert(messages.error_cookies);
	}
	else
	{
		$('bookingForm').submit();
	}
}

/* Inicializa los inputs de arrival y departure */
function initDatePicker()
{
	var options;

	$$("#arrival, #departure, #details_arrival, #details_departure").each(function(element)
	{
		options =
		{
			/* Antes de abrir el calendario */
			clickCallback: function()
			{
				if (element.name === 'departure' && !$F(element).isDate() && $F(element.form.arrival).isDate())
				{
					setNewDeparture($F(element.form.arrival).toDate().addDays(7).toStrDate(), element);
				}

				Element.observe.defer(document, 'click', function(event)
				{
					if (event.target !== element && (!element.next('img') || event.target !== element.next('img')) && !$(event.target).descendantOf($("datepicker-" + element.id)))
					{
						this.close();
					}
				}.bind(this));
			},

			/* Al seleccionar una fecha en el calendario */
			cellCallback: function(value)
			{
				switch(element.name)
				{
					case 'arrival':
						setNewArrival.defer(value, element);
						break;

					case 'departure':
						setNewDeparture.defer(value, element);
						break;
				}
				document.stopObserving('click');
			},
			relative: element.id,
			arrival: element.form.arrival.id,
			departure: element.form.departure.id,
			language: element.lang,
			keepFieldEmpty: true,
			enableShowEffect: true,
			showEffect: 'blind',
			showDuration: 0.15,
			enableCloseEffect: true,
			closeEffect: 'fade',
			closeEffectDuration: 0.1,
			disableFutureDate: false,
			disablePastDate: true,
			topOffset: -3,
			leftOffset: element.offsetWidth - 50
		}

		element.datepicker = new DatePicker(options);

		element.observe('datepicker:open', function(){element.datepicker.click();});
		element.observe('datepicker:close', function(){element.datepicker.close();});
		if (element.next('img'))
		{
			element.next('img').observe('click', function(){element.datepicker.click();});
		}
	});
}

/* Callback de ajax-availability-calendar */
function calendarSetNewArrival(arrival)
{
	setNewArrival(arrival);
	searchHotelsAvailability();
}

/* Cambia la fecha de llegada y actualiza los datos */
function setNewArrival(arrival, element)
{
	if (!element)
	{
		element = $('arrival');
	}

	if (arrival.isDate())
	{
		var today = new Date().toStrDate().toDate();
		var newArrivalDate = arrival.toDate();
		var newDepartureDate;

		if (!$F(element.form.departure).isDate())
		{
			$(element.form.departure).setValue(newArrivalDate.addDays(7).toStrDate());
		}

		if (arrival.toDate() < today)
		{
			newArrivalDate = today;
			newDepartureDate = newArrivalDate.addDays(Math.max(1, Math.min(max_nights, manyNights())));
		}
		else if ($F(element.form.departure).isDate() && newArrivalDate >= $F(element.form.departure).toDate())
		{
			newDepartureDate = newArrivalDate.addDays(Math.max(1, Math.min(max_nights, manyNights())));
		}
		else if ($F(element.form.departure).isDate() && $F(element.form.departure).toDate() > newArrivalDate.addDays(max_nights))
		{
			newDepartureDate = newArrivalDate.addDays(max_nights);
		}

		$(element).setValue(newArrivalDate.toStrDate());

		if (newDepartureDate)
		{
			if ($F(element.form.departure).isDate())
			{
				(function(){$(element.form.departure).fire('datepicker:open');}).defer();
			}

			setNewDeparture(newDepartureDate.toStrDate(), element.form.departure);
		}

		/* Actualizar el datepicker de arrival si está abierto */
		if (element.datepicker && element.datepicker.visible())
		{
			element.datepicker._initCurrentDate();
			element.datepicker._redrawCalendar();
		}

		/* Actualizar el datepicker de departure si está abierto */
		if (element.form.departure.datepicker && element.form.departure.datepicker.visible())
		{
			element.form.departure.datepicker._initCurrentDate();
			element.form.departure.datepicker._redrawCalendar();
		}
	}
}

/* Cambia la fecha de salida y actualiza los datos */
function setNewDeparture(departure, element)
{
	if (!element)
	{
		element = $('departure');
	}

	if (departure.isDate())
	{
		var today = new Date().toStrDate().toDate();
		var departureDate = departure.toDate();

		/* Si la nueva fecha se pasa más de 31 días, movemos arrival hacia delante */
		if ($F(element.form.arrival).isDate() && $F(element.form.arrival).getDaysBetween(departureDate) > max_nights)
		{
			$(element).value = departureDate.toStrDate();
			setNewArrival(departureDate.addDays(-max_nights).toStrDate(), element.form.arrival);
			$(element.form.arrival).fire('datepicker:open');
		}
		/* Si la nueva fecha es menor que arrival, mover arrival hacia atrás */
		else if (!$F(element.form.arrival).isDate() || departureDate <= $F(element.form.arrival).toDate())
		{
			var newArrivalDate = departureDate.addDays(-Math.max(1, Math.min(max_nights, manyNights())));

			/* arrival no puede ser menor que hoy */
			if (newArrivalDate < today)
			{
				newArrivalDate = today;
				departureDate = today.addDays(1);
			}

			$(element).value = departureDate.toStrDate();
			setNewArrival(newArrivalDate.toStrDate(), element.form.arrival);
			$(element.form.arrival).fire('datepicker:open');
		}
		else
		{
			$(element).value = departureDate.toStrDate();
		}

		/* Actualizar el datepicker de arrival si está abierto */
		if (element.form.arrival.datepicker && element.form.arrival.datepicker.visible())
		{
			element.form.arrival.datepicker._initCurrentDate();
			element.form.arrival.datepicker._redrawCalendar();
		}

		/* Actualizar el datepicker de departure si está abierto */
		if (element.datepicker && element.datepicker.visible())
		{
			element.datepicker._initCurrentDate();
			element.datepicker._redrawCalendar();
		}
	}
}

/* Cuenta el número de noches entre dos fechas */
function manyNights()
{
	if ($F('arrival').isDate() && $F('departure').isDate())
	{
		return $F('arrival').getDaysBetween($F('departure'));
	}
	else
	{
		return false;
	}
}

/* Desplaza el cuadro de resumen para que siga el desplazamiento de la página */
function searchFormScroll()
{
	var box = $('searchForm').up('div');
	var parent = box.up();

	/* Distancia del borde superior del contenedor al borde superior del navegador */
	var offset = Math.min(parent.cumulativeOffset().top - $(document.body).cumulativeScrollOffset().top, 0);

	/* Espacio libre donde podemos desplazar el bloque */
	var max_distance = parent.getHeight() - box.getHeight() - parseInt(box.getStyle('marginTop'), 10) - parseInt(box.getStyle('marginBottom'), 10);

	/* Desplazamiento del bloque */
	var actual_distance = parseInt(box.getStyle('top'), 10);
	var new_distance = Math.min(-offset, max_distance);

	/* Desplazamiento suave, más rápido hacia arriba */
	if (new_distance !== actual_distance)
	{
		var duration = (new_distance > actual_distance) ? 0.2 : 0.1;
		Effect.Queues.get('box').each(function(q){q.cancel();});
		new Effect.Tween(
			null, actual_distance, new_distance,
			{duration:duration, fps:50, queue:{scope:'box'}},
			function(x){box.setStyle({top:x + 'px'});}
		);
	}
}

