if(!window.Consulte){
	window.Consulte = {

		scheduleWindow: null,		
		LBEmail: null,
		lastValidatedCep: "",
		$error: new Error("Validation Error"),
			
		defaultOptions:{
			returnBoolean: false,
			showErrorMessage: true,
			focus: true,
			showInfoMessage: true
		},
		
		getOptions: function(options){
			return Object.extend(Object.clone(this.defaultOptions), options || {});
		},
		
		link: function(url){
			location.href = url;
		},
		
		enableGlossary: function(){
			this.loadPrompt("glossary");
		},
		
		hideContentRight: function(){
			if($("content_right"))
				$("content_right").hide();
			else
				Event.observe(window, "load", this.hideContentRight.bind(this));
		},
		
		showContentRight: function(){
			if($("content_right"))
				$("content_right").show();
			else
				Event.observe(window, "load", this.showContentRight.bind(this));
		},

		loadBanner: function(source){
			//FIXME: carrega banner aleatório...
			this.loadPrompt($("banner").cloneNode(true));
		},
		
		clearPrompt: function(){
			if($("prompt")){
				$("prompt").hide();
				this.loadPrompt(null);
			}else Event.observe(window, "load", this.clearPrompt.bind(this));
		},

		loadPrompt: function(source){
			var source = $(source);
			var prompt = $("prompt");
			
			if(prompt){
				prompt.innerHTML = "";
				if(source){
					prompt.appendChild(source);
					source.show();
					prompt.show();
				}
			}else{
				Event.observe(window, "load", this.loadPrompt.bind(this, source));
			}
		},
		
		showEmailForm: function(){
     		this.LBEmail = new LightBox($("emailId").innerHTML, {title:Bundle.getMessage("txt.send.to.email").capitalize(), position:"top"});
			this.LBEmail.show();
			$("EmailForm.from").focus();
		},
		
		getContentEmail: function(subject, content, cssFile){
			if(content == null){
				content = "content";
			}
			if(cssFile == null){
				cssFile = contextPath + "/print.css";
			}
			$("detailFrame").contentWindow.init();
			
			var inside = $("detailFrame").contentWindow.document.getElementById(content).innerHTML;
			if($("detailFrame").contentWindow.document.getElementById("footer")){
				inside += $("detailFrame").contentWindow.document.getElementById("footer").innerHTML;
			}
			
			return {
				content: inside,
				subject: subject,
				css: "" /*cssFile*/
			};
		},		
		
		cancelEmail: function(){
			this.LBEmail.close();
		},
		
		sendEmail: function(callBack){
			if(this.validateSendEmailMandatoryFields()){
				Processing.show();
				window.setTimeout(function(){
					var map = eval(callBack);
					new Ajax.Request(window.contextPath+"/sendMail.action", {
						parameters:{
							content: map.content,
							css: map.css,
							from: $("EmailForm.from").value,
							to: $("EmailForm.to").value,
							subject: map.subject,
							message: $("EmailForm.message").value
						},
						onComplete: function(response){
							if(!this.hasError(response)){
								this.cancelEmail();
							}
						}.bind(this)
					});
				}.bind(this), 300);
			}
		},
		
		getLocaleDate: function(){
			var localeDate = new Date().toLocaleDateString();
			localeDate = localeDate.substring(0, 1).toUpperCase() + localeDate.substring(1);
			$("localeDate").innerHTML = localeDate;
		},

		calculateAge: function(birhdate){
			var today = new Date();
			var birthdate = Date.parse_DDMMYYYY(birhdate);

			if(birthdate != null && today.getTime() > birthdate.getTime()){
				var years = today.getFullYear() - birthdate.getFullYear();

				// Seta o ano corrente:
				birthdate.setFullYear(today.getFullYear());
				if(today.getTime() < birthdate.getTime()){
					// Não fez aniversário esse ano ainda:
					years--;
				}

				return years;
			}

			return null;
		},

		getRadioValue: function(name, _rootElement){
			var radio = this.getRadios(name, _rootElement).detect(function(r){ return r.checked; });
			return (radio!=null) ? radio.value : null;	
		},

		setRadioValue: function(name, value, _rootElement){
			var radio = this.getRadios(name, _rootElement).detect(function(r){ return String(r.value) == String(value); });
			if(radio != null){
				radio.checked = true;
			}
		},

		getRadios: function(name, _rootElement){
			return Selector.findChildElements($(_rootElement)||document, ["input[type=radio]"]).select(function(radio){
				return radio.name == name;
			});
		},

		bindAutocomplete: function(options){
			var field = $(options.field), id = $(options.id);
			options = Object.extend({
				onlyRemove: false, 
				clearValue: false,
				width: field.getWidth(), 
				minChars: 3,
				resultProperty: "name", 
				itemProperty: "name",
				clearedText: "",
				autoSelectFirstIfOne: false,
				configureImage: false,
				onSelect: Prototype.emptyFunction,
				onClear: Prototype.emptyFunction
			}, options);

			if(field._hasAutocomplete){
				jQuery(field).unautocomplete();
				field._hasAutocomplete = false;
				field.value = options.clearedText;
				field.readOnly = true;
				if(id != null){
					id.value = "";
				}
				options.onClear();
			}
			if(options.onlyRemove){
				if(options.clearValue){
					field.value = options.clearedText;
					if(id != null){
						id.value = "";
					}
					options.onClear();
				}
				return;
			}

			var data = options.data;
			jQuery(field).autocomplete(data, {
				minChars: options.minChars,
                delay: 200,
                width: options.width,
                max: data.length,
                selectFirst: true,
                matchContains: true,
                autoFill: false,
                formatItem: function(row, i, max) {
					if(Object.isFunction(options.itemProperty)){
						return options.itemProperty(row);
					}else{
						return row[options.itemProperty];
					}
                },
                formatMatch: function(row, i, max) {
                    return row.name.replaceSpecialChars() + " " + row.name + " "+ row.abbreviation;
                },
                formatResult: function(row) {
                    return row[options.resultProperty];
                }
			}).result(function(event, item) {
				var oldValue = id.value;
				var value = (item != null) ? item.id: "";
				id.value = value;
				if(oldValue != value){
					((value == "") ? options.onClear : options.onSelect)(item);
				}
            });

			if(Object.isUndefined(field._hasAutocomplete)){
				var clearedText = options.clearedText;
				// Anexa o evento só na primeira vez:
				Event.observe(field, "blur", function(){
					if(field._hasAutocomplete){
						jQuery(field).search();
						if(field.value == ""){
							field.value = clearedText;
						}
					}
				});
				Event.observe(field, "focus", function(){
					if(field.value == clearedText){
						field.value = "";
					}
				});
				if(options.configureImage){
					var image = field.next("img.comboImage");
					if(image != null && image.previous("input[type=text]") === field){
						Event.observe(image, "click", function(){
							jQuery(field).showAll();
						});
					}
				}
			}

			if(field.value == ""){
				field.value = options.clearedText;
			}
			field._hasAutocomplete = true;
			field.readOnly = false;

			if(options.autoSelectFirstIfOne && options.data != null && options.data.length == 1){
				var first = options.data.first();
				field.value = first[options.resultProperty];
				jQuery(field).trigger("result", [first]);
			}
		},

		checkApprovedOwner: function(ownerId){
			var approved;

			new Ajax.Request(contextPath +"/verifyApprovedOwner.action", {
				asynchronous:false,
				parameters: {ownerId:ownerId},
				onComplete:function(response){
					approved = !Consulte.hasError(response);
				}.bind(this)
			});

			return approved;
		},
		
		openContactUs: function(){
			new Ajax.Request(contextPath +"/contactUs.action", {
				onComplete:function(response){
					if(Consulte.hasError(response) == false){
						var LBUpload = new LightBox(response.responseText.strip(), {justContent:1});
						LBUpload.show();
					}
				}.bind(this)
			});
		},
		
		openReport: function(report, parameters){
			var ownerId = $F("filter.ownerId");
			if(String.isEmpty(ownerId)){
				Consulte.showErrorMessage(Bundle.getMessage("txt.select.owner"));
				return;
			}

			parameters = Object.extend({
				//debug:true
				"filter.ownerId":ownerId
			}, parameters||{});

			new Ajax.Request(contextPath +"/report/"+report+".action", {
				parameters:parameters,
				onComplete:function(response){
					if(Consulte.hasError(response) == false){
						$("content").innerHTML = response.responseText;
					}
				}.bind(this)
			});
		},

		openSchedule: function(ownerId){
			var params = {};
			if(ownerId != null){
				params["filter.ownerId"] = ownerId;
			}

			if(this.scheduleWindow == null || this.scheduleWindow.closed){
				this.scheduleWindow = window.open(window.contextPath+"/schedule/main.action?"+Object.toQueryString(params), "schedule", "resizable=no, toolbar=no, location=no, personalbar=no, directories=no, scrollbars=yes, status=yes, menubar=no, copyhistory=no");
				this.resizeSchedule();
			}
			return this.scheduleWindow;
		},
		
		resizeSchedule: function(){
			try{
				this.scheduleWindow.moveTo(0, 0);
				this.scheduleWindow.resizeTo(screen.width, screen.availHeight);
			}catch(e){
				this.resizeSchedule.bind(this).delay(500);
			}
		},
		
		openOwnerSummary: function(ownerId){
			location.href = contextPath + "/owner/data/summaryTemplate.action?id="+ownerId;
		},
		
		getSessionCookie: function(){
			var cookies = document.cookie.split(";");
			for(var i = 0; i < cookies.length; i++){
				if(cookies[i].indexOf("JSESSIONID") >= 0){
					return cookies[i].strip();
				}
			}
			return "";
		},
		
		print: function(url, related){
			if(url == null){
				url = contextPath + "/pages/print.jsp;"+this.getSessionCookie()+"?action=print&div=detail";
			}
			if(related){
				url += "&related=true";
			}
			//url = "http://"+location.hostname+":"+Bundle.getSystemProperty("server.http.port") + url;
			var win = window.open(url, "print", "width=600, height=700, top=10, left=100, resizable=no, toolbar=no, location=no, personalbar=no, directories=no, scrollbars=yes, status=no, menubar=no, copyhistory=no");
			return win;
		},
		
		validateSendEmailMandatoryFields: function(){
			try{
				this.mandatory("EmailForm.to", "label.email.to");
				this.validateEmail("EmailForm.to", "label.email.to");
				
				if(!this.isEmpty("EmailForm.from")){
					this.validateEmail("EmailForm.from", "label.email.from");
				}
				
				return true;
				
			}catch(e){
				if(e == this.$error){
					return false;
				}else{
					throw e;
				}
			}
		},
		
		toggleBanner: function(flag){
			var banner = $("banner");
			if(banner == null){
				Event.observe(window, "load", this.toggleBanner.bind(this, flag));
			}else{
				if(flag){
					banner.show();
				}else{
					banner.hide();
				}
			}
		},				

		isBannerVisible: function(){
			var banner = $("banner");
			return banner != null && banner.visible();
		},
		
		toggleGlossary: function(elementId){
			if($(elementId).select(".resposta").first().visible()){
				$(elementId).select(".resposta").first().hide();
			}else{
				$$(".resposta").each(Element.hide);
				$(elementId).select(".resposta").each(Element.show);
				(function(){ $("content").select("div").first().hide().show(); }).defer();
			}
		},
		
		mandatory: function(field, name, options){
			options = this.getOptions(options);
			field = $(field);
			
			if(this.isEmpty(field)){
				if(options.showInfoMessage){
					this.showInfoMessage(Bundle.getMessage("message.mandatory.info"));
				}
				if(options.showErrorMessage){
					this.showErrorMessage(Bundle.getMessage("message.mandatory.field", name));
				}
				if(options.focus){
					field.focus();
				}

				return this.returnError(options);
			}
			return this.returnSuccess(options);
		},
		
		isEmpty: function(field){
			field = $(field);
			try{
				if(field && String.isEmpty(field.value)){
					return true;
				}
				return false;
			}finally{
				if(field){
					field.value = String.stripToEmpty(field.value);
				}
			}
		},
		
		isNotEmpty: function(field){
			return !this.isEmpty(field);
		},
		
		validateLogin: function(login, options){
			options = this.getOptions(options);
			var value = $(login).value;
			var minLength = 3;
			var hasError = false;
			
			if(value.length < minLength ){
				this.showInfoMessage(Bundle.getMessage("message.username.length"));
				this.showErrorMessage(Bundle.getMessage("message.username.length"));
				hasError = true;
			}

			if(hasError){
				if(options.focus){
					$(login).activate();
				}
				return this.returnError(options);
			}
			return this.returnSuccess(options);
		},
		
		validatePassword: function(password, confirmPassword, options){
			var minLengthPassword = 8;
			options = this.getOptions(options);
			passwordValue = $(password).value;
			confirmPassword = $(confirmPassword).value;
			var hasError = false;
			var isMatchAlpha = false;
			var isMatchNumber = false;
			
			if(passwordValue != confirmPassword){
				this.showInfoMessage(Bundle.getMessage("message.no.secure.password"));
				this.showErrorMessage(Bundle.getMessage(options.equalConfirmPasswordMessage||"message.password.equal.confirm.password"));
				hasError = true;
			}

			if(!hasError && passwordValue.length < minLengthPassword){
				this.showInfoMessage(Bundle.getMessage("message.no.secure.password"));
				hasError = !this.showConfirmMessage(Bundle.getMessage("message.not.a.secure.password"));
			}else if(!hasError){
				passwordValue.scan("[a-zA-Z]", function(match){isMatchAlpha = true;});
				passwordValue.scan("[0-9]", function(match){isMatchNumber = true;});
				if(!isMatchAlpha || !isMatchNumber){
					this.showInfoMessage(Bundle.getMessage("message.no.secure.password"));
					hasError = !this.showConfirmMessage(Bundle.getMessage("message.not.a.secure.password"));
					if(!hasError && options.setValidateAgainst){
						$("ChangeForm.validateAgainst").value = "false";
					}
				}else{
					var values = options.valuesAgainst;
					if(values != null && values.length > 0){
						var success = true;
						values.each(function(item){
							if(options.clearMask){
								item = Mask.clear(item);
							}
							if(item != null && item != "" && password.indexOf(item) >= 0){
								success = false;
								throw $break;
							}
						}.bind(this));

						if(!hasError){
							return this.returnSuccess(options);
						}else{
							this.showInfoMessage(Bundle.getMessage("message.password.recommendations"));
							hasError = !this.showConfirmMessage(Bundle.getMessage("message.not.a.secure.password"));
							if(!hasError && options.setValidateAgainst){
								$("ChangeForm.validateAgainst").value = "false";
							}
						}
					}
				}
			}

			if(hasError){
				if(options.focus){
					$(password).activate();
				}
				return this.returnError(options);
			}
			return this.returnSuccess(options);
		},

		/*
		validatePasswordAgainst: function(password, values, options){
			if(values == null || values.length == 0) return;
			if(!Object.isArray(values)) values = [values];

			options = this.getOptions(options);
			password = $F(password);

			var success = true;
			values.each(function(item){
				if(options.clearMask){
					item = Mask.clear(item);
				}

				if(item != null && item != "" && password.indexOf(item) >= 0){
					success = false;
					throw $break;
				}
			}.bind(this));

			if(success){
				return this.returnSuccess(options);
			}else{
				this.showInfoMessage(Bundle.getMessage("message.password.recommendations"));
				if(this.showConfirmMessage(Bundle.getMessage("message.not.a.secure.password"))){
					return this.returnSuccess(options);
				} else {
					return this.returnError(options);
				}
			}
		},
		*/
		
		validateEmail: function(field, name, options){
			var invalidCharacter = [",", ";", " ", "|", "/", "\\", "+"];
			var reEmail = /.+\@.+\..{2,}/;
			
			options = this.getOptions(options);
			field = $(field);
			numAt = field.value.split("@").length;
			
			for(var i = 0; i < invalidCharacter.length; i++){
				if(field.value.indexOf(invalidCharacter[i]) >= 0){
					this.showErrorMessage(Bundle.getMessage("message.invalid.characters", name));
					if(options.focus){
						field.focus();
					}
					return this.returnError(options);
				}
			}
			
			if(!reEmail.test(field.value) || numAt > 2){
				this.showErrorMessage(Bundle.getMessage("message.email.to.only.one"));
				if(options.focus){
					field.focus();
				}
				return this.returnError(options);
			}
			return this.returnSuccess(options);
		},
		
		validateCPF: function(field, options){
			options = this.getOptions(options);
			var cpf = String.stripToEmpty($F(field));
			cpf = Mask.clear(cpf);
			var hasError = false;

			if(cpf.length != 11){
				hasError = true;
			}

			if(!hasError){
				var array = [];
				for(var i=0; i <= 9; i++){
					array.push(String.repeat(i+"", 11));
				}
				if(array.include(cpf)){
					hasError = true;
				}
			}

			if(!hasError){
				// Aqui começa a checagem do CPF
				var posicao, i, soma, dv, dv_informado;
				var digito = new Array(10);
				dv_informado = cpf.substr(9, 2); // Retira os dois últimos dígitos do número informado
	
				// Desemembra o número do CPF na array digito
				for (i=0; i<=8; i++) {
					digito[i] = cpf.substr(i, 1);
				}
	
				// Calcula o valor do 10º dígito da verificação
				posicao = 10;
				soma = 0;
				for (i=0; i<=8; i++) {
					soma = soma + digito[i] * posicao;
					posicao = posicao - 1;
				}
				digito[9] = soma % 11;
				if (digito[9] < 2) {
					digito[9] = 0;
				}else{
					digito[9] = 11 - digito[9];
				}
				
				// Calcula o valor do 11º dígito da verificação
				posicao = 11;
				soma = 0;
				for (i=0; i<=9; i++) {
					soma = soma + digito[i] * posicao;
					posicao = posicao - 1;
				}
				digito[10] = soma % 11;
				if (digito[10] < 2) {
					digito[10] = 0;
				}else {
					digito[10] = 11 - digito[10];
				}
			}

			if(!hasError){
				// Verifica se os valores dos dígitos verificadores conferem
				dv = digito[9] * 10 + digito[10];
				if (dv != dv_informado) {
					hasError = true;
				}
			}
			
			if(hasError){
				if(options.focus){
					$(field).focus();
				}
				this.showErrorMessage(Bundle.getMessage("message.invalid.field", "label.cpf"));
				return this.returnError(options);				
			}
			return this.returnSuccess(options);
		},
		
		userWantedToKeepInvalidCep: function(invalidCepDiv, keepInvalidCep){
			return !$(invalidCepDiv).visible() || (String($(keepInvalidCep).checked) == "true" && $(invalidCepDiv).visible());
		},
		
		validateCep: function(cepValue, keepInvalidCep, invalidCepDiv, async, callback){
			if(String.isNotEmpty(cepValue) && cepValue != this.lastValidatedCep){
				var checked = $(keepInvalidCep).checked;

				new Ajax.Request(window.contextPath+"/validateCep.action", {
					parameters: {cep:Mask.clear(cepValue)},
					asynchronous: Object.isUndefined(async) ? true : async,
					onComplete: function(response){
						if(!Consulte.hasError(response)){
							var json = response.responseJSON;
							var success = (String(json.exists) == "true");
							$(keepInvalidCep).checked = checked;
							this.lastValidatedCep = cepValue;

							if(success){
								$(invalidCepDiv).hide();
							}else{
								$(invalidCepDiv).show();
							}

							if(Object.isFunction(callback)){
								callback(json, response);
							}
						}
					}.bind(this)
				});
			}
		},
		
		processingField: function(field, tag, action, parameters, async, callback){
			tag = $(tag);
			if(Consulte.isNotEmpty($(field))){
				tag.update("");
				tag.addClassName("processando");
	
				new Ajax.Updater(tag, contextPath +"/"+ action, {
					parameters:parameters,
					asynchronous: (async != null) ? async : true,
					onComplete: function(response){
						tag.removeClassName("processando");
						if(Object.isFunction(callback)){
							callback(response);
						}
					}
				});
			} else {
				tag.innerHTML = "";
			}
		},
		
		truncateMaxLength: function(field){
			field.value = field.value.substring(0, parseInt(field.getAttribute("maxlength")));
		},
		
		suggestShortNameUserName: function(fullName, shortName, login, returnUserName, callback){
			fullName = $(fullName);
			shortName = $(shortName);
			login = $(login);
			returnUserName = $(returnUserName);
			
			if(String.isNotEmpty(fullName.value)){
				var parts = $w(fullName.value);
				if(parts != null && parts.length > 1){
					var first = parts.first(), last = parts.last();
					if(shortName.value == ""){
						shortName.value = first + " " + last;
						this.truncateMaxLength(shortName);
					}

					if(first.length > 0){
						var userName = (first.charAt(0) + last).toLowerCase().replaceSpecialChars();
						if(login.value == ""){
							login.value = userName;
							this.truncateMaxLength(login);
							if(Object.isFunction(callback)){
								callback(null, function(){
									if((returnUserName.innerHTML||"").strip() != ""){
										login.value = "";
										returnUserName.innerHTML = "";
									}
								});
							}
						}
					}
				}
			}
		},
		
		doIndicate: function(group){
			try{
				if(!Consulte.isEmpty("refer.nome") && (!Consulte.isEmpty("refer.email") || !Consulte.isEmpty("refer.celular"))){
					if(!Consulte.isEmpty("refer.email")){
						Consulte.validateEmail("refer.email", "label.email");
					}
					
					document.getElementById('SMT_NOME').value = document.getElementById('refer.nome').value;
					
					if(!Consulte.isEmpty("refer.email")){
						document.getElementById('SMT_MAIL').value = document.getElementById('refer.email').value;
					}else{
						document.getElementById('SMT_MAIL').value = document.getElementById('refer.celular').value.strip() + "@portalconsulte.com";						
					}
					
					document.getElementById('SMT_FONE3').value = document.getElementById('refer.celular').value;
					document.getElementById('GRUPOS').value = group;	
					
					document.formIndicate.submit();
	
					//alert("O PortalConsulte agradece sua indicação! Em breve iremos enviar um e-mail e um sms ao médico indicado!");

					document.getElementById('refer.nome').value = "";
					document.getElementById('refer.email').value = "";
					document.getElementById('refer.celular').value = "";

					document.formIndicate.reset();
				}else{
					alert("Por favor, informe o Nome do Médico e pelo menos um dos seguintes dados: e-Mail ou Celular");
				}
			}catch(e){
				if(e != Consulte.$error) throw e;
				return false;
			}
		},
		
		runEvent: function(field, eventField){
			if(document.createEvent) {
				var evObj = document.createEvent("UIEvents");
				evObj.initUIEvent(eventField, true, true, window, 1);
				field.dispatchEvent(evObj);
			}else if(document.createEventObject){
				field.fireEvent("on"+eventField);
			}
		},

		truncateText: function(elements, length){
			var str = "";
			if (!Object.isArray(elements)) elements = [elements];
			elements.each(function(obj){
				obj = $(obj);
				if(obj.innerText != undefined){
					str = obj.innerText;
				}else{
					str = obj.textContent;
				}
				obj.innerHTML = str.stripTags().unescapeHTML().truncate(length);
			});
		},

		rgbToHex: function(value) {
			if (typeof value !== "string") {
				return "";
			}

			// Search for a pattern containing rgb followed by three sets of digits.
			var result = value.match(/^\s*rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*/);
			if (result == null) {
				if(!value.startsWith("#")){
					return "";
				}
				return value;
			}
			// Use unary operator to force type conversion of result from string to digit.
			var rgb = +result[1] << 16 | +result[2] << 8 | +result[3];
			var hex = "";
			// Convert digits to hex value.
			var digits = "0123456789abcdef";
			while (rgb != 0) {
				hex = digits.charAt(rgb&0xf) + hex;
				rgb >>>= 4;
			}
			while (hex.length < 6) {
				hex = '0' + hex;
			}
			return "#" + hex.toLowerCase();
		},

		toggleDimmer: function(dimmer, flag, clickMessage){
			dimmer = $(dimmer);
			if(flag){
				if(dimmer.visible()) return;

				var resizeFunc = function(){
					dimmer.style.height = "0px";
					var size = this.getWindowSize();
					dimmer.style.width = size.width + "px";
					dimmer.style.height = size.height + "px";
					dimmer.show();
				}.bind(this);
				resizeFunc();
				window.setTimeout(resizeFunc, 10);
				dimmer._dimmerInterval = window.setInterval(resizeFunc, 500);

				var clickFunc = function(){
					alert(clickMessage || Bundle.getMessage("message.cancel.information"));
				}.bind(this);

				Event.observe(dimmer, "click", clickFunc);
				dimmer._clickFunc = clickFunc;
			}else{
				dimmer.hide();

				if(dimmer._dimmerInterval != null){
					window.clearInterval(dimmer._dimmerInterval);
					dimmer._dimmerInterval = null;
				}

				// Limpa o callback anterior:
				if(dimmer._clickFunc != null){
					Event.stopObserving(dimmer, "click", dimmer._clickFunc);
					dimmer._clickFunc = null;
				}
			}
		},
		
		getWindowSize: function() {
			/* Só funciona com esse doctype:
				<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">*/
			return {height:document.documentElement.scrollHeight, width:document.documentElement.scrollWidth};
		},
		
		returnSuccess: function(options){
			if(options.returnBoolean){
				return true;
			}
			return undefined;
		},
		
		returnError: function(options){
			if(options.returnBoolean){
				return false;
			}else{
				throw this.$error;
			}
		},

		showErrorMessage: function(message){
			alert(message);
		},
		
		showInfoMessage: function(message, tableMessageId, txtMessageId){
			var txt = $("txtMessage");
			if(txtMessageId != null){
				txt = $(txtMessageId);
			}
			if(txt != null){
				txt.innerHTML = message;
			}

			var area = $("tableMessage");
			if(tableMessageId != null){
				area = $(tableMessageId);
			}
			if(area != null){
				area.addClassName("warning");
				area.show();
			}
		},

		showConfirmMessage: function(message){
			return confirm(message);
		},

		_formatErrorJson: function(errorJson){
			var buffer = [];

			if(String.isNotEmpty(errorJson.message)){
				buffer.push(errorJson.message);
				buffer.push("\n");
			}

			if(Array.isNotEmpty(errorJson.errors)){
				buffer.push(errorJson.errors.join("\n"));
			}

			if(buffer.length == 0){
				buffer.push(Bundle.getMessage("error.unknown"));
			}

			return buffer.join("");
		},

		hasError: function(response){
			return this.getError(response) != null;
		},

		getError: function(response){
			return this.getHeaderAsJSON(response, "X-JSON-ERROR");
		},

		getHeaderAsJSON: function(response, name){
			var header = response.getResponseHeader(name);
			if(header != null && (header=header.strip()) != ""){
				var value = null;

				if(header.isJSON()){
					value = header.evalJSON();
				}else if($(header)!=null){
					value = $F(header).evalJSON();
				}

				if(value != null && value != "null"){
					return value;
				}
			}
			return null;
		},

		isSplash: function(response){
			var json = this.getHeaderAsJSON(response, "X-Consulte-SplashScreen");
			return String(json||"").toLowerCase() == "true";
		},

		isUnauthorized: function(response){
			var json = this.getHeaderAsJSON(response, "X-Consulte-UnauthorizedScreen");
			return String(json||"").toLowerCase() == "true";
		},

		copyModuleName: function(){
			var moduleName = $("moduleName"), myModuleName = $("myModuleName");
			if(moduleName != null && myModuleName != null){
				moduleName.innerHTML = myModuleName.innerHTML;
				//IE BUG: myModuleName.remove();
			}

			var functionalityName = $("functionalityName"), myFunctionalityName = $("myFunctionalityName");
			if(functionalityName != null && myFunctionalityName != null){
				functionalityName.innerHTML = myFunctionalityName.innerHTML;
				//IE BUG: myFunctionalityName.remove();
			}
		},

		checkBackButton: function(){
			if($("backButton") != null){
				if(this.ajaxStack.length > 1){
					$("backButton").show();
					if($("topMessage") != null){
						$("topMessage").show();
					}
				}else{
					$("backButton").hide();
				}
			}
		},
		
		debug: function(obj, text, isHash){
			if(text == null) text = "";
			if(isHash){
				alert(text+Object.inspect($H(obj)));
			}else{
				alert(text+Object.inspect(obj));
			}
		},

		adjustURL: function(url){
			if(url.startsWith(window.contextPath)){
				url = url.substring(window.contextPath.length);
			}

			var index;
			if((index = url.indexOf("?")) > 0){
				url = url.substring(0, index);
			}

			return url;
		},

		_ignoreRequests: false,
		setIgnoreRequests: function(b){
			this._ignoreRequests = (b === true);
		},
		shouldIgnoreRequest: function(request){
			return this._ignoreRequests || (this.ignoredURLs[this.adjustURL(request.url)]!=null) || ((request.options||{}).consulteOptions||{}).ignoreForBack;
		},

		/******************* AJAX Responders ***********************/
		ignoredURLs:(function(){
			var array = [
		         //GERAL
		         "/systemProperty.action", "/bundle.action", "/sendMail.action", "/cities.generatedJS", "/forgotPassword.action", "/logout.action", "/term/show.action", "/hasCustomerActive.action",
		         //VALIDATE
		         "/validateCep.action", "/validateUserName.action", "/validateCPF.action", "/validateCRM.action", 
		          //DICAS
		         "/healthTip/newTip.action", "/healthTip/save.action", "/healthTip/categoryImagesList.action", "/healthTip/evaluate.action",
		         //COMUNICADOS
		         "/message/new.action", "/message/customerSelection.action", "/message/listCustomers.action", "/message/step1.action", "/message/step2.action", "/message/save.action", "/message/cancel.action", "/message/showRecipients.action",
		         //PERGUNTAS
		         "/question/save.action", "/question/replies.action", "/question/evaluate.action", "/question/evaluateReply.action", "/question/saveReply.action", "/question/approve.action",
		         //OPERADOR
		         "/operator/cancel.action", "/operator/basic.action", "/operator/detail.action", "/operator/step1.action", "/operator/step2.action", "/operator/save.action", "/operator/saveEdit.action", "/operator/showDetail.action",
		         //CONSULTORIO
		         "/workingPlace/confirm.action", "/workingPlace/basic.action", "/workingPlace/detail.action", "/workingPlace/save.action", "/workingPlace/ownersApproval.action", "/workingPlace/approval.action", "/workingPlace/activate.action", "/workingPlace/deactivate.action", "/workingPlace/insert.action",
		         //MEDICO
		         "/comment/turn.action", "/owner/data/step1.action", "/owner/data/step2.action", "/owner/data/step3.action", "/owner/data/complement.action", "/owner/data/cancel.action", "/owner/data/save.action", "/cid/showChapter.action",
		         //PACIENTE marca Consulta
		         "/customer/schedule/chooseDate.action", "/customer/schedule/cancel.action", "/customer/schedule/save.action", "/customer/schedule/makeCanceled.action", "/customer/schedule/confirm.action",
		         //RELATÓRIOS:
		         "/report/list.action",
		         //NOTÍCIAS
		         "/news/list.action"
            ];
			return array.inject({}, function(hash, url){
				hash[url] = true; return hash;
			});
		})(),
		ajaxStack: [],
		onCreate: function(request, response){
			this.pushAjaxRequest(request);
		},
		onException: function(request, exception){
			alert("Exception: "+$H(exception).inspect());
		},
		onComplete: function(request, response, json){
			this.copyModuleName();
			this.checkBackButton();
			
			(function(){
				var array = $$(".absoluteShow");
				if(array.length > 0){
					array.first().hide().show();
				}
			}).defer();

			var errorJson = this.getError(response);
			if(errorJson != null){
				var options = ((request.options||{}).consulteOptions||{});
				if(errorJson.confirmation && Object.isFunction(options.handleConfirmation)){
					options.handleConfirmation(errorJson);
				}else{
					this.showErrorMessage(this._formatErrorJson(errorJson));
				}

				if((errorJson.extraParameters||{}).logout){
					window.location = window.contextPath;
					return;
				}
			}

			if(this.isSplash(response) || this.isUnauthorized(response)){
				// Desliga do dimmer: 
				this.toggleDimmer.bind(this, "dimmerCover", false).defer();
			}			
		},
		clearAjaxStack: function(){
			this.ajaxStack.clear();
		},
		pushAjaxRequest: function(request){
			if(this.shouldIgnoreRequest(request)) return;

			var jsonRequest = {
					url:this.adjustURL(request.url),
					parameters:request.parameters,
					hadBanner:this.isBannerVisible()
			};

			var last = (this.ajaxStack.length > 0) ? this.ajaxStack.last() : null;
			if(last != null){
				// Mesma URL, sobrescreve a última:
				if(this.adjustURL(last.url) == this.adjustURL(jsonRequest.url)){
					this.ajaxStack = this.ajaxStack.without(last);
				}
			}

			this.ajaxStack.push(jsonRequest);
		},
		setBackURL: function(url, index){
			this.setBackOptions({url:url}, index);
		},
		setBackOptions: function(options, index){
			index = index || 0;
			var req = (this.ajaxStack.length > index) ? this.ajaxStack[this.ajaxStack.length-index-1] : null;
			if(req != null && options != null){
				// Adiciona mais parâmetros na requisição, não sobre-escreve:
				if(options.parameters != null){
					Object.extend(req.parameters, options.parameters);
					delete options.parameters;
				}
				Object.extend(req, options);
			}
		},

		popAjaxStack: function(){
			if(this.ajaxStack.length >= 1){
				var last = this.ajaxStack.last();
				this.ajaxStack = this.ajaxStack.without(last);
				return last;
			}
			return null;
		},

		back: function(){
			// Penúltima Requisição:
			var req = (this.ajaxStack.length >= 2) ? this.ajaxStack[this.ajaxStack.length - 2] : null;
			if(req != null){
				var last = this.ajaxStack.last(); // Guarda o último, antes que adicione mais no onCreate.

				new Ajax.Request(window.contextPath+this.adjustURL(req.url), {
					parameters: req.parameters,
					onComplete: function(response){
						if(!this.hasError(response)){
							$("content").innerHTML = response.responseText;
							Consulte.toggleDimmer("dimmerCover", false);
							this.toggleBanner(req.hadBanner);
							this.setBackOptions({hadBanner:req.hadBanner});

							// Remove as requisições:
							this.ajaxStack = this.ajaxStack.without(req, last);
							Consulte.showContentRight();
						}
					}.bind(this)
				});
				
				return true;
			}
			return false;
		}
	};
	Ajax.Responders.register(window.Consulte);
}