document.observe('dom:loaded', function()
{
	if ($('searchForm'))
	{
		$('searchForm').writeAttribute({autocomplete:'off'});

		$('arrival').observe('change', function(){setNewArrival($F('arrival'))});
		$('departure').observe('change', function(){setNewArrival($F('departure'))});

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

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

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

		initDatePicker();

		updateButtons();
	}

	if ($('bookingForm'))
	{
		$('bookingForm').writeAttribute({autocomplete:'off'});
	}
});

/* Consulta la disponibilidad según las fechas del formulario */
function searchAvailability(defer)
{
	if ($F('arrival').isDate() && $F('departure').isDate())
	{
		/* Detener peticiones anteriores */
		if (window.ajax_availability_request)
		{
			window.ajax_availability_request.abort();
			window.ajax_availability_request = null;
		}

		/* Si hay una petición anterior con retardo, anularla */
		if (window.searchAvailabilityDefer)
		{
			clearInterval(window.searchAvailabilityDefer);
			window.searchAvailabilityDefer = null;
		}
		/* Si se indica, descartar esta petición y repetirla con retardo */
		if (defer > 0)
		{
			window.searchAvailabilityDefer = searchAvailability.delay(defer);
			return false;
		}

		if ($('ajax-loader')) $('ajax-loader').show();
		$$('#bookingForm input', '#bookingForm select').invoke('disable');
		$(document.body).addClassName('loading');

		// Elementos que se difuminan durante la búsqueda
		var fadingElements = [$('bookingForm'), $('unavailability').down('table')];

		//IE fix
		if (Prototype.Browser.IE)
		{
			fadingElements = fadingElements.concat($('bookingForm').select('a.img-wrapper'), $('bookingForm').select('div.room-info'));
		}

		fadingElements.invoke('setOpacity', 0.3);

		/* Lanzar la petición */
		window.ajax_availability_request = new Ajax.Request
		(
			'/ajax-availability?id=' + hotel.id_hotel,
			{
				asynchronous:true,
				parameters: $('searchForm').serialize(),
				onComplete: function()
				{
					Element.removeClassName.delay(0.3, $(document.body), 'loading');
					if ($('ajax-loader')) $('ajax-loader').hide();
				},
				onSuccess: function(transport)
				{
					$$('#bookingForm input', '#bookingForm select').invoke('enable');
					if (transport.responseJSON)
					{
						searchAvailabilitySuccess(transport.request.parameters, transport.responseJSON);
						fadingElements.invoke('setOpacity', 1);
					}
					else
					{
						if (window.console) console.log('Invalid JSON');
					}
				},
				onFailure: function()
				{
					searchAvailabilityFailure(transport.request.parameters);
					if (window.console) console.log('AJAX Failure');
				}
			}
		);
	}
}

/* Actualiza la disponibilidad con los datos de Ajax */
function searchAvailabilitySuccess(parameters, data)
{
	var cont = 0;

	$('errores') && $('errores').update();

	$('bookingForm').arrival.setValue(parameters.arrival);
	$('bookingForm').departure.setValue(parameters.departure);

	/* Dividir las habitaciones entre las que tienen disponibilidad y las que no */
	var roomsPart = data.rooms.partition(function(room) {
		return (parseInt(room.availability, 10) > 0 && !room.errors.length);
	});

	/* Procesar habitacines con disponibilidad */
	roomsPart[0].each(function(room, index)
	{
			var availability = parseInt(room.availability, 10);

			$('room_' + room.id).show();

			$('unavailableRoom_' + room.id).hide();

			/* Actualizamos el precio mínimo */
			$('minprice_' + room.id).update(room.price_from);

			/* Actualizamos el classname que indica el tipo de precio */
			$('minprice_' + room.id).classNames().each(function(className)
			{
				if (className.match((/^minprice\-/)))
				{
					$('minprice_' + room.id).removeClassName(className);
				}
			});
			$('minprice_' + room.id).addClassName('minprice-'+room.pricing);

			/* Actualizar el mensaje de aviso */
			if (availability == 1)
			{
				var maxQuantity = 1;

				$('roomNotice_'+room.id).update(messages.last_room).show();
			}
			else if (availability < 5)
			{
				var maxQuantity = availability;
				$('roomNotice_'+room.id).update(messages.last_rooms.replace('%', availability)).show();
			}
			else
			{
				var maxQuantity = 5;
				if ($('roomNotice_'+room.id)) $('roomNotice_'+room.id).hide();
			}

			/* Actualizamos la disponibilidad (max 5 habitaciones) */
			var selectQuantity = $('quantity_' + room.id);

			selectQuantity.enable();

			if (selectQuantity.options.length-1 < maxQuantity)
			{
				// Añadir las que falten
				for (var i = selectQuantity.options.length-1; i < maxQuantity; i++)
				{
					selectQuantity.options.add(new Option(selectQuantity.options.length, selectQuantity.options.length));
				}
			}
			else if (selectQuantity.options.length-1 > maxQuantity)
			{
				// Eliminar las que sobren
				for (var i = selectQuantity.options.length-1; i > maxQuantity; i--)
				{
					$(selectQuantity.options[selectQuantity.options.length - 1]).remove();
				}
			}

			//Cambiar el background según sea fila par o impar (esto cambiará según la disponibilidad)
			if (cont++ % 2 == 1)
			{
				$('room_' + room.id).addClassName("even");
				if ($('roomInfo_' + room.id)) { $('roomInfo_' + room.id).addClassName("even"); }
			}
			else
			{
				$('room_' + room.id).removeClassName("even");
				if ($('roomInfo_' + room.id)) { $('roomInfo_' + room.id).removeClassName("even"); }
			}

			// Actualizar las pensiones de cada habitación
			$$('select[id^=board_' + room.id + ']').each(function(selectBoard)
			{
				var previousValue = selectBoard.value;

				selectBoard.options.length = 0;

				room.boards.compact().each(function(board)
				{
					var option = new Option(board.name, board.id);
					if (board.id == previousValue) option.selected = 'selected';
					selectBoard.options.add(option);
				});
			});

			// Actualizar precio inicial
			if (selectQuantity.value == 0)
			{
				$('price_'+room.id+'_0').down('.price-final').addClassName('grayed-out').update(room.price_init);
			}

			// Si es la primera y única habitación, preseleccionar la cantidad en 1
			if (index == 0 && roomsPart[0].length == 1 && $F('quantity_'+room.id) < 1)
			{
				$('quantity_'+room.id).value = 1;
			}

			// Actualizar las cantidades
			updateQuantity(room.id);

	});

	/* Procesar habitacines sin disponibilidad */
	roomsPart[1].each(function(room)
	{
		$('room_' + room.id).hide();
		if ($('roomInfo_' + room.id))
		{
			$('roomInfo_' + room.id).hide();
		}

		/* Deshabilitar el select de cantidad para que no se envíen las unidades */
		$('quantity_' + room.id).disable();

		/* Procesar el error */
		setAvailabilityErrors(room.id, room.errors);

		/* Actualizar las cantidades */
		updateQuantity(room.id);
	});


	/* Actualizar el flag de si hay extras para estas fechas */
	hotel.extras = roomsPart[0].any(function(room){return room.extras.length > 0});

	/* si hay alguna habitación disponible, mostrar el bloque de disponibilidad y actualizar precios */
	if (roomsPart[0].length)
	{
		$('availability').show();
		$$('.block-next').invoke('appear', {duration:0.3});

		updatePrices();
	}
	else
	{
		$('availability').hide();
		$$('.block-next').invoke('fade', {duration:0.3});
	}

	/* si hay alguna habitación no disponible, mostrar el bloque de no disponibilidad */
	if (roomsPart[1].length)
	{
		$('unavailability').show();
	}
	else
	{
		$('unavailability').hide();
	}
}

/* Actualiza la disponibilidad con los datos de Ajax */
function searchAvailabilityFailure(parameters)
{

}

/*
 Gestión de errores
*/
function setAvailabilityErrors(roomId, errors)
{
	var str_errors = [];

	errors.each(function(error)
	{
		switch(parseInt(error.code))
		{
			/* Hotel cerrado en estas fechas: mostramos las fechas de apertura y cierre o reapertura */
			case 3:
				var hotel_dates = error.targetvalue;

				var link_opening = '<a href="#" onclick="return setNewArrival(\'' + hotel_dates[0] + '\');">' + hotel_dates[0] + '</a>';
				var link_closing = '<a href="#" onclick="return setNewDeparture(\'' + hotel_dates[1] + '\');">' + hotel_dates[1] + '</a>';

				if (hotel_dates[1] != undefined)
				{
					str_errors.push(messages.error_closing.replace('%', link_opening).replace('%', link_closing));
				}
				else
				{
					str_errors.push(messages.error_opening.replace('%', link_opening));
				}
			break;
			/* Error de release: mostramos el error con el release para la fecha de entrada */
			case 10:
				str_errors.push('<a href="#" onclick="return setNewArrival(\'' + (new Date().addDays(error.targetvalue[0]).toStrDate()) + '\')">' + (error.targetvalue[0] == 1 ? messages.error_release_1 : messages.error_release_n.replace('%', error.targetvalue[0])) + '</a>');
			break;
			/* Error de estancia mínima: mostramos el error con la estancia mínima para la fecha de entrada */
			case 11:
				str_errors.push('<a href="#" onclick="return changeNights(' + error.targetvalue[0] + ')">' + (error.targetvalue[0] == 1 ? messages.error_minimum_stay_1 : messages.error_minimum_stay_n.replace('%', error.targetvalue[0])) + '</a>');
			break;
			/* Error de día de entrada: mostramos los días admitidos */
			case 14:
				var days = '';
				error.targetvalue.each(function(day, index){
					days += '<a href="#" onclick="return setNewArrival($F(\'arrival\').toDate().addDays(' + day + ' - $F(\'arrival\').toDate().getDay()).toStrDate())">' + weekdays[day] + '</a>';
					if (index < error.targetvalue.length - 2) days += ', ';
					else if (index == error.targetvalue.length - 2) days += ' ' + messages.or + ' ';
				});
				str_errors.push(messages.error_arrival_day.replace('%', days) + ' ' + messages.set_to_nearest_date);
			break;
			/* Error de día de salida: mostramos los días admitidos */
			case 15:
				var days = '';
				error.targetvalue.each(function(day, index){
					days += '<a href="#" onclick="return setNewDeparture($F(\'departure\').toDate().addDays(' + day + ' - $F(\'departure\').toDate().getDay()).toStrDate())">' + weekdays[day] + '</a>';
					if (index < error.targetvalue.length - 2) days += ', ';
					else if (index == error.targetvalue.length - 2) days += ' ' + messages.or + ' ';
				});
				str_errors.push(messages.error_departure_day.replace('%', days) + ' ' + messages.set_to_nearest_date);
			break;
			default:
			/* No hay disponibilidad (12), precio erróneo (19) u otros: mostramos calendario para esta habitación */
				str_errors.push(messages.error_unavailable + '<br/><a href="#calendarAvailability" onclick="return calendarAvailability('+roomId+', \'' + $F('arrival') + '\')">' + messages.error_click_calendar + '</a>');
			break;
		}
	});

	$('unavailableRoom_'+roomId).show();
	$('unavailableRoomError_'+roomId).update('<p>' + str_errors.join('</p><p>') + '</p>');
	$('unavailableRoomCalendar_'+roomId).update();

}

/* Evento al cambiar el select de cantidad */
function changeQuantity(object)
{
	var roomId = object.id.split('_')[1];
	var quantity = object.value;
	//var visibles = $('room_'+roomId).select('select[id^=adults_]').findAll(function(el){return !el.disabled}).size();

	updateQuantity(roomId);

	updatePrices(roomId);
}

/* Mostrar u ocultar unidades de habitaciones según la cantidad seleccionada */
function updateQuantity(roomId)
{
	var maxrooms = 5;
	var quantity = $('quantity_' + roomId).disabled ? 0 : $F('quantity_' + roomId);
	var visibles = $$('select[id^=adults_'+roomId+'_]').findAll(function(el){return !el.disabled}).size();

	for (var i = 0; i < maxrooms; i++)
	{
		/* Habilitar y mostrar las que falten */
		if (i < quantity)
		{
			$('roomId_'+roomId+'_'+i,
			  'adults_'+roomId+'_'+i,
			  'children_'+roomId+'_'+i,
			  'babies_'+roomId+'_'+i,
			  'board_'+roomId+'_'+i
			).invoke('enable').invoke('appear', {duration:0.2});

			if (!$('price_'+roomId+'_'+i).visible())
			{
				$('price_'+roomId+'_'+i).appear({duration:0.2});
				$('price_'+roomId+'_'+i).down('.price-before').hide();
				$('price_'+roomId+'_'+i).down('.price-final').update('&nbsp;');
				$('price_'+roomId+'_'+i).select('input[type=radio]').invoke('enable');
			}

			updateChildren(roomId, i);
		}
		/* Deshabilitar y ocultar las que sobren */
		else
		{
			$('roomId_'+roomId+'_'+i).disable();

			$('adults_'+roomId+'_'+i,
			  'children_'+roomId+'_'+i,
			  'babies_'+roomId+'_'+i,
			  'board_'+roomId+'_'+i
			).invoke('disable');

			/* Si es la primera, solo cambia el precio */
			if (i == 0)
			{
				$('price_'+roomId+'_'+i).down('a').addClassName('inactive');
				$('price_'+roomId+'_'+i).down('.price-before').hide();
				$('price_'+roomId+'_'+i).down('.price-final').removeClassName('price-options').addClassName('grayed-out');
			}
			/* Si no, ocultamos toda la línea */
			else
			{
				$(
					'adults_'+roomId+'_'+i,
					'children_'+roomId+'_'+i,
					'babies_'+roomId+'_'+i,
					'board_'+roomId+'_'+i,
					'price_'+roomId+'_'+i
				).invoke('fade', {duration:0.2});
			}

			var ratesList = $('price_'+roomId+'_'+i).down('.bubble-options ul');
			if (ratesList)
			{
				ratesList.select('li').each(function(el,idx){if (idx > 0) el.remove()});
			}
		}
	}

	return visibles == 0 && quantity > visibles;
}

/* Evento al cambiar el select de adultos */
function changeAdults(object)
{
	var roomId = object.id.split('_')[1];
	var position = object.id.split('_')[2];

	updateChildren(roomId, position);
	updatePrices(roomId, position);
}

/* Evento al cambiar el select de niños */
function changeChildren(object)
{
	var roomId = object.id.split('_')[1];
	var position = object.id.split('_')[2];

	/* Mostrar edades de los niños (TO-DO) */
	/*
	if (object.value > 0)
	{
		$('ages_' + roomId + '_' + position).show();
	}
	else
	{
		$('ages_' + roomId + '_' + position).hide();
	}
	*/

	updateBabies(roomId, position);
	updatePrices(roomId, position);
}

/* Evento al cambiar el select de bebés */
function changeBabies(object)
{
	var roomId = object.id.split('_')[1];
	var position = object.id.split('_')[2];

	updatePrices(roomId, position);
}

/* Evento al cambiar el select de régimen */
function changeBoard(object)
{
	var roomId = object.id.split('_')[1];
	var position = object.id.split('_')[2];

	updatePrices(roomId, position);
}

/* Actualizar el select de niños según el valor de adultos */
function updateChildren(roomId, position)
{
	var adults = $F('adults_'+roomId+'_'+position);
	var childrenCombo = $('children_'+roomId+'_'+position);

	var previousChildren = childrenCombo.value;
	childrenCombo.length = 0;

	if ($H(combinations[roomId][adults]).any(function(el){return el.key > 0}))
	{
		for (num in combinations[roomId][adults])
		{
			if (num.isNumeric())
			{
				childrenCombo.insert(new Element('option', {value:num}).update(num));
			}
		}
		childrenCombo.enable();

		/* Asignar el valor anterior, solo si existe */
		if (childrenCombo.select('option').any(function(op){return parseInt(op.value) == previousChildren}))
		{
			childrenCombo.value = previousChildren;
		}
	}
	else
	{
		childrenCombo.insert(new Option(0, 0));
		childrenCombo.disable();
	}

	updateBabies(roomId, position);
}

/* Actualizar el select de bebés según el valor de niños */
function updateBabies(roomId, position)
{
	var adults = $F('adults_'+roomId+'_'+position);
	var children = $F('children_'+roomId+'_'+position);
	var babiesCombo = $('babies_'+roomId+'_'+position);

	var previousBabies = babiesCombo.value;
	babiesCombo.length = 0;

	if (combinations[roomId][adults] && $H(combinations[roomId][adults][children]).any(function(el){return el.key > 0}))
	{
		combinations[roomId][adults][children].each(function(num)
		{
			babiesCombo.insert(new Element('option', {value:num}).update(num));
		});
		babiesCombo.enable();

		/* Asignar el valor anterior, solo si existe */
		if (babiesCombo.select('option').any(function(op){return op.value == previousBabies}))
		{
			babiesCombo.value = previousBabies;
		}
	}
	else
	{
		babiesCombo.insert(new Option(0, 0));
		babiesCombo.disable();
	}
}

/* Actualiza los precios según los valores del formulario */
/* Los parámetros roomId y position sirven para marcar el precio que se modifica, aunque se actualizarán los precios de todas las habitaciones */
function updatePrices(roomId, position)
{
	if ($F('arrival').isDate() && $F('departure').isDate())
	{
		/* ¿Hay alguna habitación seleccionada? */
		if ($$('select[id^=quantity_]').any(function(element){ return parseInt(element.value, 10) > 0}))
		{
			if ($('myPriceLoading')) $('myPriceLoading').show();

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

			if ($('totalPrice')) $('totalPrice').update('...');
			if ($('totalPricePro')) $('totalPricePro').update('...');
			document.totalprice = null;

			var updatedRoomId;
			var updatedPosition;

			if (roomId != undefined)
			{
				if (position == undefined || position == null)
				{
					$$('#room_'+roomId+' .price-final').each(function(element)
					{
						if (!parseInt(element.innerHTML))
						{
							element.addClassName('price-loading');
						}
					});

					updatedRoomId = roomId;
					updatedPosition = 0;
				}
				else
				{
					$('price_'+roomId+'_'+position).down('.price-before').hide();
					$('price_'+roomId+'_'+position).down('.price-final').addClassName('price-loading').update('&nbsp;');

					updatedRoomId = roomId;
					updatedPosition = position;
				}
			}

			var request = new Ajax.Request
			(
				'/ajax-price?id=' + hotel.id_hotel,
				{
					asynchronous:true,
					parameters: $('bookingForm').serialize(),
					onComplete: function() {
						Element.removeClassName.delay(0.3, $(document.body), 'loading');
					},
					onSuccess: function(transport) {
						if (transport.responseJSON)
						{
							updatePricesSuccess(transport.responseJSON, updatedRoomId, updatedPosition);
							$$('#room_'+roomId+' .price-final').invoke('removeClassName', 'price-loading');
							updateButtons();
						}
						else
						{
							if (window.console) console.log('Error JSON');
						}
					},
					onFailure: function()
					{
						updatePricesFailure();
						updateButtons();
					}
				}
			);

			return request.success();
		}
		else
		{
			$('totalPrice').update('--');
			if ($('totalPricePro')) $('totalPricePro').update('--');
			document.totalprice = null;
			updateButtons();

			return false;
		}
	}
	else
	{
		return false;
	}
}

/* Actualizar los precios del formulario con los datos de Ajax */
function updatePricesSuccess(data, updatedRoomId, updatedPosition)
{
	if($('myPriceLoading')) $('myPriceLoading').hide();

	if (data.errorCode.empty())
	{
		// Actualizar precio total, con efecto si ya tenía un precio
		if ($('totalPrice').innerHTML == '--')
		{
			$('totalPrice').update(data.price);
		}
		else
		{
			$('totalPrice').updateEffect(data.price);
		}
		document.totalprice = data.price;

		// Actualizar precio profesional
		if ($('totalPricePro')) $('totalPricePro').update(data.price_pro);

		// Mostramos precio final y total (si hay ofertas) por habitación
		var previousId = 0;
		var position = 0;
		data.breakdown.compact().each(function(br, brIdx)
		{
			if (br.id != previousId)
			{
				position = 0;
				previousId = br.id;
			}

			var roomPrice = $('price_'+br.id+'_'+position);

			if (br.id == updatedRoomId && position == updatedPosition)
			{

				roomPrice.down('.price-final').removeClassName('grayed-out').updateEffect(br.price.final);

				if (br.price.ischeaper)
				{
					roomPrice.down('.price-before').show().updateEffect(br.price.original);
				}
				else
				{
					roomPrice.down('.price-before').hide();
				}
			}
			else
			{
				roomPrice.down('.price-final').removeClassName('grayed-out').show().update(br.price.final);

				if (br.price.ischeaper)
				{
					roomPrice.down('.price-before').show().update(br.price.original);
				}
				else
				{
					roomPrice.down('.price-before').hide();
				}
			}

			/* Actualizar tarifas opcionales */
			var ratesList = roomPrice.down('.bubble-options ul');
			var newRates = ratesList.select('li').size() < 2;
			ratesList.select('li').each(function(el,idx){if (idx > 0) el.remove()});
			var anchor = roomPrice.down('a');

			if (br.rates.size())
			{
				br.rates.each(function(rate)
				{
					var newElement = ratesList.down('li').clone(true);
					ratesList.insert(newElement.show());
					newElement.down('input').value = rate.id;
					newElement.down('input').checked = (br.rate == rate.id);
					newElement.down('.name').update(rate.name);
					newElement.down('.price').update(rate.price);
					newElement.down('.description').update(rate.description);
				});

				if (position == 0 && newRates)
				{
					anchor.onclick();
				}

				anchor.removeClassName('inactive');
				anchor.down('span').addClassName('price-options');
			}
			else
			{
				anchor.down('span').removeClassName('price-options');
				anchor.addClassName('inactive');
			}

			position++;
		});
	}
	else
	{
		/* Error en la reserva, el formulario ya no es válido, recargar */
		switch (parseInt(data.errorCode))
		{
			/* Error de ocupación, recargar la página */
			case 5:
			case 6:
			case 7:
			case 8:
			case 16:
				$('bookingForm').writeAttribute({'action':''}).submit();
				break;

			/* Error de disponibilidad, volver a buscar */
			/*
			case 3:
			case 10:
			case 11:
			case 12:
			case 14:
			case 15:
				searchAvailability();
				break;
			*/
		}
	}
}

/* TO-DO */
function updatePricesFailure()
{
	$('totalPrice').update('error');
	document.totalprice = null;
}

/* Carga el calendario de disponibilidad de una habitación */
function calendarAvailability(roomId, date, offset, anchor)
{
	var calendarContent = $('unavailableRoomCalendar_'+roomId);

	// comprobamos datos, y que no haya otro ajax en marcha
	if (!calendarContent.hasClassName('calendar-loading') && roomId && date.isDate())
	{
		calendarContent.addClassName('calendar-loading');

		// deshabilitamos los enlaces de navegación
		// calendarContent.select('.months-navigation a').invoke('addClassName', 'disabled');

		/*
		if (calendarContent.down('.months'))
		{
			new Effect.Opacity(calendarContent.down('.months'), {from:calendarContent.down('.months').getOpacity(), to:0.4, duration:0.2});
		}
		*/

		var ajaxResponse, effectDone;

		// Si el efecto termina antes, se ejecuta esta
		function effectFinish()
		{
			if (ajaxResponse)
			{
				calendarContent.update(ajaxResponse);
				calendarContent.removeClassName('calendar-loading');
			}
			effectDone = true;
		}

		// Si el ajax termina antes, se ejecuta esta
		function processResponse(response)
		{
			if (effectDone || !offset)
			{
				calendarContent.update(response);
				calendarContent.removeClassName('calendar-loading');
			}
			else
			{
				ajaxResponse = response;
			}
		}

		if (offset == +1)
		{
			calendarContent.select('.month').invoke('show');
			var month = calendarContent.down('.month_-2');
			var width = month.getWidth() + parseInt(month.getStyle('marginLeft')) + parseInt(month.getStyle('marginRight'));
			new Effect.Morph(month.up('div.months'), {
				style:{marginLeft:-width+'px'},
				duration:0.5,
				afterFinish:effectFinish
			});
		}
		else if (offset == -1)
		{
			calendarContent.select('.month').invoke('show');
			var month = calendarContent.down('.month_2');
			var width = month.getWidth() + parseInt(month.getStyle('marginLeft')) + parseInt(month.getStyle('marginRight'));
			new Effect.Morph(calendarContent.down('div.months'), {
				style:{marginLeft:+width+'px'},
				duration:0.5,
				afterFinish:effectFinish
			});
		}

		var parameters = {};
		if (window.hotel) parameters.id = window.hotel.id_hotel;
		parameters.date = date;
		parameters.offset = offset;
		parameters.roomid = roomId;

		new Ajax.Request('/ajax-availability-calendar',
		{
			parameters: parameters,
			method: 'get',
			onComplete: function(transport)
			{
				processResponse(transport.responseText);
			}
		});
	}

	return false;

}

/* Despliega el cuadro de información de una habitación */
function showRoomInfo(roomId)
{
	if ($('roomInfo_' + roomId))
	{
		new Effect.toggle($('roomInfo_' + roomId), 'blind', {
			duration:0.5,
			fps:10
		});
	}

	return false;
}

/* Carga una imagen en la foto principal */
function loadPicture(href, element, position)
{
	/* imagen principal */
	var picture = $(element);

	/* Imagen auxiliar para el efecto */
	var loader = new Element('img');

	/* Posición en la galería, para popupPicture() */
	picture.position = position;

	/* Cargar la imagen principal con efecto */
	loader.onload = function() {
		picture.setOpacity(0);
		Element.writeAttribute(picture, {src:loader.src});
		picture.appear({duration:0.4})
	};
	loader.src = href;
}

/* Carga las imágenes de una habitación en una galería de shadowbox */
function popupPicture(img)
{
	var roomId = img.match(/_(\d+)$/)[1];
	var position = $(img).position || 0;

	/* Preparar la galería de shadowbox para esta habitación */
	var gallery_items = $('gallery_' + roomId).select('a');
	Shadowbox.setup(gallery_items, {
		gallery:'room_'+roomId,
		continuous:true
	});

	/* Abrir la galería en la posición de la imagen actual */
	Shadowbox.open(gallery_items[position]);
}

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

	if (!manyNights())
	{
		alert(messages.error_nights);
	}
	else if (!anyRooms)
	{
		alert(messages.error_num_rooms);
	}
	else if (!document.totalprice)
	{
		if (window.console) console.log('No hay precio');
		return;
	}
	else if (!readCookie('PHPSESSID'))
	{
		alert(messages.error_cookies);
	}
	else
	{
		/*	Si no hay extras para estas fechas y no hay que pedir edades de los niños, el destino del formulario cambia */
		var action = (hotel.extras || (hotel.age_request && $$('select[id ^= children_]').any(function(element){return element.value > 0}))) ? 'step-2' : 'step-3';
		$('bookingForm').writeAttribute({action: $('bookingForm').readAttribute('action').replace(/step-\d/, action)});

		/* Continuar */
		$('bookingForm').submit();
	}
}

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

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

				document.observe('click', function(event)
				{
					/* Cerrar siempre que el click no sea en un datepicker o en el form de búsqueda */
					if (!$(event.target).up('.datepicker') && !$(event.target).descendantOf($('searchForm').down('div')))
					{
						this.close();
					}
				}.bind(this));
			},

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

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

		element.datepicker = new DatePicker(options);
	});
}

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

/* Cambia la fecha de llegada y actualiza los datos */
function setNewArrival(arrival, defer)
{
	if (arrival.isDate())
	{
		/* Si arrival es mayor que departure, ajustar departure */
		if (arrival.toDate().getTime() >= $F('departure').toDate().getTime())
		{
			$('departure').setValue(arrival.toDate().addDays(Math.min(hotel.max_nights, Math.max(1, manyNights()))).toStrDate());
			setNewDeparture($F('departure'), 0.1);
		}

		if ($F('arrival') != arrival)
		{
			$('arrival').setValue(arrival);
		}

		if (manyNights() > hotel.max_nights)
		{
			var newDeparture = arrival.toDate().addDays(hotel.max_nights).toStrDate();
			if ($F('departure') != newDeparture)
			{
				$('departure').setValue(newDeparture);
				setNewDeparture($F('departure'), 0.1);
			}
		}

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

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

	updateButtons();

	$('nights').value = manyNights() || '--';

	if (manyNights())
	{
		searchAvailability(defer);
	}

	return false;
}

/* Cambia la fecha de salida y actualiza los datos */
function setNewDeparture(departure, defer)
{
	if (departure.isDate())
	{
		var today = new Date().toStrDate().toDate();

		/* Si departure es menor que arrival, ajustar arrival */
		if ($F('arrival').isDate() && departure.toDate() <= $F('arrival').toDate())
		{
			var newArrivalDate = departure.toDate().addDays(-Math.min(hotel.max_nights, Math.max(1, manyNights())));

			/* no puede ser menor que hoy */
			if (newArrivalDate < today)
			{
				newArrivalDate = today;
				departure = newArrivalDate.addDays(Math.min(hotel.max_nights, Math.max(1, manyNights()))).toStrDate();
			}

			if ($F('arrival') != newArrivalDate.toStrDate())
			{
				$('arrival').setValue(newArrivalDate.toStrDate());
				setNewArrival($F('arrival'), 0.1);
			}
		}

		if ($F('departure') != departure)
		{
			$('departure').setValue(departure);
		}

		if (manyNights() > hotel.max_nights)
		{
			var newArrival = $F('departure').toDate().addDays(-hotel.max_nights).toStrDate();
			if ($F('arrival') != newArrival)
			{
				$('arrival').setValue(newArrival);
				setNewArrival(newArrival, 0.1);
			}
		}

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

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

	}

	updateButtons();

	$('nights').value = manyNights() || '--';

	if (manyNights())
	{
		searchAvailability(defer);
	}

	return false;
}

/* Cambia el número de noches y actualiza los datos */
function changeNights(value)
{
	$('nights').setValue(Math.max(1, Math.min(hotel.max_nights, value)));

	if ($F('arrival').isDate())
	{
		setNewDeparture($F('arrival').toDate().addDays($F('nights')).toStrDate(), 0.7);
	}

	return false;
}

/* Activar o desactivar los botones según las fechas y las habitaciones seleccionadas */
function updateButtons()
{
	/* Botón buscar */
	if ($('button-search'))
	{
		if (manyNights())
		{
			$('button-search').addClassName('button-1-active');
		}
		else
		{
			$('button-search').removeClassName('button-1-active');
		}
	}

	/* Botones continuar */
	if (manyNights() && $$('select[id^=quantity]').any(function(element){return element.value > 0}))
	{
		$$('a[rel=nextStep]').invoke('addClassName','button-1-active');
	}
	else
	{
		$$('a[rel=nextStep]').invoke('removeClassName','button-1-active');
	}
}

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

