// utils.js


//função a ser usada no evento onkeypress para apenas permitir escrever numeros
function validaValor(e){ // para funcionar em FireFox e IE
    //alert('e.keyCode: '+e.keyCode)
    //alert('e.which: '+e.which)
    var code;
    if (!e) e = window.event;
    if (window.event){ // IE
          code = e.keyCode;
    }else // FireFox
          code = e.which;

    //if (e.keyCode){//alert('e.keyCode: '+e.keyCode); 
    //    code = e.keyCode;}
    //else if (e.which) {tipo=1;code = e.which;}
    //alert('code: '+code);
    if (code == 44){
           e.keyCode=46;
    }

    // 8 - backspace; code>0 devido a firefox em que e.which =0 quando se navega com as setas
    if (code>0 && code!= 8 && (code < 45 || code > 57)) {
          if (window.event) //IE
                window.event.returnValue = false;
          else //Firefox
                e.preventDefault();
          //e.returnValue = false;
    }
}



KEYBKSP		=  8
KEYTAB		=  9
KEYLEFT 	= 37
KEYUP		= 38
KEYRIGHT	= 39
KEYDOWN 	= 40
KEYDEL		= 46
NUMPAD0		= 48
NUMPAD1		= 49
NUMPAD2		= 50
NUMPAD3		= 51
NUMPAD4		= 52
NUMPAD5		= 53
NUMPAD6		= 54
NUMPAD7		= 55
NUMPAD8		= 56
NUMPAD9		= 57


function onlynumbers(elem){
	if (   event.keyCode != KEYBKSP 
		&& event.keyCode != KEYTAB
		&& event.keyCode != KEYLEFT
		&& event.keyCode != KEYUP
		&& event.keyCode != KEYRIGHT
		&& event.keyCode != KEYDOWN
		&& event.keyCode != KEYDEL
		&& event.keyCode != NUMPAD0
		&& event.keyCode != NUMPAD1
		&& event.keyCode != NUMPAD2
		&& event.keyCode != NUMPAD3
		&& event.keyCode != NUMPAD4
		&& event.keyCode != NUMPAD5
		&& event.keyCode != NUMPAD6
		&& event.keyCode != NUMPAD7
		&& event.keyCode != NUMPAD8
		&& event.keyCode != NUMPAD9)
		
		event.returnValue = false;
}

function onlyint(){
	if (event.keyCode < 47 || event.keyCode > 57) 
		event.returnValue = false;
}

// newFunction
function norm_button(but) {
	var src = but.src;
	src = src.substring(0,src.lastIndexOf("_u.gif"))+"_d.gif";
	but.src = src;
}

function hilite_button(but) {
	var src = but.src;
	src = src.substring(0,src.lastIndexOf("_d.gif"))+"_u.gif";
	but.src = src;
}


var msg;
var campos_vazios = "";
var erros = "";
var daysofmonth   = new makeArray(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
var daysofmonthLY = new makeArray(31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
var monthsofyear  = new makeArray(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
var today = new Date();
var year = today.getYear();
var month = today.getMonth()+1;
var day = today.getDate();
var flagConfirma = 0;
var campoData = false;

function makeArray() {
  this[0] = makeArray.arguments.length;
  for (i = 0; i<makeArray.arguments.length; i++)
    this[i+1] = makeArray.arguments[i];
}

//Array global de conversor de caracteres

compara = new Array("?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?"," ","!","\"","?","$","%","&","'","(",")","*","+","\,","-",".","/","0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?","@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","[","\\","]","?","_","?","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?"," ","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","A","A","A","A","A","A","?","C","E","E","E","E","I","I","I","I","?","?","O","O","O","O","O","?","?","U","U","U","U","?","?","?","a","a","a","a","a","a","?","c","e","e","e","e","i","i","i","i","?","?","o","o","o","o","o","÷","?","u","u","u","u","?","?","?","?");
inicializa=0;


//Abre uma janela centrada no ecrã sem qualquer opção para além do resize
function openWindow(width, height, name, url){
	var top = (screen.height - height)/2;
	var left = (screen.width - width)/2;
	return window.open(url,name,"directories=no,height="+height+",width="+width+",top="+top+",left="+left+",resizable=yes,scrollbars=yes,location=no,menubar=no,titlebar=no,toolbar=no");
}

function showModal(promptHref, wWidth, wHeight) {
	var dialogFormat="menubar:no;title:no;help:no;status:no;minimize:no;maximize:no;resizable:yes;border=thick;center:yes;scroll:no;dialogWidth="+wWidth+"px;dialogHeight="+wHeight+"px;dialogLeft=100px;dialogTop=100px;"
	var objRet = window.showModalDialog(promptHref,window,dialogFormat);
	return objRet;
}


	function formataPercentagem(){
		var value = event.srcElement.value;
		value = value.replace(',','.');
		if (isNaN(value) || value > 100){
			alert("Valor de percentagem inválido.");
			event.srcElement.focus();
			return;
		}else{
			 event.srcElement.value = value.replace('.',',');
		}
	}

// Coloca as barras nas posições correctas em todos os campos do tipo data
// Esta função é chamada no evento onBlur
	function formataData(campo){
//		var campo = event.srcElement;
		var valor = campo.value;
		var separador = '-';
		

		dataValida=false;
		result="";
		sep =' ';
		tamanho=valor.length;
		
		//Converter separador para '-'
		for (i=0;i<tamanho;i++){
			if(isNaN(valor.charAt(i))){
				sep = valor.charAt(i);
				break;
			}
		}
		if (sep!=' '){
			result = valor;
			while(result.indexOf(sep) != -1 && sep!= separador) {
	   			result = result.replace(sep, separador);
			}  
		}else if(tamanho ==8 && !isNaN(valor)){
			for (i=0;i<tamanho;i++){
				if (i==2) {
					result=result.concat(separador);
					
				}
	      		if(i==4) {
					result=result.concat(separador);
					
	      		}
				result=result.concat(valor.charAt(i));
				
	    	}
	    }
	    
	    // Verificar validade da data
	    indice = result.indexOf(separador);
	    if (indice>0){
	    	dia = result.substring(0,indice);
	    	str = result.substring(indice+1);
	    	indice = str.indexOf(separador);
	    	mes = str.substring(0,indice);
	    	ano = str.substring(indice+1);
	    	ano4 = ano
	    	//alert('dia: '+dia)
	    	//alert(ValidDate(dia,mes,ano))
	    	//alert(dia>daysofmonthLY[month])
	    	try{
		    	var dt = new Date(ano,mes-1,dia);
		    	dia = dt.getDate();
	    		mes = dt.getMonth()+1;
	    		ano = dt.getYear();
		    }catch (e) {
	    		alert('Data Inválida');
	    		result="";
				campo.createTextRange().select();
	    		campo.focus();
	    		return;		    	
		    }
		    
	    	ano = ano4;
	    	
	    	if (isNaN(dia) || isNaN(mes) || isNaN(ano) ||
	    	!ValidDate(Number(dia),Number(mes),ano)){
	    		alert('Data Inválida');
	    		result="";
				campo.createTextRange().select();
	    		campo.focus();
	    		return;
	    	}else {
	    		dataValida=true;
	    		//alert('dia: '+Number(dia)+' mes: '+Number(mes)+' ano: '+Number(ano));
	    		result = (Number(dia)<10?'0'+Number(dia):dia)+separador+
	    				(Number(mes)<10?'0'+Number(mes):mes)+separador+
	    				(Number(ano)<10?'200'+Number(ano):Number(ano)<100?'20'+Number(ano):ano);
	    	
	    	}
	    }
	    	
	    //alert(result);
	    if (result=="" && campo.value!=""){
			alert("Data Inválida");
			campo.createTextRange().select();
			campo.focus();
			return;
		}
		
		campo.value=result;
		valor=result;
		return dataValida;
	}


	function verDoc(url){
		var text ="height=800,width=800,top=1,menubar=0,titlebar=0,resizable=1,scrollbars=1,dependent=1,location=no"
		window.open(url,null,text)
	}
	
	function validaDatas(DataInicio,DataFim) {
	
	//verifica se o intervalo de Datas é valido
	//DataInicio<=DataFim
	
		datum1 = DataInicio.split("-");
		  dia1 = datum1[0];
		  mes1 = datum1[1];
		  ano1 = datum1[2];
	  
		datum2 = DataFim.split("-");
		  dia2 = datum2[0];
		  mes2 = datum2[1];
		  ano2 = datum2[2];
	
		datai = new Date(ano1, mes1-1, dia1)
		dataf = new Date(ano2, mes2-1, dia2)
	
		if(datai.getTime() > dataf.getTime()){
			//alert("O intervalo da Data Inicio e Data Final está incorrecto")
			return false;
		}
		else 
			return true;
			
	}
	

	function formataHora(obj) {
		var elem = window.event.srcElement;	
	
	    if(!isNaN(obj.value) && obj.value.length==4)
	      obj.value=obj.value.substring(0,2)+":"+obj.value.substring(2,4);
		
		var timePat = /^(\d{1,2}):(\d{2})?$/;
		
		var matchArray = obj.value.match(timePat);
		if (matchArray == null && obj.value != '') {
			alert("A Hora não se encontra no formato válido.");
			elem.focus();
			return false;
		}else if (obj.value != ''){
		
			hour = matchArray[1];
			minute = matchArray[2];	
			if (hour < 0  || hour > 23) {
				alert("Hora deverá estar entre 01 e 23.");
				elem.focus();
				return false;
			}
		
			if (minute<0 || minute > 59) {
				alert ("Os minutos deverá estar entre 0 e 59.");
				elem.focus();
				return false;
			}
		}	
		return true;	
	}


	function validaHoras(hInicio,hFim) {
		//verifica se o intervalo de horas é valido
		//hInicio<=hFim
	
		h1 = hInicio.split(":");
		hora1 = Number(h1[0]);
		min1 = Number(h1[1]);
	  
		h2 = hFim.split(":");
		hora2 = Number(h2[0]);
		min2 = Number(h2[1]);
		if (hora1<hora2){
			return true;
		}else if (hora1==hora2){
			if (min1<=min2)
				return true;
			else
				return false;
		}
		else
			return false;


	}



	window.onerror = null;
	var bName = navigator.appName;
	var bVer = parseInt(navigator.appVersion);
	var NS4 = (bName == "Netscape" && bVer >= 4);
	var IE4 = (bName == "Microsoft Internet Explorer" && bVer >= 4);
	var NS3 = (bName == "Netscape" && bVer < 4);
	var IE3 = (bName == "Microsoft Internet Explorer" && bVer < 4);
	var blink_speed=200;
	var i=0;
 
	if (NS4 || IE4) {
		if (navigator.appName == "Netscape") {
			layerStyleRef="layer.";
			layerRef="document.layers";
			styleSwitch="";
		}else{
			layerStyleRef="layer.style.";
			layerRef="document.all";
			styleSwitch=".style";
		}
	}
	
	//BLINKING
	function Blink(layerName,speed){
		if (NS4 || IE4) { 
			if(i%2==0){
				eval(layerRef+'["'+layerName+'"]'+
				styleSwitch+'.visibility="visible"');
			}else{
				eval(layerRef+'["'+layerName+'"]'+
				styleSwitch+'.visibility="hidden"');
			}
		} 
	
		if(i<1){
			i++;
		} else{
			i--
		}
		setTimeout("Blink('"+layerName+"')",blink_speed);
	}

	
	
	
	
var msg;
var campos_vazios = "";
var erros = "";
var daysofmonth   = new makeArray(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
var daysofmonthLY = new makeArray(31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
var monthsofyear  = new makeArray(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
var today = new Date();
var year = today.getYear();
var month = today.getMonth()+1;
var day = today.getDate();
var flagConfirma = 0;
var campoData = false;

function makeArray() {
  this[0] = makeArray.arguments.length;
  for (i = 0; i<makeArray.arguments.length; i++)
    this[i+1] = makeArray.arguments[i];
}

//Array global de conversor de caracteres

compara = new Array("?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?"," ","!","\"","?","$","%","&","'","(",")","*","+","\,","-",".","/","0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?","@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","[","\\","]","?","_","?","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?"," ","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","A","A","A","A","A","A","?","C","E","E","E","E","I","I","I","I","?","?","O","O","O","O","O","?","?","U","U","U","U","?","?","?","a","a","a","a","a","a","?","c","e","e","e","e","i","i","i","i","?","?","o","o","o","o","o","÷","?","u","u","u","u","?","?","?","?");
inicializa=0;


// Função que converte todos os caracteres especiais

function converte(campo,nome,j){
  result="";
  tamanho=campo.length;
  
  for(i=0;i<tamanho;i++) {
    codigo=campo.charCodeAt(i);
    if (codigo<0 || codigo>255)
      codigo = 256;
    if (compara[codigo] != campo.charAt(i) && flagConfirma == 0){ 
      flagConfirma=1;
    }
    result+=compara[codigo];
  }
  document.forms[0].elements[j].value=result;
}

// Janela de confirmação dos dados a enviar

function confirma() {
  if (confirm('Os dados introduzidos continham caracteres Inválidos! \n\n           Foi efectuada conversão automática\n\n                 Confirma esta operação '))
    return true;
  return false;
}

// Atribui propriedades ao objecto valida

function ObjectoValida(parametro,label,tipo,obrigatorio,min,max,dependencia){
  this.parametro = parametro;
  this.label = label;
  this.tipo = tipo;
  this.obrigatorio = obrigatorio;
  this.min = min;
  this.max = max;
  this.dependencia = dependencia;
}

// Captura pelo codigo ASCII se a tecla premida é diferente de Enter ou " ",incrementa o contador
// Verifica o tamanho do contador, se for zero devolve true senão devolve falso

function verificatexto(campo) {
  tamanho= campo.length;
  temp=0;
  
  for (i=0,j=0;i<tamanho;i++) {
    if ((campo.charCodeAt(i)!=10) && (campo.charCodeAt(i)!=13) && (campo.charCodeAt(i)!=32) ){
      temp[j]+=campo[i];
      j++;
    }
  }
        
  if (j == 0)
    return true;
  else
    return false;
} 

//Verifica se o tamanho passado por parametro se encontra correcto
function comprimento (campo,min,max,rows,columns) {
  tamanho= campo.length-1;
  linhas=1;
  j=0;
  
  for (i=0;i<tamanho;i++) {
    if (campo.charCodeAt(i)==10) {
      linhas++;
      j=i+2;
    }
    else {
      if (i-j>=columns){
	linhas++;
	j=i+2;
      }
    }
  }

  if  ((parseInt(min)!= null) || (parseInt(max)!= null)){
    if (campo.length < parseInt(min))
      return "9";
    if (campo.length > parseInt(max))
      return "10";
  }
  return "0";
}


//Verifica se o ano é bissexto

function bissexto(year) {
  if ((year/4)   != Math.floor(year/4))
    return false;
  if ((year/100) != Math.floor(year/100))
    return true;
  if ((year/400) != Math.floor(year/400))
    return false;
  return true;
}

function ValidDate(day,month,year) {
  if ((bissexto(year) && (day>daysofmonthLY[month])) || (!bissexto(year) && (day>daysofmonth[month]))) {
    return false;
  }
  else {
    return true;
  }
}

//Verifica se a data introduzida é uma data válida
function vData (data) {
  datum = data.split("-");
  dia = datum[0];
  mes = datum[1];
  ano = datum[2];

  if (ano.length!=4)
    return "1";
  if ((isNaN(ano)) || (isNaN(mes)) || (isNaN(dia)) || (dia.length!=2))
    return "1";
  if (mes.length!=2)
    return "1";
  if ((mes>12)||(mes<1))
    return "1";
  else{ 
    if (!ValidDate(dia-0,mes-0,ano))
      return "1";
  }

}

// Verifica se o campo introduzido é do tipo taxa
function vTaxa(campo){
  for (i=0;i<campo.length;i++) {
    if (((campo.charCodeAt(i)<48) || (campo.charCodeAt(i)>57)) && (campo.charCodeAt(i)!=46) && (campo.charCodeAt(i)!=37))
      return "12";
  }
  return "0";
}

//Verifica se o campo introduzido se encontra dentro dos parametros definidos como minimo e máximo
function limite (campo,min,max){
  if (!isNaN(campo)){
    if (min!= "") {
      if (parseInt(campo) < parseInt(min))
	return "5";
    }
    if (max!= ""){
      if (parseInt(campo) > parseInt(max))
	return "6";
    }
  }
  else
    return "4";
}


//Retira os espaços do valor passado
function tiraEspacos(campo){
  tamanho= campo.length;
  result = "";
  for (i=0;i<tamanho;i++) {
    if (campo.charCodeAt(i)!=32)
      result+=campo.charAt(i);
  }
  return result;
}

//Verifica se o campo introduzido é um campo numerico positivo
// Serve para todos os dados do tipo number

function vNumero(campo) {
  campo=tiraEspacos(campo);
  for (i=0;i<campo.length;i++) {
    if ((campo.charCodeAt(i)<48) || (campo.charCodeAt(i)>57))
      return "4";
  }
  return "0";
}

//Verifica se o campo é um número 
function vDecimal(campo){
  campo=tiraEspacos(campo);
  try{
  	campo = parseFloat(campo).toFixed();
  }catch (e) {
  	return "18";
  }
  return true;
}

//Verifica se o campo introduzido é um campo numerico positivo e permite a inserção de pontos
// Serve para todos os dados do tipo integer
//Exemplo 99.99 - 2 casas decimais

function vMoeda(campo) {
  campo=tiraEspacos(campo);
  contador=0;
  for (i=0;i<campo.length;i++) {
    if (campo.charCodeAt(i)==46)
      contador++;
    if (((campo.charCodeAt(i)<48) || (campo.charCodeAt(i)>57)) && (campo.charCodeAt(i)!=46))
      return "18";
  }

  if (contador>1){
    return "18";
  }else {
    if (contador!=0){
     // if(campo.charAt(campo.length-3)!='.')
     //COA -- Dessa forma a validação obriga a inserção de 2 casas decimais (10.5 => inválido!!!)
     //Assim permite-se a inserção no máximo de 2 casas decimais
     if (campo.length - campo.lastIndexOf('.') > 3)
	return "19";
    }
  }
  campo = parseFloat(campo).toFixed(2);
  return "0";
}

//verifica se a hora introduzida e valida (HH:MM)
function vTime4 (tempo) {
  horaum = tempo.split(":");
  hora = horaum[0];
  minuto = horaum[1];

  if ((tempo.length != 5) || (isNaN(hora)) || (isNaN(minuto)) || (hora.length != 2) || (minuto.length != 2))
    return "20";
}

//verifica se a hora introduzida e valida (HH:MM:SS)
function vTime6 (tempo) {
  horaum = tempo.split(":");
  hora = horaum[0];
  minuto = horaum[1];
  segundo = horaum[2];

  if ((tempo.length != 8) || (isNaN(hora)) || (isNaN(minuto)) || (isNaN(segundo)) || (hora.length != 2) || (minuto.length != 2) || (segundo.length != 2))
    return "21";
}


//verifica se o email introduzido e invalido (T@T.T)
function vEmail(email){
  var i = email.indexOf("@");
  var j = email.indexOf(".");
  
  if (j < i)
    j = email.indexOf(".",i);
  
  if ((i==-1) || (j==-1) || i < 1 || (j<i+2))
    return "22";
  var z = email.indexOf("@",i+1);
  if (z != -1)
    return "22";   
}

//verifica se o nº contribuinte e correcto
function vContribuinte(contribuinte){
  
  var reg=/[0-9]+/;
	
  if (contribuinte.length<9 || !reg.test(contribuinte) || contribuinte=="000000000" ) // validar número.
     return "23";
      
  produto=0;
  j=8;
  for (i=1; i<10; i++){
    produto+=contribuinte.substring(j,j+1)*i;
    j--;	
  }  
  resto=produto%11;
  if(resto==0 || (resto==1 && contribuinte.substring(8,9)==0))
    return true;    
  else 
    return "23";
  
}

function vNib(nib){
	var reg=/[0-9]+/;
	if(nib.length<21 || !reg.test(nib))
		return "17";
		
	var tabela  = new Array(73, 17, 89, 38, 62, 45, 53, 15, 50, 5, 49, 34, 81, 76, 27, 90, 9, 30, 3);
	var val=0;
	for(i=1; i<nib.length-1; i++){
		val+=nib.substring(i-1, i)*tabela[i-1];
	}
	val = 98 - val % 97;
	
	if(val == parseInt(nib.substring(19,20)) * 10 + parseInt(nib.substring(20)))
		return true;
	else
		return "17";
}

function vIban(iban){

	if(iban.length<25 )
		return "16";
		
	var pt = iban.substring(0,4);
	var nib = iban.substring(4);
	
	if((pt == "PT50" || pt == "pt50") && vNib(nib) == true)
		return true;
	else if(pt != "PT50" && pt != "pt50")
		return true;
	else 
		return "16";
}


function vArtigo(artigo){
	for (var i=0; i<artigo.length; i++){
		if (artigo.charAt(i)<'0' || artigo.charAt(i)>'9'){
			if (i>0 || artigo.charAt(i)!='P')
				return "24";
		}
	}
	return true;
}

// Esta função apanha o codigo do erro e dispara a mensagem respectiva

function erro(numero,label,min,max,rows) {

  switch(numero) {
  case "1":
    erros+= '\n           - '+label+': deve ser do tipo data (dd-mm-aaaa) ';
    return true;
  case "4":
    erros+= '\n           - '+label+': deverá ser numérico (Ex: 123) ';
    return true;
  case "5":
    erros+= '\n           - '+label+': deverá ter como minimo: '+ min;
    return true;
  case "6":
    erros+= '\n           - '+label+': deverá ter como máximo: '+ max;
    return true;
  case "9":
    erros+= '\n           - '+label+': número caracteres mínimos: '+min;
    return true;
  case "10":
    erros+= '\n           - '+label+': número caracteres máximos: '+max;
    return true;
  case "12":
    erros+= '\n           - '+label+': o formato do tipo Taxa deve ser (XX%) ';
    return true;
  case "16":
    erros+= '\n           - '+label+': o IBAN é inválido ';
    return true;
  case "17":
    erros+= '\n           - '+label+': o NIB é inválido ';
    return true;
  case "18":
    erros+= '\n           - '+label+': o formato deve ser (Ex: 99.00) ';
    return true;
  case "19":
    erros+= '\n           - '+label+': deverá ter duas casas decimais (Ex: 99.99) ';
    return true;
  case "20":
    erros+= '\n           - '+label+': o formato hora deve ser (HH:MM) ';
    return true;
  case "21":
    erros+= '\n           - '+label+': o formato hora deve ser (HH:MM:SS) ';
    return true;  
  case "22":
    erros+= '\n           - '+label+': o formato deve ser do tipo Email ';
    return true;  
  case "23":
    erros+= '\n           - '+label+': nº Contribuinte inválido ';
    return true;
  case "24":
    erros+= '\n           - '+label+': o valor deve ser numérico, opcionalmente antecedido pela letra "P" para indicar registo provisório ';
    return true;
  default: 
    return false;    
  }
  
}


function substituiVirgulas(form, aValida){
	 for (var j = 0; j < aValida.length; j++) { 
		if (aValida[j].tipo=="tax" || aValida[j].tipo=="Money"){
			var e = document.all[aValida[j].parametro];
		   e.value = e.value.replace(',','.');
		}
    }
}


function verificaForm(form,aValida,conversao) {

  // Percorre todos os elementos do form  e verifica se são obrigatorios ou se existem dependencias
  // Se forem, então valida se estão vazios e se estão bem formatados
  // Se não, verifica se estão bem formatados
  // Converte todos os caracteres e retorna verdadeiro

  flagConfirma = 0; //inicializacao flagConfirma
  flagPrimeiroErro = 0;
  campoPrimeiroErro = "";

  for (var i = 0; i < eval("document." + form + ".length"); i++) {
    var e = eval("document." + form + ".elements[i]");
    for (var j = 0; j < aValida.length; j++) { 
      if (e.name==aValida[j].parametro) {
		var campo=e.value;
		if (aValida[j].obrigatorio!="") {
	  		//Primeiro verifica se o campo está vazio
	  		if (verificatexto(campo)){
	    		campos_vazios += "\n           ---> " + aValida[j].label;
	    		if (flagPrimeiroErro == 0){
	      			flagPrimeiroErro = 1;
	      			campoPrimeiroErro = e.name;
	    		} 
	  		}
		}
		//Vai verificar se existem dependencias
		else{
	  		if(aValida[j].dependencia!="") {
	    		depende=aValida[j].dependencia;
	    		if (eval("document."+ form + "." +depende+".value")!="") {
	      			if (verificatexto(campo)){
						campos_vazios += "\n           ---> " + aValida[j].label;
						if (flagPrimeiroErro == 0){
		  					flagPrimeiroErro = 1;
		  					campoPrimeiroErro = e.name;
						}
	      			}
	    		}
	  		}
		}

	if(!verificatexto(campo)){
	 switch(aValida[j].tipo) {	  
	  case "String" :
	    if (erro(comprimento(campo,aValida[j].min,aValida[j].max,e.rows,e.columns),aValida[j].label,aValida[j].min,aValida[j].max,e.rows)){
	      if (flagPrimeiroErro == 0){
	        flagPrimeiroErro = 1;
		campoPrimeiroErro = e.name;
	      }    
	    }
	    break;
	  case "Date" :
	    if (erro(vData(campo),aValida[j].label,aValida[j].min,aValida[j].max)){
	      if (flagPrimeiroErro == 0){
			flagPrimeiroErro = 1;
			campoPrimeiroErro = e.name;
			campoData = true;
	      }
	    }
	    break;
	  case "tax" :
	  	 //e.value = e.value.replace(',','.');
	  	campo = campo.replace(',','.');
	    if ((aValida[j].min != "") || (aValida[j].max != "")){
		    if (erro(limite(campo,aValida[j].min,aValida[j].max),aValida[j].label,aValida[j].min,aValida[j].max)){
		      if (flagPrimeiroErro == 0){
				flagPrimeiroErro = 1;
				campoPrimeiroErro = e.name;
		      }
		    }
		    break;
	   }else{
	      if (erro(vTaxa(campo),aValida[j].label,aValida[j].min,aValida[j].max)){
			if (flagPrimeiroErro == 0){
			  flagPrimeiroErro = 1;
			  campoPrimeiroErro = e.name;
			}
	      }
	      break;
	    }	  
	  case "Number" :
	    if ((aValida[j].min != "") || (aValida[j].max != "")){
	      if (erro(limite(campo,aValida[j].min,aValida[j].max),aValida[j].label,aValida[j].min,aValida[j].max)){
			if (flagPrimeiroErro == 0){
			  flagPrimeiroErro = 1;
			  campoPrimeiroErro = e.name;
			}
	      }
	      break;
	    }
	    else {
	      if (erro(vNumero(campo),aValida[j].label,aValida[j].min,aValida[j].max)){
			if (flagPrimeiroErro == 0){
			  flagPrimeiroErro = 1;
			  campoPrimeiroErro = e.name;
			}
	      }
	      break;
	    }
	  case "Decimal" :
	  	campo = campo.replace(',','.');
	  	
	    if ((aValida[j].min != "") || (aValida[j].max != "")){
	      if (erro(limite(campo,aValida[j].min,aValida[j].max),aValida[j].label,aValida[j].min,aValida[j].max)){
			if (flagPrimeiroErro == 0){
			  flagPrimeiroErro = 1;
			  campoPrimeiroErro = e.name;
			}
	      }
	      break;
	    }
	    else {
	      if (erro(vDecimal(campo),aValida[j].label,aValida[j].min,aValida[j].max)){
			if (flagPrimeiroErro == 0){
			  flagPrimeiroErro = 1;
			  campoPrimeiroErro = e.name;
			}
	      }
	      break;
	    }
	  case "Money" :
	  	campo = campo.replace(',','.');
	  	
	    if ((aValida[j].min != "") || (aValida[j].max != "")){
	      if (erro(limite(campo,aValida[j].min,aValida[j].max),aValida[j].label,aValida[j].min,aValida[j].max)){
			if (flagPrimeiroErro == 0){
			  flagPrimeiroErro = 1;
			  campoPrimeiroErro = e.name;
			}
	      }
	      break;
	    }
	    else {
	      if (erro(vMoeda(campo),aValida[j].label,aValida[j].min,aValida[j].max)){
			if (flagPrimeiroErro == 0){
			  flagPrimeiroErro = 1;
			  campoPrimeiroErro = e.name;
			}
	      }
	      break;
	    }
	  case "Time4" :
	    if (erro(vTime4(campo),aValida[j].label,aValida[j].min,aValida[j].max)){
	      if (flagPrimeiroErro == 0){
		flagPrimeiroErro = 1;
		campoPrimeiroErro = e.name;
	      }
	    }
	    break;
	  case "Time6" :
	    if (erro(vTime6(campo),aValida[j].label,aValida[j].min,aValida[j].max)){
	      if (flagPrimeiroErro == 0){
		flagPrimeiroErro = 1;
		campoPrimeiroErro = e.name;
	      }
	    }
	    break;
	  case "Email" :
	    if (erro(vEmail(campo),aValida[j].label,aValida[j].min,aValida[j].max)){
	      if (flagPrimeiroErro == 0){
		flagPrimeiroErro = 1;
		campoPrimeiroErro = e.name;
	      }
	    }
	    break;
	  case "Contribuinte" :
	    if (erro(vContribuinte(campo),aValida[j].label,aValida[j].min,aValida[j].max)){
	      if (flagPrimeiroErro == 0){
		flagPrimeiroErro = 1;
		campoPrimeiroErro = e.name;
	      }
	    }
	    break;
	  case "Nib" :
	    if (erro(vNib(campo),aValida[j].label,aValida[j].min,aValida[j].max)){
	      if (flagPrimeiroErro == 0){
		flagPrimeiroErro = 1;
		campoPrimeiroErro = e.name;
	      }
	    }
	    break;
	  case "Iban" :
	    if (erro(vIban(campo),aValida[j].label,aValida[j].min,aValida[j].max)){
	      if (flagPrimeiroErro == 0){
		flagPrimeiroErro = 1;
		campoPrimeiroErro = e.name;
	      }
	    }
	    break;
	  case "Artigo" :	
	    if (erro(vArtigo(campo),aValida[j].label,aValida[j].min,aValida[j].max)){
	      if (flagPrimeiroErro == 0){
		flagPrimeiroErro = 1;
		campoPrimeiroErro = e.name;
	      }
	    }
	    break;
	  default :
	    if (erro(comprimento(campo,aValida[j].min,aValida[j].max,e.rows,e.columns),aValida[j].label,aValida[j].min,aValida[j].max,e.rows)){
	      if (flagPrimeiroErro == 0){
		flagPrimeiroErro = 1;
		campoPrimeiroErro = e.name;
	      }
	    }
	  }
	}
      }
    }
  }

  // Se ocorrer erros, dispara mensagens e retorna falso ao fazer submit,senão retorna verdadeiro
  if (!campos_vazios && !erros) {
    for (var i = 0; i < eval("document." + form + ".length"); i++) {
      var e = eval("document." + form + ".elements[" + i + "]");
      
      if (conversao == true)
        converte(e.value,e.name,i);
    }
    if (flagConfirma==1){
      if (!confirma())
		return false;
	  substituiVirgulas(form, aValida);
      return true;
    }
    else{
    	substituiVirgulas(form, aValida);
	    return true;
	}
  }
  
  msg  = "______________________________________________________\n\n";
  msg += 'Por favor, verifique a informação submetida e carregue em OK.\n';
  msg += "______________________________________________________\n\n"
    
  if (campos_vazios)
    msg += ' - São de preenchimento obrigatório os seguintes campos:' + campos_vazios + '\n';
  if (erros)
    msg += '\n - Os seguintes campos encontram-se mal formatados:\n';
  
  msg += erros;
  alert(msg);
  msg = "";
  campos_vazios = "";
  erros = "";
  
  //faz o focus do campo em que ocorreu o primeiro erro
  if (campoPrimeiroErro!=""){
    if (campoData==false) 
	    document.all[campoPrimeiroErro].focus();
     // eval("document." + form + "." + campoPrimeiroErro + ".focus()");
      
    campoData=false;
  }

  return false;
}
	

function ietruebody() { return (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body }	
	
function tooltip(obj){
	var ie=document.all
	var ns6=document.getElementById && !document.all
	if (ie||ns6) {
		var tipobj=document.all?document.all[obj] : document.getElementById? document.getElementById(obj) : ""
		var curX=(ns6)?nsmousepos.pageX : event.x+ietruebody().scrollLeft;
		var curY=(ns6)?nsmousepos.pageY : event.y+ietruebody().scrollTop;
		var rightedge=ie&&!window.opera? ietruebody().clientWidth-event.clientX : window.innerWidth-nsmousepos.clientX-16
		var bottomedge=ie&&!window.opera? ietruebody().clientHeight-event.clientY : window.innerHeight-nsmousepos.clientY
		var leftedge= -1000
		
		if (rightedge<tipobj.offsetWidth) 
			tipobj.style.left=ie? ietruebody().scrollLeft+event.clientX-tipobj.offsetWidth+"px" : window.pageXOffset+nsmousepos.clientX-tipobj.offsetWidth+"px"
		else if (curX<leftedge) 
			tipobj.style.left="5px"
		else 
			tipobj.style.left=curX+"px"
			
		if (bottomedge<tipobj.offsetHeight) 
			tipobj.style.top=ie? ietruebody().scrollTop+event.clientY-tipobj.offsetHeight+16+"px" : window.pageYOffset+nsmousepos.clientY-tipobj.offsetHeight-16+"px"
		else tipobj.style.top=curY+16+"px"
			tipobj.style.visibility="visible"
		document.body.style.cursor="help";
	}

}
	
	
function hidetip(obj){
	var ie=document.all
	var ns6=document.getElementById && !document.all
	if (ie||ns6) {
		var tipobj=document.all?document.all[obj] : document.getElementById? document.getElementById(obj) : ""
		tipobj.style.visibility="hidden";
		tipobj.style.left="-1000px";
		document.body.style.cursor="auto";
	}
}	


var encN=1;

// ENCODES, IN UNICODE FORMAT, ALL TEXT AND THEN ESCAPES THE OUTPUT
function encodeTxt(s){
	s=escape(s);
	var ta=new Array();
	for(i=0;i<s.length;i++)ta[i]=s.charCodeAt(i)+encN;
	return ""+escape(eval("String.fromCharCode("+ta+")"))+encN;
}

// DECODES AND UNESCAPES ALL TEXT.
function decodeTxt(s){
	var s1=unescape(s.substr(0,s.length-1));
	var t='';
	for(i=0;i<s1.length;i++)t+=String.fromCharCode(s1.charCodeAt(i)-s.substr(s.length-1,1));
	return unescape(t);
}


// CONVERTS *ALL* CHARACTERS INTO ESCAPED VERSIONS.
function escapeTxt(os){
	var ns='';
	var t;
	var chr='';
	var cc='';
	var tn='';
	for(i=0;i<256;i++){
		tn=i.toString(16);
		if(tn.length<2)
			tn="0"+tn;
		cc+=tn;
		chr+=unescape('%'+tn);
	}
	cc=cc.toUpperCase();
	os.replace(String.fromCharCode(13)+'',"%13");
	for(q=0;q<os.length;q++){
		t=os.substr(q,1);
		for(i=0;i<chr.length;i++){
			if(t==chr.substr(i,1)){
				t=t.replace(chr.substr(i,1),"%"+cc.substr(i*2,2));
				i=chr.length;
			}	
		}
		ns+=t;
	}
	return ns;
}


// SIMPLY UNESCAPES TEXT (ONLY INCLUDED TO MAKE A COMPLEMENTARY FUNCTION FOR escapeTxt()
function unescapeTxt(s){
	return unescape(s);
}

// WRITES THE DECODED STRING (s) TO THE DOCUMENT WHEREVER THIS FUNCTION IS CALLED
function wF(s){
	document.write(decodeTxt(s));
}



      function ltrim( s )
      {
        var lpatt = new RegExp( "^ *(.*)$" );
        var parse = s.match( lpatt );
        if (null==parse)
          return "";
        else
          return parse[1];
      }

      function rtrim( s )
      {
        var rpatt = new RegExp( "^(.*[^ ]) *$" );
        var parse = s.match( rpatt );
        if (null==parse)
          return "";
	else
          return parse[1];
      }


/**
  * Get last day of month taking into account leap years.
  * @param month [0..11]
  * @param year  (4 digits)
*/
  function getLastDay(month, year) {

    switch(month) {
      case 0:
      case 2:
      case 4:
      case 6:
      case 7:
      case 9:
      case 11:
        return 31;
      case 3:
      case 5:
      case 8:
      case 10:
        return 30;
      case 1:
	return ( (year%400==0) || ((year%4==0) && (year%100!=0)) ) ? 29 : 28;
    } // end switch()
    return 0;
  } // getLastDay()
  
  // ----------------------------------------------------------
 

  /**
    * Verify that a string represents a valid date
    * @param Input string
    * @param Date format. Currently only "d" is supoported as
    *        a format identifier, corresponding to "YYYY-MM-DD"
  */
  function isDate (dtexpr, dtformat) {
    var exp = new RegExp("[0-9]{4}-[0-9]{2}-[0-9]{2}");
    var ser = dtexpr.split("-");
    var ret;
    var yy;
    var mm;
    var dd;
  
    if (dtformat=="d") {
      if (exp.test(dtexpr)) {
	    dd = parseInt(ser[0],10);
	    mm = parseInt(ser[1],10)-1;
        yy = parseInt(ser[2],10);
      
        if (mm<0 || mm>12) {
          ret = false;
        }
        else if (dd>getLastDay(mm,yy)) {
          ret = false;
        }
        else
          ret = true;                
      }
      else {
        ret = false;
      }
    }
    else {
      ret = false;
    }
    
    return ret;
  } // isDate()      
      
function submitenter(myfield, e, val) {
	var keycode;
	if (window.event) keycode = window.event.keyCode;
	else if (e) keycode = e.which;
	else return true;
	
	if (keycode == 13) {
		if (val != null) {
			if (!val()) {				 	  
				return true;
			}
			myfield.form.submit();
			return false;		
		}
	} else {
		return true;
	}
}

function desactivarWidgets(myForm, estado) {
	for (i = 0; i < myForm.length; i++) {
		var tempobj = myForm.elements[i];
		var ty = tempobj.type.toLowerCase();
		var vl = tempobj.value;

		if (ty == "submit" || ty == "reset" || ty == "select-one") {
			tempobj.disabled = estado;
			
			// Recriar o elemento com hidden para que possa ser usado
			if (estado == true) {
				var el = document.createElement("input");
				el.name = tempobj.name;
				el.type = "hidden";
				el.value = vl;
				document.myForm.appendChild(el);
			}
		}			
	}		
}


function getContext() {		
	var tmp = location.pathname.substring(1, location.pathname.length);
	tmp = tmp.substring(0, tmp.indexOf('/'));
	return tmp;
}

function trim (s) {
	if (s.length == 0) return s;
    return s.replace(/^\s*(.*?)\s*$/,'$1');
}

function isEmpty(s) {
	return (s == null || s.length == 0 || trim(s).length == 0)
}


function addfractions(num1, den1, num2, den2) {
	if (num1 == 0) {
		var res = new Array(2);
		res[0] = num2;
		res[1] = den2;
				
		return res;
	}
	
	if (num2 == 0) {
		var res = new Array(2);
		res[0] = num1;
		res[1] = den1;
				
		return res;
	}	

	if ((den1==0)||(den2==0)){
		return;
	}

	var lcd = lcm(den1,den2);
	num1 = lcd/den1*num1;
	num2 = lcd/den2*num2;
	
	var res = new Array(2);
	res[0] = num1 + num2;
	res[1] = lcd;

	return res;
}

function lcm (x,y) {
	return x*y/gcf(x,y);
}

function gcf (x,y) {
	var x1 = Math.min(x,y);
	var y1 = Math.max(x,y);
	if (x1==y1) { return x; }
	return euclid(x1,y1);
}

function euclid(x,y) {
	var a = y%x
	if (a==0) {return x;}
	return euclid (a, x);
}



	// --- Calendar functions

	var oldLink = null;

	// code to change the active stylesheet
	function setActiveStyleSheet(link, title) {
	  var i, a, main;
	  for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
	    if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")) {
	      a.disabled = true;
	      if(a.getAttribute("title") == title) a.disabled = false;
	    }
	  }
	  if (oldLink) oldLink.style.fontWeight = 'normal';
	  oldLink = link;
	  link.style.fontWeight = 'bold';
	  return false;
	}

	// This function gets called when the end-user clicks on some date.
	function selected(cal, date) {
	  cal.sel.value = date; // just update the date in the input field.
	  if (cal.dateClicked){
	    // if we add this call we close the calendar on single-click.
	    // just to exemplify both cases, we are using this only for the 1st
	    // and the 3rd field, while 2nd and 4th will still require double-click.

	    //obj = document.all.data_alocacao;
	    //preencheDiaSemana(obj);
	    
	    cal.callCloseHandler();
	   }
	}

	// And this gets called when the end-user clicks on the _selected_ date,
	// or clicks on the "Close" button.  It just hides the calendar without
	// destroying it.
	function closeHandler(cal) {
	  cal.hide();   
	  calendar = null;                     // hide the calendar
	}

	// This function shows the calendar under the element having the given id.
	// It takes care of catching "mousedown" signals on document and hiding the
	// calendar if the click was outside.
	function showCalendar(id, format) {
	  var el = document.getElementById(id);
	  if (calendar != null) {
	    // we already have some calendar created
	    calendar.hide();                 // so we hide it first.
	  } else {
	    // first-time call, create the calendar.
	    var cal = new Calendar(false, null, selected, closeHandler);
	    // uncomment the following line to hide the week numbers
	    // cal.weekNumbers = false;
	    calendar = cal;                  // remember it in the global var
	    cal.setRange(1900, 2070);        // min/max year allowed.
	    cal.create();
	  }

	  calendar.setDateFormat(format);    // set the specified date format
	  calendar.parseDate(el.value);      // try to parse the text in field
	  calendar.sel = el;                 // inform it what input field we use
	  calendar.showAtElement(el);        // show the calendar below it
	
	  //return false;
	}

	var MINUTE = 60 * 1000;
	var HOUR = 60 * MINUTE;
	var DAY = 24 * HOUR;
	var WEEK = 7 * DAY;
	
	// If this handler returns true then the "date" given as
	// parameter will be disabled.  In this example we enable
	// only days within a range of 10 days from the current
	// date.
	// You can use the functions date.getFullYear() -- returns the year
	// as 4 digit number, date.getMonth() -- returns the month as 0..11,
	// and date.getDate() -- returns the date of the month as 1..31, to
	// make heavy calculations here.  However, beware that this function
	// should be very fast, as it is called for each day in a month when
	// the calendar is (re)constructed.
	function isDisabled(date) {
	  var today = new Date();
	  return (Math.abs(date.getTime() - today.getTime()) / DAY) > 10;
	}
	
	//  Fim Calendar Functions --------------
	
	
	
	