	/*
	userInterface uServers 
	*/
	
	// $URBANO_VERSION = "2.490";
	function userInterface(id) {
		this.ID = id;
		this.Error = false;
		this.Error_History = Array();
		return this;
	}
	
	userInterface.prototype.setError = function(error) {
		if(this.Error) { this.Error_History.push(this.Error); }
		this.Error = error;
		return false;
	}

	// Este lo hice asi porque el nombre ya sobraba:
	userInterface.prototype.fadeIn = function(element) {
		return this.usvx_fadeIn(element);		
	}
	
	userInterface.prototype.usvx_fadeIn = function (element) {
		element.uOpacity = 0;
		this.usvx_faderApplyValue(element);
		element.style.display = "block";
		this.usvx_fadeInLoop(element.id);					
		
	}
				
	userInterface.prototype.usvx_fadeInLoop = function (element_id) {
	   var element = document.getElementById(element_id);
	   var este;
	   este = this;
	   if(element.uOpacity == 100) { return; }
	   		element.uOpacity = element.uOpacity + 10;
			this.usvx_faderApplyValue(element);
			
			element.usvx_faderTimer = window.setTimeout(function() { este.usvx_fadeInLoop(element_id);}, 60);
			//element.usvx_faderTimer = window.setTimeout(this.ID+".usvx_fadeInLoop(\'"+element_id+"\')", 60);
	}
				                                 
	// Este lo hice asi porque el nombre ya sobraba:
	userInterface.prototype.fadeOut = function(element) {
		return this.usvx_fadeOut(element);		
	}
	
	userInterface.prototype.usvx_fadeOut = function (element) {
		element.uOpacity = 80;
		this.usvx_faderApplyValue(element);
		// element.style.display = "block";
		this.usvx_fadeOutLoop(element.id);					
		
	}
				
	userInterface.prototype.usvx_fadeOutLoop = function (element_id) {
	   var element = document.getElementById(element_id);
	   var este;
	   este = this;
	   if(element.uOpacity <= 0) { document.getElementById(element_id).style.display = 'none'; return; }
	   
	   element.uOpacity = element.uOpacity - 20;
	   this.usvx_faderApplyValue(element);
	   
	   element.usvx_faderTimer = window.setTimeout(function() { este.usvx_fadeOutLoop(element_id);}, 60);
	   
	}
   	
	userInterface.prototype.usvx_faderApplyValue = function(element) {
		
		if(element.style.opacity != undefined) {
				element.style.opacity = element.uOpacity / 100;
		} else {
			 //element.style.filters.item(0).Opacity = "alpha(opacity="+element.uOpacity+")";
			//element.filters.item("DXImageTransform.Microsoft.Alpha").Opacity = element.uOpacity;
			element.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity = uOpacity)";
			//filter:progid:DXImageTransform.Microsoft.Alpha(opacity = 50);
			//element.style.filter.item(0).Opacity = element.uOpacity;
		}
		// -moz-opacity:0.35;
	}
	
	userInterface.prototype.findPos = function(obj) {
		// Calcula la posicion de un elemento tomando en cunta elementos posicionados, 
		// y contenidos escroleados. Probado en FF, IE, OP, KQ
		var curleft = curtop = 0;
		var scrollX = scrollY = 0;	// Contador de escroleados
		var tObj = obj.parentNode;
		while(tObj.parentNode) {
			
			if(! window.opera ) {
				if(tObj.scrollTop != 0)		{ scrollY = scrollY + tObj.scrollTop; }
				if(tObj.scrollLeft != 0)	{ scrollX = scrollX + tObj.scrollLeft; }
				
			} else {
				// Funcion aprendida de:
				// http://dev.rubyonrails.org/ticket/7466
				//if(tObj.scrollTop != 0)		{ alert("ID: " + tObj.id+ " Top: " + tObj.scrollTop + " offset: " + tObj.offsetTop); }
				var vT = tObj.scrollTop		|| 0;
				var vL = tObj.scrollLeft	|| 0;
				
				scrollX = vT - tObj.offsetTop	|| 0;
				scrollY = vL - tObj.offsetLeft	|| 0;
				
			}
			tObj = tObj.parentNode;
		}
		
		if (obj.offsetParent) {
			curleft	= obj.offsetLeft
			curtop	= obj.offsetTop
			
			// Checa si esta escroleado:
			// if(obj.parentNode.scrollTop) { scroll = obj.parentNode.scrollTop curtop -= scroll }
			while (obj = obj.offsetParent) {
				
				curleft	+= obj.offsetLeft
				curtop	+= obj.offsetTop
				// alert(obj.id + " tag: " + obj.tagName);
			}
			
		}
		curleft	= curleft - scrollX;
		curtop	= curtop - scrollY;
		//suma lo que no se ve de arriba
		if(document.documentElement.scrollTop) { curtop = (curtop + document.documentElement.scrollTop); }
		else if(window.pageYOffset) { curtop = (curtop + window.pageYOffset); }
		
		return [curleft,curtop];
	}
	
	userInterface.prototype.bodySize = function(completo) {
		// #uDOC:TITLE bodySize
		// #uDOC:DESCR Regresa el alto y ancho del body en un array
		
		return [this.bodyWidth(completo),this.bodyHeight(completo)];	
	}
	
	userInterface.prototype.bodyHeight = function(completo) {
		// #uDOC:TITLE bodyHeight
		// #uDOC:DESCR Regresa la altura en pixeles del body
		
		// Si completo esta definido entonces significa sacar todo el body, 
		// hasta lo que no se ve, si no solo lo visible
		if(completo == undefined) { completo = false; }
		
		// Solo el alto de lo visible:
		if(completo == false) {
			if( typeof( window.innerHeight ) == 'number' ) {
				return window.innerHeight;
			} else if( document.documentElement && document.documentElement.clientHeight ) {
				return document.documentElement.clientHeight;
			} else if( document.body && document.body.clientHeight ) {
				return document.body.clientHeight;
			}
			
		// El alto de hasta lo que no se ve:
		} else {
			// FIXME: Hay que probar esto
			if(document.body.scrollHeight) {
				var visible = this.bodyHeight(false); 
				if(visible > document.body.scrollHeight) {
					return visible;
				} else {
					return document.body.scrollHeight;
				}
			} else {
				// Bummer
				// alert("No se como");
			}
		}
		
	}
	
	userInterface.prototype.bodyWidth = function(completo) {
		// #uDOC:TITLE bodyWidth
		// #uDOC:DESCR Regresa el ancho del body en pixeles
		// Si completo esta definido entonces significa sacar todo el body, 
		// hasta lo que no se ve, si no solo lo visible
		if(completo == undefined) { completo = false; }
		
		// Solo el ancho de lo visible:
		if(completo == false) {
			if( typeof( window.innerWidth ) == 'number' ) {
				return window.innerWidth;
			} else if( document.documentElement && document.documentElement.clientWidth ) {
				return document.documentElement.clientWidth;
			} else if( document.body && document.body.clientWidth ) {
				return document.body.clientWidth;
			}
		
		// El ancho de hasta lo que no se ve:
		} else {
			// FIXME: Hay que probar esto con mor browsers:
			/*esto lo quite porque siemrpe hay scrollWidth*/
			/*if(document.body.scrollWidth) {
				var visible = this.bodyWidth(false); 
				if(visible > document.body.scrollWidth) {
					return visible;
				} else {
					return document.body.scrollWidth;
				}
			} else {
				// Bummer
			}*/
			return document.body.scrollWidth;  
			
		}
		
	}
	
	userInterface.prototype.getScrollXY = function() {
		var scrOfX = 0, scrOfY = 0;
		if( typeof( window.pageYOffset ) == 'number' ) {
			//FireFox
			scrOfY = window.pageYOffset;
			scrOfX = window.pageXOffset;
		} else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
			//DOM 
			scrOfY = document.body.scrollTop;
			scrOfX = document.body.scrollLeft;
		} else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
			//IE6 
			scrOfY = document.documentElement.scrollTop;
			scrOfX = document.documentElement.scrollLeft;
		}
		return [ scrOfX, scrOfY ];
	}
	
	userInterface.prototype.addEventHandler = function(elemento, evento, manejeitor) {
		//# uDOC:TITLE addEventHandler
		//# uDOC:DESCR Agrega un event handler a un elemento
		
		if(elemento.addEventListener) {
			return elemento.addEventListener(evento, manejeitor, false);
		} else if(elemento.attachEvent) {
			return elemento.attachEvent("on"+evento, manejeitor);
		} else {
			return false;
		}
	}
	
	userInterface.prototype.removeEventHandler = function(elemento, evento, manejeitor) {
		//# uDOC:TITLE addEventHandler
		//# uDOC:DESCR Quita un event handler a un elemento
		
		if(elemento.removeEventListener) {
			return elemento.removeEventListener(evento, manejeitor, false);
		} else if(elemento.detachEvent) {
			return elemento.detachEvent("on"+evento, manejeitor);
		} else {
			return false;
		}
	}
	
	userInterface.prototype.createEvtHandler = function(objeto, handler, target) {
		return  (function(e) {
			e = e||window.event;
			if(target) {
				objeto[handler](e, target);
			} else {
				// alert(1);
				objeto[handler](e);
			}
		});
	}
	
	// Obscurece pantalla
	userInterface.prototype.shadeBody = function(color_triplet){
		
		if(! document.getElementById("usvx_screen")) {
			var div = document.createElement("div");
			div.id = "usvx_screen";
			div.className = "usvx_screen";
			document.body.appendChild(div);
		}
		
		//document.getElementById("usvx_screen").style.height	= this.bodyHeight(true) + "px";
		//document.getElementById("usvx_screen").style.width		= this.bodyWidth(true) + "px";
		document.getElementById("usvx_screen").style.height	= 5000 + "px";
		document.getElementById("usvx_screen").style.width		= 5000 + "px";
		
		
		if(color_triplet != undefined) {
			document.getElementById("usvx_screen").style.backgroundColor = color_triplet;
		} else {
			document.getElementById("usvx_screen").style.backgroundColor = "#cc9";
		}
		document.getElementById("usvx_screen").style.display	= "block";
		
		
		// Esconde las scrollbars del body:
		document.documentElement.style.overflow = 'hidden';
		
		// Si es IE6 hay que esconder todos los selects del documento
		// por que si no salen sobre la cortinilla:
		if(this.esIE(6)) {
			var selectos = document.getElementsByTagName("select");
			if(selectos) {
				var i;
				for(i=0; i<selectos.length; i++) {
					if(selectos.item(i).style.visibility) {
						selectos.item(i).USVX_preShadeV = selectos.item(i).style.visibility; 
					}
					selectos.item(i).style.visibility = "hidden";
				}
			}
		}
		
		/* Para firefox < 2:  -moz-opacity:0.10;*/
	}
	
	userInterface.prototype.esIE = function(qversion) {
		
		// Si no hay ActiveXObject regresa false ya:
		if(! window.ActiveXObject) { return false; }
		
		// Si no hay version ya seguro es IE, regresa:
		if(qversion == undefined) { return true; }
		
		// Si hay XMLHttpRequest, entonces es 7:
		if(qversion == 7) { if(window.XMLHttpRequest) { return true; } else { return false; } }
		
		// Ya para motivos practicos siempre regresa 
		// 7 y "todo lo demas" en vez de andar buscando:
		if(qversion != 7) { if(window.XMLHttpRequest) { return false; } else { return true; } }
		
	}
	
	userInterface.prototype.unshadeBody = function() {
		if(document.getElementById("usvx_screen").dialogElement) {
			document.getElementById("usvx_screen").dialogElement.style.display = "none";
			document.getElementById("usvx_screen").dialogElement = null;
		}
		if(this.esIE(6)) {
			var selectos = document.getElementsByTagName("select");
			if(selectos) {
				var i;
				for(i=0; i<selectos.length; i++) {
					if(selectos.item(i).USVX_preShadeV) {
						selectos.item(i).style.visibility = selectos.item(i).USVX_preShadeV;
					} else {
						selectos.item(i).style.visibility = "visible";
					}
				}
			}
		}
		
		document.documentElement.style.overflow = 'auto';
		document.getElementById("usvx_screen").style.display = "none";
	}
	
	userInterface.prototype.unShadeBody = function() {
		// this alerta(func deprecada)
		return this.unshadeBody();
	}
	
	userInterface.prototype.centerElement = function(element, container) {
		if(container != undefined) {
			
			var ancho	= container.offsetWidth;
			var alto	= container.offsetHeight;
			
			var anchoEL;
			var altoEL;
			if(element.tagName == "IMG") {
				anchoEL = element.width;
				altoEL = element.height;
			} else {
				anchoEL = element.offsetWidth;
				altoEL = element.offsetHeight;
			}
			element.style.position = "absolute";
			element.style.marginLeft = (ancho/2) - (anchoEL/2) +"px"; 
			element.style.marginTop = (alto/2) - (altoEL/2) + "px";
		} else {
			// Posiciona un elemento absoluto y centralo en la pantalla:
			element.style.position = "absolute";
			
			// si hay que agregar una cosa, agregala aqui:
			var escroleado = 0;
			if(document.documentElement) {
				if(document.documentElement.scrollTop) { escroleado = document.documentElement.scrollTop; }
				else if(window.pageYOffset) { escroleado = window.pageYOffset; }
			}
			
			element.style.top = (parseInt((this.bodyHeight(false) / 2) - (element.offsetHeight / 2)) + escroleado) + "px";
			// alert(parseInt((this.bodyHeight(false) / 2) - (element.offsetHeight / 2)));
			element.style.left = parseInt((this.bodyWidth(false) / 2) - (element.offsetWidth / 2)) + "px";
			
			// alert(parseInt((this.bodyWidth(false) / 2) - (element.offsetWidth / 2)) + "px");
			//alert(this.bodyWidth(true));
		}
	}
	
	userInterface.prototype.showAsDialog = function(element, bgcolor) {
		
		this.shadeBody(bgcolor);
		element.style.zIndex	= "100";
		// Aqui meti este visibility hidden para que no camine:
		element.style.visibility = "hidden";
		element.style.display	= "block";
		
		if(document.getElementById("usvx_screen").dialogElement) {
			if(document.getElementById("usvx_screen").dialogElement.id != element.id) {
				document.getElementById("usvx_screen").dialogElement.style.display = "none";
			}
		}
		
		document.body.appendChild(element);
		this.centerElement(element);
		document.getElementById("usvx_screen").dialogElement = element;
		
		
		// Aqui reinstauramos la visibility para que salga
		element.style.visibility = "visible";
	}
	
	// Cuadro de dialogo
	userInterface.prototype.dialog = function(element){
		element.style.display = "block";
		
	}
	
	
	/* Errores de elementos: **/
	userInterface.prototype.showElementError = function(id, titulo, mensaje, extras) {
			
		if(this.lastElementMessageID) {
			this.clearElementError(this.lastElementMessageID);
		}
		
		var elemento = document.getElementById(id);
		
		// Checa si el elemento destino existe:
		if(! elemento) { return false; }
		
		if(! elemento.elementErrorBox) {
			// Crea aqui
			elemento.elementErrorBox = document.createElement("div");
			elemento.elementErrorBox.className = "uui_elmsg";
			document.body.appendChild(elemento.elementErrorBox);
		}
		
		// Guarda los estilos para restaurar mas tarde (bug#683):
		
		// Checa si hay getComputedStyle:
		if(document.getElementById(id).currentStyle) {
			elemento.USVX_preElErrorColor	= document.getElementById(id).currentStyle.color;
			elemento.USVX_preElErrorBGColor	= document.getElementById(id).currentStyle.backgroundColor;
		} else if(window.getComputedStyle) {
			var estilo = window.getComputedStyle(elemento, null);
			if(estilo) {
				elemento.USVX_preElErrorColor		= estilo.color;
				elemento.USVX_preElErrorBGColor	= estilo.backgroundColor;
			}
		
		// Si no, de plano asi con el style:
		} else {
		
			if(elemento.style.color) { elemento.USVX_preElErrorColor = elemento.style.border; }
			if(elemento.style.backgroundColor) { elemento.USVX_preElErrorBGColor = elemento.style.backgroundColor; }
		}
		
		// document.getElementById(id).style.border = "#c33 1px solid";
		elemento.style.backgroundColor = "#d66";
		elemento.style.color = "#f8f8f8";
		
		// Pon los datos:
		elemento.elementErrorBox.innerHTML = "<h3>"+titulo+"</h3><p>"+mensaje + "</p>";
		elemento.elementErrorBox.style.display = "block";
		
		// Pon la posicion del dialogo:
		var coords = this.findPos(elemento);
		var leftpos = ((coords[0] + 310) - this.bodyWidth());
		
		if(leftpos >= 0) {
			//alert(((coords[0] + 300) - this.bodyWidth(true)));
			elemento.elementErrorBox.style.left = (coords[0]-leftpos) + "px";
		} else {
			elemento.elementErrorBox.style.left = coords[0] + "px";
		}
		
		// Fija el top:
		elemento.elementErrorBox.style.top = (coords[1] + elemento.offsetHeight + 5) + "px";
		
		// Fija el timer:
		elemento.taimer = window.setTimeout(this.ID + ".clearElementError(\'"+id+"\')", 3500);
		
		
		// Esto lo comente porque esta haciendo loops en algunas cosas 
		// Pasa el focus al elemento que tuvo el error:
		// if(elemento.focus) { elemento.focus(); }
		
		// Acuerdate cual fue el ultimo para que nomas salga 1:
		this.lastElementMessageID = id;
		
	}
	
	userInterface.prototype.clearElementError = function(id) {
		
		var elemento = document.getElementById(id);
		if(! elemento) { return false; }
		
		if(elemento.elementErrorBox) {
			elemento.elementErrorBox.style.display = "none";
			
			// Restaura los styles:
			if(elemento.USVX_preElErrorBGColor) { 
				elemento.style.backgroundColor = elemento.USVX_preElErrorBGColor;
			} else {
				elemento.style.backgroundColor = "";
			}
			
			if(elemento.USVX_preElErrorColor) {
				elemento.style.color = elemento.USVX_preElErrorColor;
			} else {
				elemento.style.border = '';
			}
		}
		
		return true;
		
	}
	
	
	

