const Ad74aUtils = (function () {
	
	
	const allowedOrigins = () => { 
		return {
		    'http://tsadm.jakina.ejgvdns': 1,
		    'http://www.lan.jakina.ejiedes.net': 1
		}
	};
	
	const cerrarFeedbacks = () =>  {
		try{
			$("div.rup-feedback").each(function(){
				$(this).rup_feedback("close");
			});
		}catch(e){}
	};
	
	// Bloquear pantalla mientras se esta realizando una operacion en segundo plano
	// Permite asignarle propiedades
	const bloquearInterfaz = (properties) => {
		var defaultProp = {
			baseZ: 999999,
			centerX: true, 
			css:{
				paddingTop: "0.5em",
				paddingBottom: "0.5em",
				color: "#1472a4",
				borderColor: "#1472a4",
				background: "#FFFFFFb3",
				fontSize : "1.6em",
				cursor:		'default'
			},
			overlayCSS: {
				backgroundColor: 	'#222222', 
				opacity:			0.5,
				cursor:		'default'
			}, 	
			message: `<div class="processing-container">
							<span class="loading">${$.rup.i18n.base.rup_blockUI.cargando}</span>
					</div>`
		};
		$.blockUI($.extend(true, defaultProp, properties));
	};

	// Desbloquear pantalla
	const desBloquearInterfaz = () => {
		try{
			$.unblockUI();
		}catch(e){
			$('.blockUI').remove();
		}
	};
	
	//Ordenar un objeto por sus keys
	const sortObject = o => {
		try{
			return Object.keys(o).sort().reduce((r, k) => (r[k] = o[k], r), {});
		}catch(err){
			console.log(err);
			return {};
		}
	}
	
	const validarTelefono = (telefono) => {
		if(""==telefono){
			return true;
		}else{
			 const intRegex = /^[6]\d{8}|[7][1-4]\d{7}|[8,9][1-9]\d{7}$/;
	         return intRegex.test(telefono);
		}
     };
	
	const validarUrl = (str) => {
		if(str==""){
			return true;
		}
		var regex = new RegExp("^(http[s]?:\\/\\/(www\\.)?|ftp:\\/\\/(www\\.)?|www\\.){1}([0-9A-Za-z-\\.@:%_\+~#=]+)+((\\.[a-zA-Z]{2,3})+)(/(.)*)?(\\?(.)*)?"); 
		var without_regex = new RegExp("^([0-9A-Za-z-\\.@:%_\+~#=]+)+((\\.[a-zA-Z]{2,3})+)(/(.)*)?(\\?(.)*)?");		
		if(regex.test(str) || without_regex.test(str)){
		   return true;
		}else{
		   return false;
		}	
     };
	
	

	//Funcion solo numerico
	const soloNumericos = () =>{
		$("input.solonumerosinsignos").keydown(function (e) {
		    // Allow: backspace, delete, tab, escape, enter and .
		    if ($.inArray(e.keyCode, [46, 8, 9, 27, 13]) !== -1 ||
		         // Allow: Ctrl/cmd+A
		        (e.keyCode == 65 && (e.ctrlKey === true || e.metaKey === true)) ||
		         // Allow: Ctrl/cmd+C
		        (e.keyCode == 67 && (e.ctrlKey === true || e.metaKey === true)) ||
		         // Allow: Ctrl/cmd+X
		        (e.keyCode == 88 && (e.ctrlKey === true || e.metaKey === true)) ||
		         // Allow: home, end, left, right
		        (e.keyCode >= 35 && e.keyCode <= 39)) {
		             // let it happen, don't do anything
		             return;
		    }
		    // Ensure that it is a number and stop the keypress
		    if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
		        e.preventDefault();
		    }
		    
//		    deleteSimbol(this, true);
		});
		$("input.solonumeros").keydown(function (e) {
			 if ($.inArray(e.keyCode, [46, 8, 9, 27, 13,188,110,190]) !== -1 ||
			         // Allow: Ctrl/cmd+A
			        (e.keyCode == 65 && (e.ctrlKey === true || e.metaKey === true)) ||
			         // Allow: Ctrl/cmd+C
			        (e.keyCode == 67 && (e.ctrlKey === true || e.metaKey === true)) ||
			         // Allow: Ctrl/cmd+X
			        (e.keyCode == 88 && (e.ctrlKey === true || e.metaKey === true)) ||
			         // Allow: home, end, left, right
			        (e.keyCode >= 35 && e.keyCode <= 39)) {
			             // let it happen, don't do anything
			             return;
			    }
		    // Ensure that it is a number and stop the keypress
		    if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
		        e.preventDefault();
		    }
		    
//		    deleteSimbol(this, true);
		});
	};
	
	//Funcion solo numerico
	const sinEspacios = () =>{
		$("input.sinespacios").keydown(function (e) {
		    // Allow: backspace, delete, tab, escape, enter and .
			 if (e.which === 32)
			      return false;
			  
		    
//		    deleteSimbol(this, true);
		});
		$("input.solonumeros").keydown(function (e) {
			 if ($.inArray(e.keyCode, [46, 8, 9, 27, 13,188,110,190]) !== -1 ||
			         // Allow: Ctrl/cmd+A
			        (e.keyCode == 65 && (e.ctrlKey === true || e.metaKey === true)) ||
			         // Allow: Ctrl/cmd+C
			        (e.keyCode == 67 && (e.ctrlKey === true || e.metaKey === true)) ||
			         // Allow: Ctrl/cmd+X
			        (e.keyCode == 88 && (e.ctrlKey === true || e.metaKey === true)) ||
			         // Allow: home, end, left, right
			        (e.keyCode >= 35 && e.keyCode <= 39)) {
			             // let it happen, don't do anything
			             return;
			    }
		    // Ensure that it is a number and stop the keypress		    
		});
	};
	
	const monedaSpan = () =>{
		let x = document.querySelectorAll(".monedaSpan");
	    for (let i = 0, len = x.length; i < len; i++) {
	    	try{
	    		if( ! x[i].innerHTML.includes('€')){
	    			let num = Number(x[i].innerHTML).toLocaleString('es', { style: 'currency', currency: 'EUR' });
					if(num == 'NaN €'){
						throw true;
					}
					x[i].innerHTML = num ;
	    		}
	    	}catch (e){
				alert($.rup.i18n.app.errores.errorConversion);
				x[i].currentTarget.value = Ad74aUtils.valorFormatoMoneda(x[i].currentTarget.defaultValue);
			}
	    }
    };
	
	const formatoMoneda = () =>{
		let x = document.querySelectorAll(".moneda");
        for (let i = 0, len = x.length; i < len; i++) {
        	
        	try{
        		if( ! x[i].value.includes(' €')){
					let num = Ad74aUtils.valorFormatoMoneda(x[i].value);
					x[i].value = num ;
					if(x[i].value == 'NaN €'){
						throw true;
					}
        		}				
        	}catch (e){
				alert($.rup.i18n.app.errores.errorConversion);
				x[i].currentTarget.value = Ad74aUtils.valorFormatoMoneda(x[i].currentTarget.defaultValue);
			}
			
			$(x[i]).change(function (x) {
				try{
					let num = x.currentTarget.value;
					let numSinFormato = num.replace(' €', '').replace('.','').replace(',','.');
					x.currentTarget.value = Ad74aUtils.valorFormatoMoneda(numSinFormato);
					if(x.currentTarget.value == 'NaN €'){
						throw true;
					}
				}catch (e){
					alert($.rup.i18n.app.errores.errorConversion);
					x.currentTarget.value = Ad74aUtils.valorFormatoMoneda(x.currentTarget.defaultValue);
				}
				
				
			})
        }
		
	};
	
	const deshacerFormatoMoneda = (data,idFormulario) =>{
		let x = document.querySelectorAll("#"+ idFormulario + " .moneda");
        for (let i = 0, len = x.length; i < len; i++) {
			let num = data[x[i].name];
			if(num != undefined ){
				data[x[i].name] = Ad74aUtils.deshacerValorFormatoMoneda(num);
			}
        }
        return data;
		
	};

	
	const valorFormatoMoneda = (num,numDecimals) =>{
		
		let decimals = "";
		let locale = "es";
		let params = {};
		params.style = 'currency';
		params.currency = 'EUR'
		if(numDecimals != undefined && numDecimals != null && numDecimals > 0) {
			params.minimumFractionDigits = 4;
			locale = undefined;
		}
		if( num != undefined && num!= null){
			return Number(num).toLocaleString(locale, params);
		}else{
			return  Number('').toLocaleString(locale, params);
		}
					
	};
	
	const deshacerValorFormatoMoneda = (value,locale) =>{
		//Por defecto en castellano
		
		if( value != undefined && value!= null){
			return  value.replace('€', '').trim().replaceAll('.','').replace(',','.');
		}else{
			return '';
		}
	
	
	};
	
	const refreshViewFood = (filter,url,estados) =>{
		let data = filter;
    	data = JSON.stringify(data);    	
    	
        let ajaxData = {
                'url': url,
        	       'type': 'POST',
        	       'data': data,
        	       'contentType': 'application/json',
        	       'dataType': 'json',
        	       success: function (data) {
        	    	   if(data != undefined){
        	    		   $.each(data , function(index, elem) { 
        	    			  let key = undefined; 
        	    			  let value = jQuery.map( elem, function( valor,index ) {
        	    				   			key = index;
        	    				   			return valor;
        	    			  			  });
	               	    	   $.each(estados , function(index, codEstado) { 
	               	    		   if(key == codEstado){
	               	    			$('.datosResumen[data-customerid="'+index+'"]').text(value);  
	               	    		   }	    	        	    	  
	            	    	   });
       	    		          }); 
        	    	   }
        	    	   let sum = 0;
        	    	   $.each(estados , function(index) { 
	        	    	   sum = sum + parseInt($('.datosResumen[data-customerid="'+index+'"]').text());
        	    	   });
        	    	   $('.datosResumen[data-customerid="00"]').text(sum);
        	    		 
        	       },
        	       error: function (error) {

        	       }
         	};
 
        $.rup_ajax(ajaxData);
	};
	
	const deshabilitarBotones = () =>{
		$('button').click(function() {
		    let myButton = $(this).prop("disabled", true); 
		    window.setTimeout(function() {
		    	myButton.prop("disabled",false);
		    }, 1000 /* 1 sec */); 
		});	
		
	};
	
	
	const hacerPlegable = () =>{
		$(".plegable").unbind('click');
		$(".plegable").click(function(elemt){
			if(elemt.currentTarget.nextElementSibling.classList.contains('plegado')){
				//El siguiente div al clicado no es visible
				try{					
					elemt.currentTarget.firstChild.classList.add('mdi-minus-box-outline');
					elemt.currentTarget.firstChild.classList.remove('mdi-plus-box-outline');
				}catch(err){}
				
			}else{
				//El siguiente div al clicado es visible
				try {					
					elemt.currentTarget.firstChild.classList.remove('mdi-minus-box-outline');
					elemt.currentTarget.firstChild.classList.add('mdi-plus-box-outline');
				}catch(err){}
			}
			
			$(elemt.currentTarget.nextElementSibling).toggleClass('plegado');
		});	
		
	};

	
	/**
	 * Función que valida un campo numérico mientras se está escribiendo en él.
	 * 
	 * selector: selector para obtener los objetos
	 * properties:
	 * 	- tipo: decimal/integer(default)
	 *  - negative: true/false(default). Si false no acepta negativos
	 *  - callback: función a ejecutar en el blur y keyup
	 *  - decimals: número de decimales a aplicar si el tipo=decimal (default=2)
	 *  - integers: número de dígitos de la parte entera (default=6)
	 *  - minVal: indica el valor mínimo que se podrá escribir
	 *  - maxVal: indica el valor máximo que se podrá escribir
	 *  - currency: true/false(default). Indica si el número es moneda
	 *  	- usa las funciones Ad74aUtils.valorFormatoMoneda() y Ad74aUtils.deshacerValorFormatoMoneda()
	 *  - text: true/false(default). Indica si esolo texto
	 *  	- si true, no se añaden los eventos
	 *  - tooltip: default null (tooltip de UDA)
	 *  	"tooltip": {
	 *			"icon": "mdi mdi-information",
	 *			"className": "clasecss"
	 *			"properties": {
	 *				        content: {
	 *			        	title: "Título del tooltio", -- opcional
	 *			            text: "TExto del tooltip"
	 *			        }
	 *			},
	 *			"showOnMaxVal": true
	 *		}
	 *  
	 *  Invocación:	ab10bUtils.util.numero(selector,propiedades a sobreescribir)
	 *  	- Ad74aUtils.number(".decimal",{"tipo": "decimal", "negative": true, "callback": function(){calcularTotal()}});
	 *  
	 */
	const number = function(selector, properties){
		let defProperties = {
			"type": "integer",
			"negative": false,
			"callback": "",
			"decimals": 2,
			"integers": 6,
			"minVal": false,
			"maxVal": false,
			"currency": false,
			"text": false,
			"tooltip": null,
			"showZeroValue": true
		}
		
		$.extend(true, defProperties, properties);
		if(defProperties.type==="decimal" && Number(defProperties.decimals) <= 0){
			defProperties.decimals = 2;
		}
		if(Number(defProperties.integers) <= 0){
			defProperties.decimals = 6;
		}
		
		
		if(defProperties.type==="decimal"){
			$.each($(selector), function(idx, el){
				if(defProperties.text){					
					$(el).html(Number($(el).html()).toFixed(defProperties.decimals));
					//$(el).attr("value",Number($(el).val()).toFixed(defProperties.decimals));
				}else{					
					$(el).val(Number($(el).val()).toFixed(defProperties.decimals));
					$(el).attr("value",Number($(el).val()).toFixed(defProperties.decimals));
				}
				
			});
		}
		
		if(defProperties.currency){		
			$.each($(selector), function(idx, el){
				if(defProperties.text){					
					$(el).html(Ad74aUtils.valorFormatoMoneda($(el).html()));				
				}else{					
					$(el).val(Ad74aUtils.valorFormatoMoneda($(el).val()));				
				}
			});	
		}
		
		if(!defProperties.text){
			
			const elementos = $(selector);
			let pattern = "";
			let zeroValue = 0;
			if(defProperties.type==="decimal" && defProperties.negative){
				pattern = "(^-?\\d\\d{0,"+(defProperties.integers-1)+"}\\.\\d{0,"+defProperties.decimals+"}$)|(^-?\\d\\d{0,"+(defProperties.integers-1)+"}$)";
				zeroValue = zeroValue.toFixed(defProperties.decimals);
			}else if(defProperties.type==="decimal" && !defProperties.negative){
				pattern = "(^\\d\\d{0,"+(defProperties.integers-1)+"}\\.\\d{0,"+defProperties.decimals+"}$)|(^\\d\\d{0,"+(defProperties.integers-1)+"}$)";
				zeroValue = zeroValue.toFixed(defProperties.decimals);
			}else if("integer" === defProperties.type && defProperties.negative){
				pattern = "(^-\\d\\d{0,"+(defProperties.integers-1)+"}$)";
			}else if("integer" === defProperties.type && !defProperties.negative){
				pattern = "(^\\d\\d{0,"+(defProperties.enteros-1)+"}$)";
			}
			
			if(!defProperties.showZeroValue) {
				zeroValue = '';
			}
			
			const test = new RegExp(pattern);
			
			$.each(elementos, function(idx, el){
				let tooltip = null;
				// Añadir tooltip si tiene icono y properties				
				if(defProperties.tooltip != null && defProperties.tooltip.icon != null  
						&& defProperties.tooltip.properties != null){					
					// Borrar tooltip previo si existe
					const icon = $(el).next("i");
					if($(icon).data("number")){
						$(icon).remove();
					}
					$(el).after('<i data-number="true" class="'
							+defProperties.tooltip.icon+' '+(defProperties.tooltip.className?defProperties.tooltip.className:'')
							+'" style="font-size: 1.3rem;padding: 1px 10px 0 0;position: absolute;right: 0;top: 0;"></i>');
					tooltip = $(el).next("i").rup_tooltip(defProperties.tooltip.properties);
				}
				
				$(el).unbind('keyup');
				$(el).unbind('blur');
				$(el).unbind('focus');
				
				$(this).data("prev", "");
				$(this).attr("data-prev", "");
				
				$(el).bind('keyup',function(e){  
					const input = $(this);
					const oldVal =  input.data("prev");			
					const newVal = $.trim(input.val());
					input.val(newVal);
					input.attr("value", newVal);
					if(newVal != null && ((newVal!="-" && defProperties.negative) || !defProperties.negative)){
						if(!((e.keyCode == 46 || e.keyCode == 8) && newVal == "")) {
							if(!test.test(newVal)){
								input.val(oldVal); 
								input.attr("value", oldVal);
							}else if(defProperties.maxVal && Number(newVal) > defProperties.maxVal ){
								input.val(oldVal); 	
								input.attr("value", oldVal);
								if(tooltip != null && defProperties.tooltip.showOnMaxVal == true) tooltip.rup_tooltip("open");
							}else if(defProperties.minVal && Number(newVal) < defProperties.minVal ){
								input.val(oldVal); 	
								input.attr("value", oldVal);
								if(tooltip != null && defProperties.tooltip.showOnMinVal == true) tooltip.rup_tooltip("open");
							}else{
								input.data("prev", newVal);
								input.attr("data-prev", newVal);
							} 
							if(defProperties.callback !== undefined && defProperties.callback !== "") defProperties.callback();
						}			
					}
				});  
				
				$(el).bind('blur',function(e){  
					const input = $(this);
					const oldVal = input.data("prev");
					const newVal = $.trim(input.val());
					input.val(newVal);
					input.attr("value", newVal);
					if(newVal != null){
						if(newVal == "" || newVal == "-" || newVal == "-0" || newVal == "-0." || newVal == "0." || newVal == "0"){
							input.val(zeroValue); 
							input.attr("value", zeroValue);
							if(defProperties.callback !== undefined && defProperties.callback !== "") defProperties.callback();
						}else{
							if(!test.test(newVal)){
								input.val(oldVal); 
								input.attr("value", oldVal);
							}else if(defProperties.type==="decimal"){
								input.val(Number(newVal).toFixed(defProperties.decimals));
								input.attr("value", Number(newVal).toFixed(defProperties.decimals));
							}
						}			
					}
					if(defProperties.currency){				
						$(this).val(Ad74aUtils.valorFormatoMoneda($(this).val()));
						input.attr("value", Ad74aUtils.valorFormatoMoneda(input.attr("value")));
					}
				}); 
				
				$(el).bind('focus',function(e){  
					if(defProperties.currency){
						$(this).val(Ad74aUtils.deshacerValorFormatoMoneda($(this).val()));
					}
					const input = $(this);
					const oldVal = input.val();
					$(this).data("prev", oldVal);
					if(input.val() == zeroValue || input.val() == "0") {
						$(this).val("");
						input.attr("value", "");
					}
				});
			});
		}
	    
	}	
	
	const configCombo = function (item, properties) {
		const defaultProperties = {
		width: 'auto',
		ordered: true,
		rowStriping: true,
		customClasses: ['select-material']
		}
		
		item.rup_combo($.extend(properties, defaultProperties));
	}
	
	const changeDisabledByName = ( name, disable ) => {
        const els = document.getElementsByName(name);
        for (let i = 0, len = els.length; i<len; i++){
            els[i].disabled = disable;
        }
    }
	
	const openConfirmDialog = ( id, title, message, buttons, dialogClass ) => {
		if($(`div[aria-describedby=${id}]`).length == 1){
	    	$(`div[aria-describedby=${id}]`).remove();
	    	//$('#'+id).remove();
	    }
					
		$("#"+id+" label").html(message);
		
		$('#'+id).rup_dialog({
	        type: $.rup.dialog.DIV,
	        autoOpen: false,
	        modal: true,
	        resizable: false,
	        title: title,	    
	        height: 150,
			dialogClass: dialogClass || 'custom_small_dialog',
	        buttons: buttons,
	    });	
		
		$("#"+id).removeClass("custom_small_dialog custom_medium_dialog custom_full_dialog");
		$("#"+id).addClass(dialogClass || "custom_small_dialog");
		
		if(dialogClass != null && dialogClass.includes('rup-message')) {
			$(`div[aria-describedby=${id}] > .ui-dialog-titlebar`).removeClass('app-primary-color');
			$(`div[aria-describedby=${id}] > .ui-dialog-titlebar > a`).removeClass('text-white');
		}
		
		$('#'+id).rup_dialog('open');
	}
	/**
	 * 
	 */
	const validarCampoIdentificador = function (tipoIdentificador, identificador) {
		if(identificador != ''){
			 if (tipoIdentificador == '1' ){
				 return validarIdentificador(identificador);
			 }else if(tipoIdentificador == '2'){
				return validarCif(identificador);
			 }else if(tipoIdentificador == '3'){
				 return validarNIE(identificador);
			 }else if(tipoIdentificador == '4'){
				 return validarPasaporte(identificador);
			 }
			 else{
				 // Si no está definido el tipo no se puede validar
				 return false; 
			 }
		}else{
			return true;
		}
	}

	const esVacioUndefinedONull = function (input) {
		if(typeof input == 'undefined' || input == null || input == ''){
			return true;
		}else{
			return false;
		}
	}
	
	//Valida el NIE
	const validarNIE = function (input) {
		
		if(Ad74aUtils.esVacioUndefinedONull(input)){
			return true;
		}
		
		let nie = input.toUpperCase();
		// Change the initial letter for the corresponding number and validate as DNI
	    var nie_prefix = nie.charAt( 0 );

	    if (nie_prefix == 'X') {
	        nie_prefix = 0;
	    } else if (nie_prefix == 'Y') {
	        nie_prefix = 1;
	    } else if (nie_prefix == 'Z') {
	        nie_prefix = 2;
	    } else {
	        // Devolver false si no coincide con ninguna de las opciones
	        return false;
	    }

	    dni = nie_prefix + nie.substr(1);
	    
	    var dni_letters = "TRWAGMYFPDXBNJZSQVHLCKE";
	    var letter = dni_letters.charAt( parseInt( dni, 10 ) % 23 );
	    
	    return letter == dni.charAt(8);
	}
	//Valida el cif
	const validarCif = function (elCIF)  {
		
		if(Ad74aUtils.esVacioUndefinedONull(elCIF)){
			return true;
		}  
		
		var CIF_REGEX = /^([ABCDEFGHJKLMNPQRSUVW])(\d{7})([0-9A-J])$/;
		
		var cif = elCIF.toUpperCase(); // pasar a mayúsculas
		
		var match = cif.match( CIF_REGEX );
		if(Ad74aUtils.esVacioUndefinedONull(match) || match.length != 4){
			return false;
		}
		var letter  = match[1],
		    number  = match[2],
		    control = match[3];
		
		var even_sum = 0;
		var odd_sum = 0;
		var n;
		
		for ( var i = 0; i < number.length; i++) {
		  n = parseInt( number[i], 10 );
		
		  // Odd positions (Even index equals to odd position. i=0 equals first position)
		  if ( i % 2 === 0 ) {
		    // Odd positions are multiplied first.
		    n *= 2;
		
		    // If the multiplication is bigger than 10 we need to adjust
		    odd_sum += n < 10 ? n : n - 9;
		
		  // Even positions
		  // Just sum them
		  } else {
		    even_sum += n;
		  }
		
		}
		
		//var control_digit = (10 - (even_sum + odd_sum).toString().substr(-1) );
		var control_digit = (even_sum + odd_sum) % 10;
		if(control_digit !== 0) {
			control_digit = 10 - control_digit;
		}
		
		var control_letter = 'JABCDEFGHI'.substr( control_digit, 1 );
		
		// Control must be a digit
		if ( letter.match( /[ABEH]/ ) ) {
		  return control == control_digit;
		
		// Control must be a letter
		} else if ( letter.match( /[KPQS]/ ) ) {
		  return control == control_letter;
		
		// Can be either
		} else {
		  return control == control_digit || control == control_letter;
		}
	}
	
	//Valida el DNI
	const validarIdentificador = function (input) {
		
		if(Ad74aUtils.esVacioUndefinedONull(input)){
			return true;
		}  

		let identificador = input.toUpperCase();
		
		
		// Array de letras  permitidas DNI NIE
		let letras = 'TRWAGMYFPDXBNJZSQVHLCKE';
		let DNI_REGEX = /^([0-9]{8})([A-HJ-NP-TV-Z])$/;
		
		if (DNI_REGEX.test(identificador)) {

			// Extraer el número del DNI 
			var numero = identificador.substring(0, 8);

			// Extraer la letra y convertirla a mayúsculas
			var letraControl = identificador.charAt(8).toUpperCase();

			// Calcular la letra esperada
			var indice = parseInt(numero) % 23;

			// Verificar si la letra coincide con la esperada
			if (letraControl === letras.charAt(indice)) {
				console.log("validarIdentificador -- Valido");
				return  true; // DNI válido
			} else {
				console.log("validarIdentificador -- Erroneo");
				return false; // DNI no válido
			}
		}else{
			console.log("validarIdentificador -- Erroneo");
			return  false; // El formato no es válido				
		}
	}

	const empieceComprobarCP = function (cp,input) {
		if(cp.length <=2){
			if(cp.length == 1){
				console.log("entro en length == 1");
				if(cp != 0 && cp != 2 && cp != 4){
					console.log("entro en el if para dejar vacio con un numero");
					$('#'+input).val('');
				}
			}else{
				if(cp != 01 && cp != 20 && cp != 48){
					$('#'+input).val(cp.charAt(0));
				}
			}
		}		 
	}
	
	// valida el IBAN
	const validarIBAN = function(IBAN) {

	    // Se pasa a Mayusculas
	    IBAN = IBAN.toUpperCase();
	    // Se quita los blancos de principio y final.
	    IBAN = IBAN.trim();
	    IBAN = IBAN.replace(/\s/g, ""); // Y se quita los espacios en blanco
										// dentro de la cadena

	    var letra1,letra2,num1,num2;
	    var isbanaux;
	    var numeroSustitucion;
	    // La longitud debe ser siempre de 24 caracteres
	    if (IBAN.length != 24) {
	        return false;
	    }

	    // Se coge las primeras dos letras y se pasan a números
	    letra1 = IBAN.substring(0, 1);
	    letra2 = IBAN.substring(1, 2);
	    num1 = getnumIBAN(letra1);
	    num2 = getnumIBAN(letra2);
	    // Se sustituye las letras por números.
	    isbanaux = String(num1) + String(num2) + IBAN.substring(2);
	    // Se mueve los 6 primeros caracteres al final de la cadena.
	    isbanaux = isbanaux.substring(6) + isbanaux.substring(0,6);

	    // Se calcula el resto, llamando a la función modulo97, definida más
		// abajo
	    resto = modulo97(isbanaux);
	    if (resto == 1){
	        return true;
	    }
	        return false;
	    
	}

	function modulo97(iban) {
	    var parts = Math.ceil(iban.length/7);
	    var remainer = "";

	    for (var i = 1; i <= parts; i++) {
	        remainer = String(parseFloat(remainer+iban.substr((i-1)*7, 7))%97);
	    }

	    return remainer;
	}

	function getnumIBAN(letra) {
	    ls_letras = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
	    return ls_letras.search(letra) + 10;
	}
	
	/*
	 * Metodo para establecer el valor por defecto en los inputs de un formulario (control para los rup_combos).
	 * Si se utiliza el metodo establecerComoValoresPorDefecto se seteara correctamente el valor para los combos (se carga el valor "defaultValue").
	 * Opcionalmente se le puede pasar 
	 * 
	*/
	const resetFormulario = function (formId,feedback) {
		//hacemos reset del formulario y refresh de los combos para actualizarlos porque sino no se muestra correctamente los combos.
		$('#'+ formId).rup_form("resetForm");
		$('#'+ formId +' .rup_combo').each(function( index ) {
			try{
				 $(this).rup_combo("setRupValue" , document.getElementById(this.id).valorPorDefecto) ;	
			}catch{}
			
		});		
		$('#'+ formId +' .rup_combo').rup_combo("refresh");
	}
	const establecerComoValoresPorDefecto = function (formId) {
		
			let aData =  $.rup_utils.jsontoarray($("#"+formId).rup_form("formToJson")) ;
			for (let i in aData) {
				let formElem = $( "#" + formId + ' [name=\'' + i + '\']' );
				if (formElem.length == 0) {
					selectorArray = i.substr(0, i.indexOf('['));
					formElem = $( "#" + formId +'[name=\'' + selectorArray + '\']');
				}
				if( !( formElem.is('input:radio') || formElem.is('input:checkbox') || formElem.is('select')  ) ){
					formElem.prop("defaultValue", aData[i]);
					formElem.attr("value", aData[i]);
				}
				
			}	
			//Para los combos
			$('#'+formId+' .rup_combo').each(function( index ) {
				try{
					document.getElementById(this.id).valorPorDefecto =  $(this).rup_combo("getRupValue");	
				}catch{}
				
			});		
			
			//Para los radios
			$('#'+formId+' .radioButton:checked').each(function( index ) {
				document.getElementById(this.id).defaultChecked = true;
			});
			$('#'+formId+' .radioButton:not(:checked)').each(function( index ) {
				document.getElementById(this.id).defaultChecked = false;
			});
			
			//Para los checkBox
			$('#'+formId+' input:checkbox:checked').each(function( index ) {
				document.getElementById(this.id).defaultChecked = true;
			});
			$('#'+formId+' input:checkbox:not(:checked)').each(function( index ) {
				document.getElementById(this.id).defaultChecked = false;
			});
	}
	const FN_controlMaxDni = function (tipo,identificador)  {
		if(tipo.val() == '1' || tipo.val() == '2'){
			identificador.attr('maxlength',9);
		}else if(tipo.val() == '3'){
			identificador.attr('maxlength',10);
		}else{
			identificador.attr('maxlength',15);
		}
	}
	const FN_validacionIdentificador = function(tipo,identificador) {
		tipo.parent().removeClass("rup-validate-field-error");
		identificador.parent().removeClass("rup-validate-field-error");
		tipo.removeClass("error");
		identificador.removeClass("error");
		tipo.parent().find('.error').remove();
		identificador.parent().find('.error').remove();
		
		let valueTipo = tipo.val();
		let valueIdentificador = identificador.val();
		let padreTipo = tipo.parent();
		let padreIdentificador = identificador.parent();
		if (valueTipo == '' || valueTipo == null ){
			tipo.parent().addClass('rup-validate-field-error');
			tipo.addClass('error');
			tipo.parent().append(`<span for="${tipo.attr('id')}" generated="true" class="error" >${$.rup.i18n.app.errores.errorTipoIdentificador}</span>`);
		}else{
			if(valueIdentificador != null || valueIdentificador != ''){
				let resultado = validarCampoIdentificador(valueTipo,valueIdentificador);
				if (!resultado){
					identificador.parent().addClass('rup-validate-field-error');
					identificador.addClass('error');
					identificador.after(`<span for="${identificador.attr('id')}" generated="true" class="error" >${$.rup.i18n.app.errores.errorIdentificadorErroneo}</span>`);
				}
			}else{
				identificador.parent().addClass('rup-validate-field-error');
				identificador.addClass('error');
				identificador.after(`<span for="${identificador.attr('id')}" generated="true" class="error" >${$.rup.i18n.app.errores.errorIdentificadorVacio}</span>`);
			}
		}
		
	}
	const FN_bloquearInputsFormulario  = (idFormulario) => {
		$("#"+idFormulario +" input,#"+idFormulario + " textarea").prop("disabled",true);  
		$("#"+idFormulario +" .rup_combo").rup_combo('disable');
		$("#"+idFormulario +" [ruptype='date']").rup_date("disable");
		$("#"+idFormulario +" .radioButton ").prop( "disabled", true );
			
	}
	const FN_desBloquearInputsFormulario = (idFormulario) => {
		
		$("#"+idFormulario +" input,#"+idFormulario + " textarea").prop("disabled",false);  
		try{
			$("#"+idFormulario +" .rup_combo").rup_combo('enable');
		} catch{
			console.log("Error al habilitar los combo")
		}
		$("#"+idFormulario +" [ruptype='date']").rup_date("enable");
		$("#"+idFormulario +" .radioButton ").prop( "disabled", false );
			
	}
	
	/*Función que inicia timer para un elemento*/
	const timer = (selector, properties) => {
		
		let timer;
		
		const initRefreshTimer = (selector, properties) => {
			
			let defProperties = {
				"init": "false", // indica si hay que reiniciar intervalo
				"callback": () => {}, // función a ejecutar 
				"style": {}, // estilos para la barra de progreso --height, --background
				"refreshInterval": "30", //segundos
				"click": true, // indica si añadir evento click con el callback
				"currentTimer": 0 // pasar parámetro del contador (no definir en llamada)
			}		
			$.extend(true, defProperties, properties);
			
			let currentTimer = defProperties.currentTimer;
			
			if(selector != "" || $(selector)) {			
				$(selector).addClass("progressButton");
				
				Object.entries(defProperties.style).forEach(([key, value]) => {
					$(selector+'.progressButton').css("--"+key, value);
				});
				
				if(defProperties.init) {
					clearTimeout(timer);
					currentTimer = 0;
					properties.init = false;
					$(selector+'.progressButton').css('--progressPercent', '0%');
				}				
				
				timer = setTimeout( () => {
//					console.log(currentTimer);
					currentTimer++;			
					$(selector+'.progressButton').css('--progressPercent', ((currentTimer*100)/defProperties.refreshInterval) + '%');
					if( currentTimer >= defProperties.refreshInterval){				
						defProperties.callback();
						currentTimer = 0;
						$(selector+'.progressButton').css('--progressPercent', '0%');
					}
					properties.init = false;
					properties.currentTimer = currentTimer; 
					timer = initRefreshTimer(selector, properties);
				}, 1000);
				
				if(defProperties.click) {
//					console.log("##3");
					$(selector).unbind("click.progressButton");
					$(selector).bind("click.progressButton", () => {
						currentTimer = 0;
						defProperties.callback();
					});
				}
			}
		}
		
		timer = initRefreshTimer(selector, properties);
	}
	
	const validarPasaporte = (pasaporte) =>{
		
		    const patronPasaporte = /^[A-Za-z0-9]{9}$/;

		    return patronPasaporte.test(pasaporte);
		
	}
	
	const limpiarErroresValidacionEnFormulario = (formularioId) =>{
		
		   $("#" + formularioId).find('.error').not('input, textarea').remove();
		   $("#" + formularioId).find('input.error, textarea.error').removeClass("error") ;
		   $("#" + formularioId).find('.rup-validate-field-error').removeClass('rup-validate-field-error');
	
	}
	
	/*
	 * [jbhg]
	 * Funcion para descargar ficheros mediante ajax. A este metodo se le puede indicar las mismas propiedades que al metodo $.ajax.
	 * Lo mínimo indispensable que hay que informar, es la propiedad 'url':
	 * {
	 * 		url: 'http://...',
	 * 		fileName: 'nombre_de_fichero.pdf',
	 * 		...
	 * }
	 * 
	 * 
	 */
	const fileDownload = (properties) => {
		//Preparacion de las propiedades de la llamada ajax
		let successFnc = function(data, textStatus, request){
        	//Establecer el nombre del fichero a descargar:
    		let fileName = 'descarga';
        	if(properties.fileName){
        		//1)primero se comprueba si se ha indicado la propiedad fileName
        		fileName = properties.fileName;
        	}else if(request.getResponseHeader('filename')){
        		//2)Se comprueba cabecera 'filename'
        		fileName = request.getResponseHeader('filename');
        	}else if(request.getResponseHeader('Content-Disposition') && request.getResponseHeader('Content-Disposition').toLowerCase().indexOf('filename')>=0){
        		//3)Se comprueba cabecera 'content-disposition'
        		let arr = request.getResponseHeader('Content-Disposition').split(';');
        		for(let i=0; i < arr.length;i++){
        			if(arr[i].toLowerCase().indexOf('filename')>=0){
        				fileName=arr[i].split('=')[1].trim();
        			}
        		}
        	}
        	
            var a = document.createElement('a');
            var url = window.URL.createObjectURL(data);
            a.href = url;
            a.download = fileName;
            document.body.append(a);
            a.click();
            a.remove();
            window.URL.revokeObjectURL(url);
        };
        if(properties.success){
        	//Si se ha definido la funcion de success, se ejecuta despues de la de este componente
        	let userSuccessFnc = properties.success;
        	properties.success = function(data, textStatus, request){
        		successFnc.call(properties, data, textStatus, request);
        		userSuccessFnc.call(properties, data, textStatus, request);
        	}
        }else{
        	properties.success = successFnc;
        }
		const finalProps = $.extend(true,{
			//url: 'http....'
			method: 'GET',
	        xhrFields: {
	            responseType: 'blob'
	        }
	        
		},properties);
		// Llamada a la descarga del fichero		
		return $.ajax(finalProps);
	}
	
	const valorFormatoMiles = (num) =>{
		if( num != undefined && num!= null){
			return Number(num).toLocaleString('es', { });
		}else{
			return Number('').toLocaleString('es', {  });
		}
					
	};
	
	const pintarAvisoInteroperabilidad = (id, clase, mensaje) => {
		const avisoElem = document.getElementById(id);
		avisoElem.classList.remove("ok", "warning", "nook");
		$("#"+id).addClass(clase);
		$("#"+id+" b").html(mensaje)
	}
	
return { // Public vbles and methods
		allowedOrigins,
		cerrarFeedbacks,
		bloquearInterfaz,
		desBloquearInterfaz,
		sortObject,
		soloNumericos,
		validarTelefono,
		monedaSpan,
		formatoMoneda,
		deshacerFormatoMoneda,
		valorFormatoMoneda,
		deshacerValorFormatoMoneda,
		refreshViewFood,
		hacerPlegable,
		deshabilitarBotones,
		validarUrl,
		number,
		configCombo,
		changeDisabledByName,
		openConfirmDialog,
		validarCampoIdentificador,
		empieceComprobarCP,
		resetFormulario,
		establecerComoValoresPorDefecto,
		esVacioUndefinedONull,
		FN_controlMaxDni,
		FN_validacionIdentificador,
		FN_bloquearInputsFormulario,
		FN_desBloquearInputsFormulario,
		timer,
		validarIBAN,
		validarPasaporte,
		fileDownload,
		sinEspacios,
		limpiarErroresValidacionEnFormulario,
		valorFormatoMiles,
		pintarAvisoInteroperabilidad
    }
})();