/*
 * Funciones javascript para el modulo de reservas
 *
 * Ids utilizados en javascript (hay otros ids para css):
    #formReserva-disponibilidad,
    #formReserva
    #numNoches
    #formReserva.reservar-2
    #stHab
    #stSupl
    #precioMedio
    #ddTotal
    #tipoPago
    #pago_xxxx
 *
 */

/////////// Para sincronizar con calendario-dinamico.js
// Cambiar la selección del calendario de disponibilidad si son fechas diferentes a las introducidas
function actualizarCalendarioDisp(inputFecha) {
	// Necesario para otros datepicker que haya en la web donde se utiliza el módulo
	if (typeof actualizacionCalendario != 'undefined') {
		var closestDiv = $(inputFecha).closest('div');
		if (closestDiv) {
			var idClosestDiv = closestDiv.attr('id');
			if (typeof actualizacionCalendario != 'undefined' && typeof actualizacionCalendario[idClosestDiv] != 'undefined') {
				actualizacionCalendario[idClosestDiv]();
				return;
			}
		}
	}
	if ($("input[name=fechaEntrada]").val() != '' && $("input[name=fechaSalida]").val() != '') {
		$("#comprobarDisponibilidad").removeAttr("disabled");
		$("#comprobarDisponibilidad").css("opacity", "1");
	} else {
		$("#comprobarDisponibilidad").attr("disabled", "disabled");
		$("#comprobarDisponibilidad").css("opacity", "0.3");
	}
	if ($('div.calendariosDinamicos').length == 0) {
        return;
	}
    var seleccionados = $('div.calendariosDinamicos td.seleccionado');
    var idx = 0;
    if (inputFecha.attr('name') == 'fechaEntrada') {
        idx = 0;
    } else if (inputFecha.attr('name') == 'fechaSalida') {
        idx = 1;
    }
    if (seleccionados && seleccionados.length > 0) { // Hay alguna fecha seleccionada
        if (seleccionados.length  == 1) { // Solo hay una fecha seleccionada
			// Si la que ha cambiado es la fecha entrada o la fecha seleccionada es la de salida, deseleccionar antigua
            if (idx == 0 || (idx == 1 && $("input[name=fechaEntrada]").val() == '')) {
                seleccionados.eq(0).removeClass('seleccionado');
            }
        } else { // hay dos fechas seleccionadas: cambiar la que corresponda
            seleccionados.eq(idx).removeClass('seleccionado');
        }
    }
    if (!inputFecha.val() || inputFecha.val() == '') {
		$('div.calendariosDinamicos td:parent').removeClass('enSeleccion');
        return;
    }
    // Marcar como seleccionada en calendario dinamico la fecha que coincida
    seleccionarFecha(inputFecha.val());

	comprobarFechasHotelCerrado();
}

// Hacer visible #mensajeHotelCerrado si alguna de las fechas seleccionadas incluye un día de cierre
function comprobarFechasHotelCerrado() {
	if ($('td.seleccionado,td.enSeleccion').filter('.cerrado').length > 0) {
		$('#mensajeHotelCerrado').show();
	} else {
		$('#mensajeHotelCerrado').hide();
	}
}

function seleccionarFecha(fecha) {
    if (fecha == '') {
        return;
    }
    fecha = revisarFechaES(fecha);
    var $celdas = $('div.calendariosDinamicos td:parent');
    $celdas.filter('[title=' + fecha + ']').eq(0).addClass('seleccionado');
    // Seleccionar las fechas intermedias
	var $selecc = $celdas.filter('.seleccionado');
    var limites = new Array();
	limites[0] = $celdas.index($selecc.get(0));
	limites[1] = $celdas.index($selecc.get(1));
	$selecc = $celdas.filter( [':lt(', limites[1], '):gt(', limites[0], ')'].join('') );
	$celdas.removeClass('enSeleccion jsError');
	$selecc.filter('[title]').addClass('enSeleccion').filter('.sinCupo').addClass('jsError');
    actualizarResumenReserva();
}
function revisarFechaES(fecha) {
    if (lang == 'en') {
        var comps = fecha.split('/');
        fecha = comps[1] + '/' + comps[0] + '/' + comps[2];
    }
    return fecha;
}

function actualizarResumenReserva() {
    var resumenFechasReserva = $('#resumenFechasReserva');
    if (resumenFechasReserva) {
        var $fecEntrada = $('#fechaEntrada');
        var $fecSalida = $('#fechaSalida');
        if ($fecEntrada.val() != '' && $fecSalida.val() != '') {
            var noches = numeroNoches($fecEntrada.val(), $fecSalida.val());
            resumenFechasReserva.html($fecEntrada.val() + ' - ' + $fecSalida.val() + ' <br />' +
            noches + ' ' + txtNoche + ( noches > 1 ? 's' : ''));
        } else {
            resumenFechasReserva.html('');
        }
    }
}
function numeroNoches(fecha1, fecha2) {
    var date1 = fecha1.toDate(),
		date2 = fecha2.toDate(),
		MILLIS_DIA = 86400000;
    return Math.round(Math.abs(date1.getTime() - date2.getTime())/MILLIS_DIA);
}
///////////////////
jQuery.fn.extend({
    print: function() {
		if ($('#lda-print').length) return false;
        var cache = jQuery('body>*').addClass('lda-noprint');
        this.clone().appendTo('body').wrapAll('<div id="lda-print"></div>');
		window.print();
		setTimeout(function() {
			cache.removeClass('lda-noprint');
			jQuery('#lda-print').remove();
		}, 2000);
		return this;
    }
});

function prepararEventosReserva(ctx) {
	var contexto = ctx || document;
	$('#javascriptDesactivado').val('0');
    ocultarSuplementos(contexto);
    extenderEnlacesImprimir(contexto);
    extenderClasesReserva(contexto);
	extenderFormulariosReserva(contexto);
    controlesReserva();
	inicPanels(contexto);
	comprobarFechasHotelCerrado();
}

function extenderEnlacesImprimir(contexto) {
	var $a = $('a', contexto)
	// imprimir divs
    $a.filter('.imprimirDiv').click(function() {
        var ids = '#' + $.trim(this.rel).split(' ').join(', #');
        $(ids).print();
        return false;
    });
}

$(function() {
	prepararEventosReserva(document);
});

function ocultarSuplementos(contexto) {
// Ocultar los elementos con clases panelOcultar o psPanelOcultar (para que aparezcan visibles si JavaScript está desactivado)
    $('.panelOcultar').addClass('panel').removeClass('panelOcultar');
    $('.psPanelOcultar').addClass('psPanel').removeClass('psPanelOcultar');
}

/*
 * ---------------------------------- paneles genericos comunes a todo el site
 * estilos asociados en css/comun.css (clases panel, shown, active y showPanel)
 */
var estadoPaneles;
try {estadoPaneles = eval(getCookie('estadoPaneles'))} catch(e) {};
estadoPaneles = estadoPaneles || {};

function inicPanels(scp) {
	var scope = scp || document,
		$a = $('a.showPanel', scope),
		$p = $('.panel', scope);

	$p.each(function(index) {
		var sAccion = estadoPaneles[this.id]===0 ? 'removeClass' : 'addClass',
			$thisA = $a.eq(index),
			$thisP = $p.eq(index),
			clasesOK = $thisA.filter('.active').length == $thisP.filter('.shown').length;

		// si tiene identificador actuamos segun lo almacenado en estadoPaneles o
		// si tiene las clases desemparejadas las quitamos (sAccion es 'removeClass')
		if (this.id || !clasesOK ) {
			$thisA[sAccion]('active');
			$thisP[sAccion]('shown');
		}
		// chivato para desarrollo en caso de error
		if (!clasesOK) {
			try {
				console.log('Error de emparejamiento de clases entre:');
				console.log($thisA.get(0));
				console.log($thisP.get(0));
			} catch(e) {}
		}
	});
}
// evento de click
$('a.showPanel').live('click', function() {
	var $a = $('a.showPanel'),
		$p = $('.panel'),
		index = $a.index(this);
	$a.eq(index).toggleClass('active');
	$p.eq(index).css('height','').slideToggle(400, function() {
		var $t = $(this);
		$t.toggleClass('shown').css({display:'', height:($.browser.msie && $t.css('position')=='static') ? '1%':''}); // height:1% para corregir bug IE
		if (this.id) {
			estadoPaneles[this.id] = $t.hasClass('shown') ? 1 : 0;
		}
	});
	return false;
});
// almacenar cookie
$(window).unload(function() {
	var aTemp = [];
	for (i in estadoPaneles) {
		aTemp.push('"'+i+'":'+estadoPaneles[i]);
	}
	setCookie('estadoPaneles', '({' +aTemp.join(',')+ '})', 7);
});
/*
 * --------------------------------------------------------- FIN: paneles genericos
 */

// Funciones de eventos y extensiones del DOM
function extenderClasesReserva(contexto) {
	// tablas y listados
	var $e = $('tr', contexto).children().add($('li', contexto));
	$e.filter(':odd').addClass('odd');
	$e.filter(':even').addClass('even');
	$e.filter(':first-child').addClass('first');
	$e.filter(':last-child').addClass('last');
	// inputs
	$('input', contexto).each(function() {
		$(this).addClass(this.type);
	});
	// eventos hover para MSIE6
	if ($.browser.msie && $.browser.version < 7) {
		$('tr, li', contexto).hover( function() {$(this).addClass('hover')}, function() {$(this).removeClass('hover')});
	}
}


// ---------------------- pasar a dos decimales y cambiar de puntos a comas en un numero
Number.prototype.aPrecio = function() {
	var aNum = (this.toFixed(2)+'').split('.'),
		entero = aNum[0],
		i, l;
	// txtSeparadorMiles y txtSeparadorDecimales vienen de lang/.../txtReserva.js
	aNum[0] = '';
	aNum[1] = ['<small>', aNum[1], '</small>'].join('');
	for (i=0,l=entero.length;i<l;i++) {
		if (i && i%3===0) aNum[0]= txtSeparadorMiles + aNum[0];
		aNum[0] = entero.charAt(l-i-1) + aNum[0];
	}
	return aNum.join(txtSeparadorDecimales);
}

// -------------------------------------------------------------- Comprobar email valido
String.prototype.testEmail = function() {
	var reEmail = /^(?:\w+(-\w+)*\.?)*\w+@(?:\w+(-\w+)*\.)+\w+$/;
	return reEmail.test(this);
}

// -------------------------------------------------------- Comprobar documentos validos
String.prototype.testDNI = function() {
	var _t = this.toUpperCase(),
		reDNI = /\d{8}[A-Z]/,
		sCode = 'TRWAGMYFPDXBNJZSQVHLCKET';
	if (reDNI.test(_t) && sCode.charAt(parseInt(_t,10)%23) == _t.replace(/\d/g, '')) {
		return true;
	} else {
		return false;
	}

}
String.prototype.testNIE = function() {
	var _t = this.toUpperCase(),
		reNIE = /([A-Z])(\d{7}[A-Z])/,
		deltaChar = _t.charCodeAt(0) - 'X'.charCodeAt(0);
	return (_t.replace(reNIE, deltaChar + '$2')).testDNI();
}

// -------------------------------------------------------- Comprobar tarjetas de credito
String.prototype.testLuhn = function(){
	var number = this.replace(/\D/g, '');
	var number_length = number.length;
	var parity = number_length % 2;
	var total = 0;

	for (i = 0; i < number_length; i++) {
		var digit = number.charAt(i);
		if (i % 2 == parity) {
			digit = digit * 2;
			if (digit > 9) {
				digit = digit - 9;
			}
		}
		total = total + parseInt(digit);
	}
	if (total % 10 == 0) {
		return true;
	} else {
		return false;
	}
}
String.prototype.testVisa = function() {
	var cardNumber = this.replace(/(\d)([\s\-])(\d)/g, '$1$3');
	return /^4\d{12}(\d{3})?$/.test(cardNumber) && cardNumber.testLuhn();
}
String.prototype.testMasterCard = function() {
	var cardNumber = this.replace(/(\d)([\s\-])(\d)/g, '$1$3');
	return /^5[1-5]\d{14}$/.test(cardNumber) && cardNumber.testLuhn();
}
String.prototype.testAmericanExpress = function() {
	var cardNumber = this.replace(/(\d)([\s\-])(\d)/g, '$1$3');
	return /^3[47]\d{13}$/.test(cardNumber) && cardNumber.testLuhn();
}


// PREPARAMOS FUNCIONES PARA EL DATEPICKER
// extendemos el objeto String con la clase toDate, que devuelve un objeto Date

if(lang == 'en') {
	dformat = 'mm/dd/yyyy';
	jqdformat = 'mm/dd/yy';
} else {
	dformat = 'dd/mm/yyyy';
	jqdformat = 'dd/mm/yy';
}
String.prototype.toDate = function(f, modDia, modMes) {
	var f     = f || dformat;
    var modDia= modDia || 0;
    var modMes= modMes || 0;
    var normalizada = this.replace(/\b(\d\/)/g,'0$1');
    var anyo  = normalizada.substring(f.indexOf('y'), f.lastIndexOf('y') + 1);
    var mes   = parseInt(normalizada.substring(f.indexOf('m'), f.lastIndexOf('m') + 1), 10) + modMes;
    var dia   = parseInt(normalizada.substring(f.indexOf('d'), f.lastIndexOf('d') + 1), 10) + modDia;
    var fecha = new Date(anyo, mes-1, dia);
    return fecha;
}
Date.prototype.fechaLocal = function() {
	return this.toLocaleString().replace(/[0-2]?[0-9]\:.{5}/g, '');
}

Date.prototype.ddmmyyyy = function() {
	var dia = this.getDate()  < 10 ? '0'+this.getDate()  : this.getDate();
	var mes = (this.getMonth()+1) < 10 ? '0'+(this.getMonth()+1) : this.getMonth()+1;
	var fecha = [dia,'/',mes,'/',this.getFullYear()].join('');
	return fecha;
}

String.prototype.testDate = function(f) {
	var f = f || dformat;
    f = f.replace(/([\/\-])/g, '\\$1');
    f = f.replace('dd', '(0?[1-9]|[12][0-9]|3[01])'); // dias
    f = f.replace('mm', '(0?[1-9]|1[0-2])'); // meses
    f = f.replace('yyyy', '(19|20)\\d{2}'); // anyos, solo para 1901 hasta 2099
    f = ['/\\b', f, '/'].join('');
    reFecha = eval(f);
    var normalizada = this.replace(/\b(\d\/)/g,'0$1');
	var day = parseInt((lang != 'en' ? normalizada.substring(0, 2) : normalizada.substring(3, 5)), 10);
    if (!reFecha.test(normalizada) || day != normalizada.toDate().getDate()) {
        return false;
    } else {
        return true;
    }
}

$.datepicker.setDefaults( {
	yearRange :'-1:+2',
	changeFirstDay :false,
	minDate :'+0',
	showOn :'button',
	buttonImage :moduleRoot+'img/calendarIcon.gif',
	dateFormat : jqdformat
});
var fechaValidada = true;
function validarFecha(inputFecha, func) {
    var fecha0 = inputFecha.val();
    if (fecha0 == '' || fecha0.testDate(dformat)) {
        return true;
    }else {
        fechaValidada = false;
        alert(txtErrorFecha + ': ' + fecha0);
        setTimeout(function(){
            inputFecha.focus();
        }, 100);
        inputFecha.val('');
        return false;
    }
}

// function para acondicionar las clases de .calendariosDinamicos
function clasesCalendario(contexto) {
	var $td = $('td', contexto);
	$td.filter(':nth-child(odd)').addClass('impar').next().addClass('par');
	$td.filter(':empty').removeClass('impar par');
}

function extenderFormulariosReserva(contexto) {
	// fechas relacionadas
	// ver $.datepicker.setDefaults para las opciones por defecto
	var $formDisponibilidad = $('#buscadorDisponibilidad');
	$formDisponibilidad.submit(function() {
// Si estamos en la web o en la ficha de hotel, no tiene sentido redirigir a la home si no se entran fechas
		var nuevoDestino = $('#destinoUrl').val();
		var urlHotelActual = nuevoDestino;
		var posUrlHotel = location.href.indexOf('/u/');
		if (posUrlHotel >= 0) {
			urlHotelActual = location.href.substring(posUrlHotel + 3);
			posUrlHotel = urlHotelActual.indexOf('/');
			if (posUrlHotel >= 0) {
				urlHotelActual = urlHotelActual.substring(0, posUrlHotel);
			}
		}
//		if ((uriBaseHoteles == '/hotel/' || location.href.indexOf('/nuestros-hoteles/hotel/') >= 0 ||
//				location.href.indexOf('/nuestros-hoteles/reservar/') >= 0) &&
//				($('#fechaEntrada').val() == '' || $('#fechaSalida').val() == '') &&
//				urlHotelActual == nuevoDestino) {
		if (($('#fechaEntrada').val() == '' || $('#fechaSalida').val() == '') &&
				(urlHotelActual == nuevoDestino ||  location.href.indexOf('/nuestros-hoteles/') < 0)){
			alert(txtFaltanFechas);
			return false;
		}
		// Por si se integra en una web que no tiene idiomas (husainternacional, p.ej.)
		var idioma = $('input[name=lang]').val();
		if (!utilizarIdiomaEnUrl) {
			idioma = '';
		}
		if ($('#fechaEntrada').val() && $('#fechaSalida').val()) {
			var urlReservas = 'https://www.husa.es';
//			$formDisponibilidad.attr('action', webRoot+ idioma + '/' + uriReservar);
			$formDisponibilidad.attr('action', urlReservas+webRoot+ idioma + '/' + uriReservar);
		} else {
			$formDisponibilidad.attr('action', webRoot+ idioma +
				(uriBaseHoteles == '/hotel/' ? '/hotel/v/u/' : '/nuestros-hoteles/hotel/v/u/') +
				$('#destinoUrl').val());
		}
		$("[type=submit]").attr("disabled", "disabled");
		$("[type=submit]").css("opacity", "0.3");
		// Utilizamos javascriptDesactivado por si el buscador de disponibilidad se envia sin introducir fechas
		return true;
	});

	$('div.fechasRelacionadas', contexto).each(function() {
		var $input = $('input.datepicker', this),
			desfase=$(this).hasClass('mismoDia') ? 0 : 1;
        $input.bind('change', function() {
                var ok = validarFecha($(this), 'change');
				if (ok && $("input[name=fechaEntrada]").val() != '' && $("input[name=fechaSalida]").val() != '') {
					$("#comprobarDisponibilidad").removeAttr("disabled");
					$("#comprobarDisponibilidad").css("opacity", "1");
				} else {
					$("#comprobarDisponibilidad").attr("disabled", "disabled");
					$("#comprobarDisponibilidad").css("opacity", "0.3");
					if (this.name == 'fechaEntrada') {
						$('button.borrarSeleccion').click();
					} else {
						var entrada = $("input[name=fechaEntrada]").val();
						$('button.borrarSeleccion').click();
						if (entrada != '') {
							$("input[name=fechaEntrada]").val(entrada);
							$('div.calendariosDinamicos td:parent').filter('[title=' + entrada + ']').eq(0).addClass('seleccionado');
						}
					}
				}
				return ok;
        });
        $input.keypress(function (e) {
            if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
                return fechaValidada;
            }
            return true;

        });
		$input.eq(0).datepicker({
			beforeShow:function() {
				if ( $input.eq(1).val() ) {
					$('button.borrarSeleccion').click();
					$input.eq(1).val('');
				}
				var fecha = ($input.eq(1).val()) ? $input.eq(1).val().toDate(dformat, -desfase) : false;
				$input.eq(0).datepicker('option',{'maxDate':fecha,'dateFormat':jqdformat});
			},
			onSelect: function() {
				actualizarCalendarioDisp($input.eq(0));
                if (!$input.eq(1).val()) {
                    setTimeout(function(){
                        $input.eq(1).next().click();
                    }, 100);
                }
			}
		});

		$input.eq(1).datepicker({
			beforeShow:function() {
				var fecha = $input.eq(0).val();
				fecha = fecha.testDate(dformat) ? fecha.toDate(dformat, desfase) : 0;
				$input.eq(1).datepicker('option',{'minDate':fecha,'dateFormat':jqdformat});
			},
			onSelect: function() {
				actualizarCalendarioDisp($input.eq(1));
			}
		});
	});

}























/* RAMON ESTA USANDO:
 * todos los <input type="checkbox" ... /> y <select>
 * <input type="hidden" /> sin nombre que estan antes de los <select>
 * <input name="adults" ... />
 * <input name="children" ... />
 * <input name="rooms[x][id]" ... />
 * <input name="rooms[x][cupo]" ... />
 * <input name="rooms[x][people o personasBase me da lo mismo]" ... />
 * <input name="rooms[x][supplements][x_xxx][incompatibles]" ... />
 * <input name="rooms[x][supplements][x_xxx][cupo]" ... />
 * <input name="rooms[x][supplements][x_xxx][aumentaUsoHabitacion]" ... />
 * <input name="rooms[x][supplements][x_xxx][cantidadAumentaUso]" ... />
 */

// variables relacionadas con CSS:
var cssCupoSel = 'cupoSeleccionado',
    cssHabSel  = 'habitacionSeleccionada',
    colorHabOff= '#F6F0D6',
    colorHabOn = '#FFFFFF';

// al cargar el DOM comprobamos los que tienen "check" para ponerles una clase pero NO ocultamos los demas
function cambioClaseFilasCupo(filasCupo) {
	filasCupo.each( function() {
		var $t = $(this);
		if ($t.find(':checked').length) {
			$t.addClass(cssCupoSel);
		}
	});
}

function clickEnFilas(evento) {
	var $target = $(evento.target),
		$fila = $target.closest('tr');

	if ($fila.next().is(':hidden')) {
		$fila.addClass(cssCupoSel);
		$fila.nextAll().show()
	}else {
		$fila.removeClass(cssCupoSel)
		.nextAll().hide()
		.find('select').filter(function() {return ($(this).val()>0)}).val(0).change();
	}
}

function hallarIncompatibles(select) {
    var $sel = $(select),
    numHijo = parseInt($sel.prevAll('span').text().replace(/\D/g, ''))-1,
    inputIncompatibles = $sel.nextAll('[name*=\[incompatibles\]]'),
    idIncompatibles = null,
    $hermanitos = null;
    // comprobamos que sea del tipo que mola, de los que tienen incompatibles
    if (!inputIncompatibles.length) return false;
    // si tiramos palante reasignamos las variables
    idIncompatibles = inputIncompatibles.val().split(',');
    $hermanitos = $sel.closest('li').siblings().find('label:eq('+ numHijo +')').find('select').filter(function() {
        var id = $(this).attr('name');
        id = parseInt(id.substring(id.indexOf('_')+1));
        return ($.inArray(id+'', idIncompatibles) != -1);
    });
    return $hermanitos;
}

// comprobacion de los suplementos complementarios
function comprobarSuplCompl(element){
	// idBDD puede vernir de un parametro o de los datos insertados en el 
	var $t = $((element.tagName && element.tagName == 'SELECT') ? element : this),
		idBDD = $t.data('idBDD'),
		$supl = $('select.suplementosComplementarios_'+idBDD, $t.closest('ul')),
		cupoComplementario = parseInt($t.nextAll('[name*=\[cantidad\]]').val());
	$supl.each(function() {
		cupoComplementario-=parseInt($(this).val(), 10);
	});
	$supl.each(function() {
		var $t = $(this),
			$opt = $t.children(),
			cupoComplementarioTemp;
		cupoComplementarioTemp = cupoComplementario + parseInt($t.val(), 10);
		for (var i=0,l=$opt.length;i<l;++i) {
			$opt.eq(i)[(i>cupoComplementarioTemp)?'hide':'show']();
		}
		if (cupoComplementarioTemp > 0) {
			$t.removeAttr('disabled');
		} else {
			$t.attr('disabled', 'disabled');
		}
	});
}

// control del cambio en el valor del SELECT de habitacion
function cambioNumeroHabitaciones() {
	var $t = $(this),
		idBDD = $t.next().val(),
		$fila = $t.closest('tr'),
		valor = parseInt($t.val(), 10),
		$psPanel = $fila.next().find('div.psPanel'),
		$mismaHab = $('tr.habitacion select').filter(function() {return ($(this).next().val()==idBDD)}),
		cupoRestante = parseInt($t.nextAll('[name*=\[cupo\]]').val(), 10);
	// Primero recalculamos el cupo por si tenemos que eliminar opciones
	$mismaHab.each(function() {
		cupoRestante-=$(this).val();
	}).each(function() {
		if (this==$t.get(0)) return;
		var $hab = $(this),
			numOpcionesIni = $hab.children().length,
			numOpcionesFin = parseInt($hab.val())+cupoRestante;
		// como el numero maximo de habitaciones reservables por uso es de 3 (+ no seleccionado)
		// limitamos a 3+1 el numOpcionesFin
		numOpcionesFin = Math.min(numOpcionesFin, 3)+1;
		// anyadimos las que toca
		for (var i=numOpcionesIni,l=numOpcionesFin;i<l;++i) {
			$hab.append('<option>'+ i +'</option>');
		}
		// nos cargamos las que sobran
		for (var i=numOpcionesIni,l=numOpcionesFin;i>l;--i) {
			$hab.children(':last').remove();
		}
	});
	// y ahora animaciones y similares
	if ($t.val() != 0) {
		// si es distinto de cero replicamos los LABEL.multi en funcion del numero del SELECT ...
		$psPanel.find('div.accion:has(label.multi)').each(function() {
			var $label = $(this).find('label.multi'),
				$clon;
			// eliminamos los que sobran...
			$label.filter(':gt(' + (valor-1) + ')').remove();
			// o clonamos tantas veces como haga falta
			for (var i=$label.length, l=valor; i<l; ++i) {
				$clon = $label.eq(0).clone().appendTo($label.eq(0).parent());
				// cambiamos la etiqueta de "habitacion #"
				$clon.find('span').html( $clon.find('span').html().replace(/\d+/g, i+1) );
				// cambiamos el valor de los input
				$clon.find(':input').each(function() {
					this.name = this.name.replace('[supplements][0_', '[supplements]['+ i +'_');
					this.className = this.className.replace('suplementosComplementarios_0', 'suplementosComplementarios_'+ i);
					this.value = this.value.replace('0_', '' + i + '_');
				});
				// cambiamos el numero de habitacion
				$clon.find(':input[name*=\[room\]]').val(i);
			}
		});
		// cambiamos color de fondo, anyadimos la clase cssHabSel y finalmente hacemos el slideDown del pseudo panel
		$fila.add($fila.next()).children().css('backgroundColor', colorHabOn);
		$fila.addClass(cssHabSel);
		$psPanel.show();
	} else {
		// si es igual a cero, ocultamos y reseteamos a cero todos los valores contenidos en su desplegable asociado
		$fila.add($fila.next()).children().css('backgroundColor', colorHabOff);
		$fila.removeClass(cssHabSel);
		$fila.next().find('div.psPanel').hide().find('select').val(0);
	}
	validarFormulario('#formReserva');
}

// suplementos que modifican el cupo de habitacion tienen que actualizar las opciones
// que son relativas al numero de personas de esa habitacion
function actualizarCuposHabitacionActual() {
	var $t = $(this);
    var $trSuplementos = $t.closest('tr');
    var $trRoom = $trSuplementos.prev();
    var selectHab = $trSuplementos.find('select');
	var pBase = parseInt($trRoom.find('input[name*=\[personasBase\]]').val());
	var amount = parseInt($trRoom.find('select[name*=\[amount\]]').val());
	var nuevoNumPax = (pBase * amount) + calcularAumentoCupo(this);
	// con el nuevo num pax tenemos que hacer las acciones pertinentes
	selectHab.each(function() {
		var $sel = $(this),
			$opt = $sel.children(),
			numOpt = $opt.length,
			cantidad = 1,
			sTexto = txtPersonas;
        var $aumentaUso = $sel.nextAll('[name*=\[aumentaUsoHabitacion\]]');
        var $uso = $sel.nextAll('[name*=\[usoSuplemento\]]');
        // usoSuplemento == 0: noche
        // usoSuplemento == 1: persona o unidades
        var uso= $uso.val();
        var ambitoSuplemento = $sel.nextAll('[name*=\[hambitoSuplemento\]]').val();
        var aumentaUso = $aumentaUso.val();
		if (uso==1) {
           cantidad *= nuevoNumPax;
            // ambitoSuplemento == 0: persona
            // ambitoSuplemento == 2: noche o unidades
			if (ambitoSuplemento==2) {
				cantidad *= $('#numNoches').val();
                    sTexto = txtUnidades;
            }
			if ($sel.nextAll('input[name*=\[incluido\]][value=true]').length) {
				// si es un suplemento incluido modificamos el valor para que sea igual a la nueva canitidad
				$opt.text($opt.text().replace(/\d+/g, cantidad)).attr('value', cantidad);
			} else {
				// sumamos uno por no obviar el valor 0
                cantidad++;
                if (numOpt > cantidad) {
                        $opt.eq(cantidad-1).nextAll().remove();
                } else if (numOpt < cantidad) {
                    for (var i=numOpt,l=cantidad;i<l;++i) {
						$sel.append('<option>'+ i + sTexto +'</option>')
                    }
                }
                cantidad--;	
			}
        }
            // modificamos el cupo de los suplementos complementarios ...
			$sel.nextAll('[name*=\[cantidad\]]').val(cantidad);
        });
	// ... y recomprobamos OPTIONs
	comprobarSuplCompl(this);
	//$('#formReserva').triggerHandler('submit');
	validarFormulario('#formReserva');
}

// Suplementos incompatibles
function cambioSuplIncompatibles() {
	var $incops = hallarIncompatibles(this);
		if ($(this).val() == 0) {
			$incops.removeAttr("disabled");
		} else {
			$incops.attr('disabled', 'disabled');
		}
}
/**
 Comprobaciones cuando cambia el número de personas:
 Si tenemos el número correcto de personas, desactivamos los suplementos que aumentan el cupo que no estén seleccionados
 Si NO tenemos el número correcto de personas, volvemos a activar los suplementos desactivados
*/
function revisarCuposNoSeleccionados(context, activar) {
    var suplAumentaCupo   = $('select.aumentaCupo', context);
    suplAumentaCupo.each(function() {
        var $supl = $(this);
        if (!activar && parseInt($supl.val()) == 0) {
            $supl.attr('disabled', 'disabled');
            $supl.children().each(function() {
                if ($(this).is(':hidden')) $(this).show();
            });
        } else if (activar && $supl.attr('disabled')) {
            $supl.removeAttr('disabled');
            $supl.children().each(function() {
                if ($(this).is(':hidden')) $(this).show();
            });
        }
	});
}
// suplementos con cupo
function cambioSuplConCupo() {
	var $t = $(this),
		idBDD = $t.next().val(),
		$mismoSupl = $('select[name*=\[supplements\]]').filter(function() {return ($(this).next().val()==idBDD)}),
		cupoRestante = parseInt($t.nextAll('[name*=\[cupo\]]').val(), 10);
	// Primero recalculamos el cupo por si tenemos que ocultar opciones
	$mismoSupl.each(function(){
		cupoRestante-=$(this).val();
	});
	$mismoSupl.each(function() {
		var accion = null,
			$supl = $(this),
			$opt  = $supl.children(),
			numOpcionesFin = parseInt($supl.val(),10)+cupoRestante;
		if (numOpcionesFin<$opt.length) {
			for (var i=1,l=$opt.length;i<l;++i) {
				accion = (i<=numOpcionesFin)?'show':'hide';
				$opt[accion]();
			}
			if (numOpcionesFin==0) {
				$supl.attr('disabled', 'disabled');
			} else {
				$supl.removeAttr('disabled');
			}
		}
	});
    // Primero volvemos a mostrar opciones ocultas de esta misma habitación
    // var $ocultos = $('select').find('option').filter(function() {return $(this).parent().next().val()==idBDD && $(this).is(':hidden');});
    // $ocultos.each(function() {$(this).show();});
}

// CALCULOS DE SUBOTOTALES
function calcularSubtotales() {
	var stHab = 0,
		stSupl= 0,
		numNoches = parseInt($('#numNoches').val());
	$('tr.habitacionSeleccionada').next().andSelf().find('select').each( function() {
		// iteramos por cada uno de los select y anyadimos al sumatorio correspondiente
		var $t = $(this),
			$inputPrecio = $t.prevAll('input[type=hidden]').length ? $t.prevAll('input[type=hidden]').eq(0) : $t.closest('label').prevAll('input[type=hidden]').eq(0),
			nTemp;
		nTemp =   parseInt( $t.val(), 10 ) // valor del SELECT
			  * parseFloat( $inputPrecio.val(), 10 ); // valor del INPUT type=hidden antes del SELECT
		if ($t.closest('tr.habitacion').length) {
			stHab += nTemp;
		} else {
			stSupl += nTemp;
		}
	});
	$('#stHab').html(stHab.aPrecio() + ' &euro;');
	$('#stSupl').html(stSupl.aPrecio() + ' &euro;');
	$('#precioMedio').html( ((stSupl + stHab) / numNoches).aPrecio() + ' &euro;');
	$('#ddTotal').html((stSupl + stHab).aPrecio() + ' &euro;');
}
// VALIDACION DEL FORMULARIO formReserva
function validarFormulario(context) {
	// Esto es por si se invoca el submit por el cambio de idioma (en ese caso no tiene que validar sino enviarlo directamente)
		if ($('input[name=dispForm]', context).length > 0 && $('input[name=dispForm]', context).val() == '1') {
			return true;
		}
		var suplIncompatibles = $('select.conIncompatibles', context);
		var suplAumentaCupo   = $('select.aumentaCupo', context);
		// enteros para validacion
		var inputAdults = parseInt($('input[name=adults]', context).val(), 10),
			inputChildren= parseInt($('input[name=children]', context).val(), 10)
		$(":submit").removeAttr("disabled").css("opacity", "1");;
		// comprobamos CUPO == PAX
		var selectHab = $('tr.'+cssHabSel+' select', context),
			numPax = 0,
			aErr = [];
		// iteramos por las habitaciones a ver que tal va...
		selectHab.each(function() {
			var $t = $(this),
				numHab = parseInt($t.val(), 10);
			if (numHab != 0) {
				numPax += numHab * parseInt($t.nextAll('[name*=\[personasBase\]]').val());
			}
		});
		// y filtramos los aumenta uso habitacion en funcion de si tienen valor 'true' y...
		// su select anterior tiene valor != 0. Los sumamos a muerte
        numPax += calcularAumentoCupo(suplAumentaCupo);
		if (numPax != (inputChildren + inputAdults)) {
			aErr.push(txtCupoNoCoincide.replace('#numPax#', numPax).replace('#numInputs#', (inputChildren + inputAdults)));
		}
		/* */
		// ahora toca el temita de comprobar que nos nos piruleen con los incompatibles
		suplIncompatibles.filter(function() {return $(this).val() != 0}).each(function() {
			var $t = $(this),
				$incomp = hallarIncompatibles(this);

			$incomp = $incomp.filter(function() {return $(this).val() != 0});
			if ($incomp.length) {
				aErr.push(txtSuplIncompat + $t.closest('li').find('h5').text() + ', ' + $incomp.eq(0).closest('li').find('h5').text());
				return false;
			}
		});
		/* */
		var $divSubmit = $('div.submit', context);
		if (aErr.length) {
			var sHtml = '<ul><li>' + aErr.join('</li><li>') + '</li></ul>',
				$divError = $divSubmit.children('div.ko');
			$divSubmit.find('div.ok').remove();
			if ($divError.length) {
				$divError.html(sHtml).fadeOut(400).fadeIn(400)
			} else {
				$('<div class="ko" style="display:none">'+sHtml+'</div>').appendTo($divSubmit).show(1200);
			}
            // Activar suplementos que afectan al cupo si hay menos personas que las indicadas
            revisarCuposNoSeleccionados(context, (numPax < (inputChildren + inputAdults) ? true : false ));
			return false;
		}
		else {
			$divSubmit.find('div.ko').remove();
			$('<div class="ok" style="display:none"><ul><li>'+txtPaso1ReservaOK+'</li></ul></div>').appendTo($divSubmit).show(1200);
            // Desactivar suplementos que afectan al cupo si ya se han seleccionado las personas indicadas
    		if (numPax == (inputChildren + inputAdults)) {
                revisarCuposNoSeleccionados(context, false);
            }
			return true;
		}

}
function onSubmitFormulario(context) {
	var idFormulario = $(context).closest('form').attr('id');
	$('#' + idFormulario).submit(function() {
		var $formOK = validarFormulario('#' + idFormulario);
		if ($formOK) {
			$("[type=submit]").attr("disabled", "disabled");
			$("[type=submit]").css("opacity", "0.3");
		} else {
			$("[type=submit]").removeAttr("disabled");
			$("[type=submit]").css("opacity", "1");
		}
		return $formOK;
	});
}

function controlesReserva() {
	var context  = '#formReserva-disponibilidad',
		filasCupo = $('tr.cupoHab', context),
		selectHab = $('tr.habitacion select', context),
		selectSupl= $('tr.infoSuplementos select');

	//si no existe el contexto no seguimos, total pa que...
	if (!$(context).length) return false;

	// preparamos estilos
    cambioClaseFilasCupo(filasCupo);
	
	// preparamos los SELECT de suplementos pertinentes con clases para poder llamarlos a traves de LIVE
	// suplementos que aumentan el cupo de una habitacion:
	selectSupl.filter( function(){
		return $(this).nextAll('[name*=\[aumentaUsoHabitacion\]][value=true]').length;
	}).addClass('aumentaCupo');
	
	// suplementos con incompatibles:
	selectSupl.filter( function(){
		return $(this).nextAll('[name*=\[incompatibles\]][value!=]').length;
	}).addClass('conIncompatibles');
	
	// suplementos con cupo
	selectSupl.filter( function(){
		return $(this).nextAll('[name*=\[cupo\]][value!=]').length;
	}).addClass('conCupo');
	
	// suplementos complementarios:
	selectSupl.each(function() {
		var $t = $(this),
			idBDD = $t.next().val(),
			$hermanitos;
		// comprobamos que no tenga ya la clase para evitar hacer demasiado trabajo
		if ($t.is('.suplementosComplementarios_'+idBDD)) {
			return;
		}
		$hermanitos = $t.closest('tr').find('select').filter(function() {return $(this).next().val()==idBDD;});
		if ($hermanitos.length>1) {
			$hermanitos.addClass('suplementosComplementarios_'+idBDD).data('idBDD', idBDD)
		}
	});	
	
	// ASIGNACION DE EVENTOS
	// siempre que sea posible la haremos a traves de delegación de eventos ("live") para mejorar el rendimiento

	// evento a la "clickMyRows"
    filasCupo.live('click', clickEnFilas);
    selectHab.bind('change', cambioNumeroHabitaciones);
	$('tr.infoSuplementos').delegate('select.aumentaCupo', 'change', actualizarCuposHabitacionActual)
    .delegate('select.conIncompatibles', 'change', cambioSuplIncompatibles)
    .delegate('select.conCupo', 'change', cambioSuplConCupo)
	.delegate('select[class*=suplementosComplementarios_]', 'change', comprobarSuplCompl);
	
    $(context).delegate('select', 'change', calcularSubtotales);

    onSubmitFormulario(context);

}

// funcion para el paso de DATOS DE USUARIO
$(function() {
	var context = '#formReserva.reservar-2'; 
	//si no existe el contexto (datos de usuario) no seguimos, total pa que...
	if (!$(context).length) return false;

    $('.sensibledata').attr('autocomplete', 'off');

	$('#tipoPago').bind('change', function() {
		var elementos = $(this).val()=='pagoBono'?['Bono','Directo']:['Directo','Bono'];
		$('#pago_'+elementos[0]).show();
		$('#pago_'+elementos[1]).hide();
	}).triggerHandler('change');

	$(context).submit(function() {
		$("[type=submit]").removeAttr("disabled");
		$("[type=submit]").css("opacity", "1");
		var $this = $(this),
		$fields = $('fieldset', context),
		reUL = /<\/?ul>/g,
		formElem,
		aErr = [],
		mixedTemp;

		// primer fieldset - datos personales
		var tipoDeDoc = $('select[name=client\[idKind\]]', context).val(),
			numDoc = $('input[name=client\[idNumber\]]', context).val();
		switch (tipoDeDoc) {
			case 'dni':
			if (!numDoc.testDNI()) {
				aErr.push('<li>', txtFormatDocInvalid,'</li>');
			}
			break;
			case 'nie':
			if (!numDoc.testNIE()) {
				aErr.push('<li>', txtFormatDocInvalid,'</li>');
			}
			break;
		}
		mixedTemp = validarObl($fields.get(0));
		if (mixedTemp !== true) aErr.push(mixedTemp.replace(reUL, ''));

		// segundo fieldset - datos de pago
		// Si el cliente está logado y el tipo de contrato es "Agencia", solamente validar que no está vacío el campo
		if ($('#tipoPago').val() != 'pagoBono') {
			// aqui tambien se entra si no existe el <input id="#tipoPago" ... />
			// validamos numero tarjeta
			var tipoTarjeta = $('select[name=creditCard\[kind\]]', context).val(),
				numTarjeta  = $('input[name=creditCard\[number\]]', context).val();
			switch (tipoTarjeta) {
				case 'VI':
				if (!numTarjeta.testVisa()) {
					aErr.push('<li>', txtNumTarjInvalid,'</li>');
				}
				break;
				case 'MC':
				if (!numTarjeta.testMasterCard()) {
					aErr.push('<li>', txtNumTarjInvalid,'</li>');
				}
				break;
				case 'AX':
				if (!numTarjeta.testAmericanExpress()) {
					aErr.push('<li>', txtNumTarjInvalid,'</li>');
				}
				break;
			}
			// validamos fecha de caducidad
			var caducaMes = parseInt($('[name=creditCard\[month\]]', context).val(), 10),
				caducaAno = parseInt($('[name=creditCard\[year\]]', context).val(), 10);
			if (!caducaMes || !caducaAno || new Date() > (new Date()).setFullYear(caducaAno+2000, caducaMes-1, 1)) {
				aErr.push('<li>',txtCaducidadKo,'</li>');
			}
			// validamos el numero de verificacion
			var secCode = $('[name=creditCard\[sec\]]', context).val();
			if (!secCode || secCode.length!=3 || parseInt(secCode, 10) != secCode) {
				aErr.push('<li>',txtCardCodeKo,'</li>');
			}

			mixedTemp = validarObl('#pago_Directo');
			if (mixedTemp !== true) aErr.push(mixedTemp.replace(reUL, ''));
		} else {
			// si esta marcado pago con bono validamos el campo que toca
			mixedTemp = validarObl('#pago_Bono');
			if (mixedTemp !== true) aErr.push(mixedTemp.replace(reUL, ''));
		}


		// tercer fieldset - he leido las cosas legales esas
		if (!$('[name=disclaimer]', context).is(':checked')) {
			aErr.push('<li>',txtLegalKo,'</li>');
		}

		/* comprobacion final ... */
		if (aErr.length) {
			var sHtml = '<ul><li>' + aErr.join('</li><li>') + '</li></ul>', $divSubmit = $('fieldset.submit', context)
			$divError = $divSubmit.children('div.ko');
			if ($divError.length) {
				$divError.html(sHtml).fadeOut(400).fadeIn(400)
			}
			else {
				$('<div class="ko floatLeft" style="display:none">' + sHtml + '</div>').prependTo($divSubmit).show(1200);
			}
			return false;
		}
		else {
			$('input[name=creditCard\[number\]]', context).val(numTarjeta.replace(/(\d)([\s\-])(\d)/g, '$1$3'));
			$("[type=submit]").attr("disabled", "disabled");
			$("[type=submit]").css("opacity", "0.3");
			return true;
		}
	});

});
function calcularAumentoCupo(base) {
    nuevoNumPax = 0;
    var selectHab = $(base).closest('tr').find('select');
	selectHab.each(function() {
		var $THIS = $(this);
		if ($THIS.nextAll('[name*=aumentaUsoHabitacion]').val()=='true') {
			nuevoNumPax+=(parseInt($THIS.val()) * parseInt($THIS.nextAll('[name*=cantidadAumentaUso]').val()));
		}
	});
    return nuevoNumPax;
}
// -------------------------------------------------------------- utilizacion de cookies
function getCookie( name ) {
	var start = document.cookie.indexOf( name + "=" );
	var len = start + name.length + 1;
	if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {
		return null;
	}
	if ( start == -1 ) return null;
	var end = document.cookie.indexOf( ';', len );
	if ( end == -1 ) end = document.cookie.length;
	return unescape( document.cookie.substring( len, end ) );
} // function

function setCookie( name, value, expires, path, domain, secure ) {
	var today = new Date();
	today.setTime( today.getTime() );
	if ( expires ) {
		expires = expires * 1000 * 60 * 60 * 24;
	}
	var expires_date = new Date( today.getTime() + (expires) );
	document.cookie = name+'='+escape( value ) +
		( ( expires ) ? ';expires='+expires_date.toGMTString() : '' ) + //expires.toGMTString()
		( ( path ) ? ';path=' + path : '' ) +
		( ( domain ) ? ';domain=' + domain : '' ) +
		( ( secure ) ? ';secure' : '' );
} // function

function deleteCookie( name, path, domain ) {
	if ( getCookie( name ) ) document.cookie = name + '=' +
			( ( path ) ? ';path=' + path : '') +
			( ( domain ) ? ';domain=' + domain : '' ) +
			';expires=Thu, 01-Jan-1970 00:00:01 GMT';
} // function

// validacion generica de formularios
function validarObl(campos) {
	var err = [];
	$(':input', campos).each(function() {
		var $t=$(this),
			className = $t.attr('className');
		if (!className) return;

		if ($t.hasClass('obl') && !$t.val()) {
			if ($t.is(':visible')) $t.effect('highlight', {color:'#793635'}, 2000);
			err.push('<li>',txtCampo, '<strong>', $t.closest('label').find('span:first').text().replace('*', ''), '</strong>', txtEsObligatorio, '</li>');
		} else if ($t.hasClass('email') && $t.val() && !$t.val().testEmail()) {
			$t.effect('highlight', {color:'#793635'}, 2000);
			err.push('<li>',txtCampo, '<strong>', $t.closest('label').find('span:first').text().replace('*', ''), '</strong>', txtNoEsEmail, '</li>');
		} else if (false){

		}
	});
	return err.length ? '<ul>'+err.join('')+'</ul>' : true;
}
