// -----------------------------------------------------------------------------
// Generic Form Validation
//
// Copyright (C) 2000 Jacob Hage - [jacobhage@hotmail.com]
// Distributed under the terms of the GNU Library General Public License
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// Initializing script  - setting global variables
// -----------------------------------------------------------------------------
var checkObjects		= new Array(); 	// Array containing the objects to validate.
var errors				= ""; 			// Variable holding the error message.
var returnVal			= false; 		// General return value. The validated form will only be submitted if true.


// -----------------------------------------------------------------------------
// define - Call this function in the beginning of the page. I.e. onLoad.
//
// n = name of the input field (Required)
// type= string, num, email (Required)
// min = the value must have at least [min] characters (Optional)
// max = the value must have maximum [max] characters (Optional)
// optional = true|false
// d = (Optional)
// -----------------------------------------------------------------------------
function define(n,type,HTMLname,min,max,optional,d){
	var p;
	var x;
	if(!d) d=document;

	if(!(x=d[n])&&d.all) x=d.all[n];

  	for (var i=0;!x&&i<d.forms.length;i++){
  		x=d.forms[i][n];
  	}
	for(i=0;!x&&d.layers&&i<d.layers.length;i++){
		x=define(n,type,HTMLname,min,max,optional,d.layers[i].document);
		return x;
	}

	// Create Object. The name will be "V_something" where something is the "n" parameter above.
	eval("V_"+n+" = new formResult(x,type,HTMLname,min,max,optional);");
	checkObjects[eval(checkObjects.length)] = eval("V_"+n);
}

// -----------------------------------------------------------------------------
// formResult - Used internally to create the objects
// -----------------------------------------------------------------------------
function formResult(form,type,HTMLname,min,max,optional){
	this.form = form;
	this.type = type;
	this.HTMLname = HTMLname;
	this.min  = min;
	this.max  = max;
	this.optional = optional;
}

// -----------------------------------------------------------------------------
// validate - Call this function onSubmit and return the "returnVal". (onSubmit="validate();return returnVal;")
// -----------------------------------------------------------------------------
function validate(){

    returnVal = true;

	if(checkObjects.length>0){
		errorObject = "";

		for(i=0;i<checkObjects.length;i++){
			validateObject 			= new Object();
			validateObject.form 	= checkObjects[i].form;
			validateObject.HTMLname = checkObjects[i].HTMLname;
			validateObject.val 		= checkObjects[i].form.value;
			validateObject.len 		= checkObjects[i].form.value.length;
			validateObject.min 		= checkObjects[i].min;
			validateObject.max 		= checkObjects[i].max;
			validateObject.type 	= checkObjects[i].type;
			validateObject.optional = checkObjects[i].optional;

			//Debug alert line
			//alert("validateObject: "+validateObject+"\nvalidateObject.val: "+validateObject.val+"\nvalidateObject.len: "+validateObject.len+"\nvalidateObject.min,validateObject.max: "+validateObject.min+","+validateObject.max+"\nvalidateObject.type: "+validateObject.type);

			// Checking input. If "min" and/or "max" is defined the input has to be within the specific range
			if (validateObject.type == "num" ||
                validateObject.type == "string" ||
                validateObject.type == "float") {

                if (validateObject.len <= 0) {
                    if (validateObject.optional) {
                        continue;
                    } else {
                        alert('é necessário preencher ' + validateObject.HTMLname);
                        if (!validateObject.form.disabled && String(validateObject.form.type)!='hidden' && String(validateObject.form.type)!='undefined') {
                            validateObject.form.focus();
                        }
                        returnVal = false;
                        break;
                    }
                }

                if ((validateObject.type == "float" && validateObject.len <= 0) ||
                    (validateObject.type == "float" && !isFloat(validateObject.val))) {
                       alert(validateObject.HTMLname + ' deve ser numérico (eventualmente com parte decimal - ex: 12,34)');
                       if (!validateObject.form.disabled && String(validateObject.form.type)!='hidden' && String(validateObject.form.type)!='undefined') {
                            validateObject.form.focus();
                        }
                       returnVal = false;
                       break;
                }

                if ((validateObject.type == "signedFloat" && validateObject.len <= 0) ||
                    (validateObject.type == "signedFloat" && !isSignedFloat(validateObject.val))) {
                       alert(validateObject.HTMLname + ' deve ser numérico (eventualmente com parte decimal - ex: 12,34)');
                       if (!validateObject.form.disabled && String(validateObject.form.type)!='hidden' && String(validateObject.form.type)!='undefined') {
                            validateObject.form.focus();
                        }
                       returnVal = false;
                       break;
                }


                if ((validateObject.type == "num" && validateObject.len <= 0) ||
                    (validateObject.type == "num" && isNaN(validateObject.val))) {
                       alert(validateObject.HTMLname + ' deve ser numérico');
                       if (!validateObject.form.disabled && String(validateObject.form.type)!='hidden' && String(validateObject.form.type)!='undefined') {
                            validateObject.form.focus();
                        }
                       returnVal = false;
                       break;
                } else if (!validateObject.min &&
                           validateObject.len <= 0) {
                         alert('é necessário preencher ' + validateObject.HTMLname);
                         if (!validateObject.form.disabled && String(validateObject.form.type)!='hidden' && String(validateObject.form.type)!='undefined') {
                            validateObject.form.focus();
                        }
                         returnVal = false;
                         break;
				} else if (validateObject.min &&
                           validateObject.max &&
                           (validateObject.len < validateObject.min ||
                            validateObject.len > validateObject.max)) {
                            if (validateObject.min == validateObject.max) {
                                alert(validateObject.HTMLname + ' deve ter ' + validateObject.min + ' caracteres');
                            } else {
                                alert(validateObject.HTMLname + ' deve ter entre ' + validateObject.min + ' e ' + validateObject.max + ' caracteres');
                            }
                             if (!validateObject.form.disabled && String(validateObject.form.type)!='hidden' && String(validateObject.form.type)!='undefined') {
                               validateObject.form.focus();
                             }
                             returnVal = false;
                             break;
				} else if (validateObject.min &&
                           !validateObject.max &&
                           (validateObject.len < validateObject.min)) {
                         alert(validateObject.HTMLname + ' deve ter pelo menos ' + validateObject.min + ' caracteres');
                         if (!validateObject.form.disabled && String(validateObject.form.type)!='hidden' && String(validateObject.form.type)!='undefined') {
                            validateObject.form.focus();
                        }
                         returnVal = false;
                         break;
				} else if (validateObject.max &&
                          !validateObject.min &&
                          (validateObject.len > validateObject.max)) {
                        alert(validateObject.HTMLname + ' deve ter menos de ' + validateObject.max + ' caracteres');
                        if (!validateObject.form.disabled && String(validateObject.form.type)!='hidden' && String(validateObject.form.type)!='undefined') {
                            validateObject.form.focus();
                        }
                        returnVal = false;
                        break;
				} else if (!validateObject.min &&
                           !validateObject.max &&
                           validateObject.len <= 0) {
                         alert(validateObject.HTMLname + 'é necessário');
                         if (!validateObject.form.disabled && String(validateObject.form.type)!='hidden' && String(validateObject.form.type)!='undefined') {
                            validateObject.form.focus();
                         }
                         returnVal = false;
                         break;
				}
			} else if(validateObject.type == "email"){
				// Checking existense of "@" and ".". The length of the input must be at least 5 characters. The "." must neither be preceding the "@" nor follow it.
				if((validateObject.val.indexOf("@") == -1) ||
                   (validateObject.val.charAt(0) == ".") ||
                   (validateObject.val.charAt(0) == "@") ||
                   (validateObject.len < 6) ||
                   (validateObject.val.indexOf(".") == -1) ||
                   (validateObject.val.charAt(validateObject.val.indexOf("@")+1) == ".") ||
                   (validateObject.val.charAt(validateObject.val.indexOf("@")-1) == ".")) {

                   alert(validateObject.HTMLname + 'deve conter um e-mail válido');
                   if (!validateObject.form.disabled && String(validateObject.form.type)!='hidden' && String(validateObject.form.type)!='undefined') {
                       validateObject.form.focus();
                   }
                   returnVal = false;
                   break;
                }
			}
		}
	}



}

var digits = "0123456789";

var lowercaseLetters = "abcdefghijklmnopqrstuvwxyz"

var uppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

// whitespace characters
var whitespace = " \t\n\r";

// decimal point character differs by language and culture
var decimalPointDelimiter = ","

// CONSTANT STRING DECLARATIONS
// (grouped for ease of translation and localization)

var daysInMonth = new Array(12);
daysInMonth[1] = 31;
daysInMonth[2] = 29;   // must programmatically check this
daysInMonth[3] = 31;
daysInMonth[4] = 30;
daysInMonth[5] = 31;
daysInMonth[6] = 30;
daysInMonth[7] = 31;
daysInMonth[8] = 31;
daysInMonth[9] = 30;
daysInMonth[10] = 31;
daysInMonth[11] = 30;
daysInMonth[12] = 31;


// Check whether string s is empty.

function isEmpty(s)
{
	return (s == null || s.length == 0 || trim(s).length == 0)
}

function isRbEmpty(radiobutton) {

    for (var i = 0; i < radiobutton.length; i++) {
        if (radiobutton[i].checked) return false;
    }

    return true;
}


// Returns true if string s is empty or
// whitespace characters only.

function isWhitespace (s)
{

    // Is s empty?
    if (isEmpty(s)) return true;

    // Search through string's characters one by one
    // until we find a non-whitespace character.
    // When we do, return false; if we don't, return true.

    for (var i = 0; i < s.length; i++)
    {
        // Check that current character isn't whitespace.
        var c = s.charAt(i);

        if (whitespace.indexOf(c) == -1) return false;
    }

    // All characters are whitespace.
    return true;
}


// Returns true if character c is an English letter
// (A .. Z, a..z).
//
// NOTE: Need i18n version to support European characters.
// This could be tricky due to different character
// sets and orderings for various languages and platforms.

function isLetter (c)
{   return ( ((c >= "a") && (c <= "z")) || ((c >= "A") && (c <= "Z")) )
}


// Returns true if character c is a digit
// (0 .. 9).

function isDigit (c)
{   return ((c >= "0") && (c <= "9"))
}


// Returns true if character c is a letter or digit.

function isLetterOrDigit (c)
{   return (isLetter(c) || isDigit(c))
}


// isInteger (STRING s)
//
// Returns true if all characters in string s are numbers.
//
// Accepts non-signed integers only. Does not accept floating
// point, exponential notation, etc.

function isInteger (s)
{

    if (isEmpty(s)) return false;

    // Search through string's characters one by one
    // until we find a non-numeric character.
    // When we do, return false; if we don't, return true.

    for (var i = 0; i < s.length; i++)
    {
        // Check that current character is number.
        var c = s.charAt(i);

        if (!isDigit(c)) return false;
    }

    // All characters are numbers.
    return true;
}


// isSignedInteger (STRING s)
//
// Returns true if all characters are numbers;
// first character is allowed to be + or - as well.
//
// Does not accept floating point, exponential notation, etc.

function isSignedInteger (s)
{
    if (isEmpty(s)) return false;

    else {
        var startPos = 0;

        // skip leading + or -
        if ( (s.charAt(0) == "-") || (s.charAt(0) == "+") )
           startPos = 1;
        return (isInteger(s.substring(startPos, s.length)))
    }
}


// isPositiveInteger (STRING s)
//
// Returns true if string s is an integer > 0.

function isPositiveInteger (s)
{
    if (isEmpty(s)) return false;

    return (isSignedInteger(s) && Number (s) > 0);
}


// isNonnegativeInteger (STRING s)
//
// Returns true if string s is an integer >= 0.

function isNonnegativeInteger (s)
{
    if (isEmpty(s)) return false;

    return (isSignedInteger(s) && Number (s)>=0);
}


// isNegativeInteger (STRING s)
//
// Returns true if string s is an integer < 0.

function isNegativeInteger (s)
{
    if (isEmpty(s)) return false;

    return (isSignedInteger(s) && Number(s)<0);
}


// isNonpositiveInteger (STRING s)
//
// Returns true if string s is an integer <= 0.

function isNonpositiveInteger (s)
{
    if (isEmpty(s)) return false;

    return (isSignedInteger(s) && Number(s)<=0);
}


// isFloat (STRING s)
//
// True if string s is an unsigned floating point (real) number.
//
// Also returns true for unsigned integers. If you wish
// to distinguish between integers and floating point numbers,
// first call isInteger, then call isFloat.
//
// Does not accept exponential notation.

function isFloat (s)

{
    var seenDecimalPoint = false;

    if (isEmpty(s)) return false;

    if (s == decimalPointDelimiter) return false;

    // Search through string's characters one by one
    // until we find a non-numeric character.
    // When we do, return false; if we don't, return true.

    for (var i = 0; i < s.length; i++)
    {
        // Check that current character is number.
        var c = s.charAt(i);

        if ((c == decimalPointDelimiter) && !seenDecimalPoint) seenDecimalPoint = true;
        else if (!isDigit(c)) return false;
    }

    // All characters are numbers.
    return true;
}


// isSignedFloat (STRING s)
//
// True if string s is a signed or unsigned floating point
// (real) number. First character is allowed to be + or -.
//
// Also returns true for unsigned integers. If you wish
// to distinguish between integers and floating point numbers,
// first call isSignedInteger, then call isSignedFloat.
//
// Does not accept exponential notation.

function isSignedFloat (s)
{
    if (isEmpty(s)) return false;

    else {
        var startPos = 0;

        // skip leading + or -
        if ( (s.charAt(0) == "-") || (s.charAt(0) == "+") )
           startPos = 1;
        return (isFloat(s.substring(startPos, s.length)))
    }
}


// isAlphabetic (STRING s)
//
// Returns true if string s is English letters
// (A .. Z, a..z) only.

function isAlphabetic (s)
{

    if (isEmpty(s)) return false;

    // Search through string's characters one by one
    // until we find a non-alphabetic character.
    // When we do, return false; if we don't, return true.

    for (var i = 0; i < s.length; i++)
    {
        // Check that current character is letter.
        var c = s.charAt(i);

        if (!isLetter(c))
        return false;
    }

    // All characters are letters.
    return true;
}


// isAlphanumeric (STRING s)
//
// Returns true if string s is English letters
// (A .. Z, a..z) and numbers only.

function isAlphanumeric (s)
{

    if (isEmpty(s)) return false;

    // Search through string's characters one by one
    // until we find a non-alphanumeric character.
    // When we do, return false; if we don't, return true.

    for (var i = 0; i < s.length; i++)
    {
        // Check that current character is number or letter.
        var c = s.charAt(i);

        if (! (isLetter(c) || isDigit(c) ) )
        return false;
    }

    // All characters are numbers or letters.
    return true;
}


// isYear (STRING s)
//
// isYear returns true if string s is a valid
// Year number.  Must be 4 digits only.

function isYear (s)
{
	if (isEmpty(s)) return false;
    if (!isPositiveInteger(s)) return false;
    return (s.length==4);
}


// isIntegerInRange (STRING s, INTEGER a, INTEGER b)
//
// isIntegerInRange returns true if string s is an integer
// within the range of integer arguments a and b, inclusive.

function isIntegerInRange (s, a, b)
{
    if (isEmpty(s)) return false;

    // Catch non-integer strings to avoid creating a NaN below,
    // which isn't available on JavaScript 1.0 for Windows.
    if (!isInteger(s)) return false;

    // Now, explicitly change the type to integer via Number
    // so that the comparison code below will work both on
    // JavaScript 1.2 (which typechecks in equality comparisons)
    // and JavaScript 1.1 and before (which doesn't).
    var num = Number (s);
    return ((num >= a) && (num <= b));
}


// isMonth (STRING s)
//
// isMonth returns true if string s is a valid
// month number between 1 and 12.

function isMonth (s)
{
    if (isEmpty(s)) return false;
    return isIntegerInRange (s, 1, 12);
}


// isDay (STRING s)
//
// isDay returns true if string s is a valid
// day number between 1 and 31.

function isDay (s)
{
    if (isEmpty(s)) return false;
    return isIntegerInRange (Number(s), 1, 31);
}


// daysInFebruary (INTEGER year)
//
// Given integer argument year,
// returns number of days in February of that year.

function daysInFebruary (year)
{   // February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (  ((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0) ) ) ? 29 : 28 );
}


// isDate (STRING)
//
// isDate returns true if string argument forms a valid date (yyyy-mm-dd).

function isDate (date)
{
	if (date.length == 0) return true;
	var re = /^\d\d\d\d\-\d\d\-\d\d$/;
	if (!re.test(date)) return false;
	var year = date.substring(0,4);
	var month = date.substring(5,7);
	if (month < 1 || month > 12) return false;
	var day = date.substring(8,10);
	var max = 31;
	if (month == 4 || month == 6 || month == 9 || month == 11) {
		max = 30;
	} else if (month == 2 && !isLeapYear(year)) {
		max = 28;
	} else if (month == 2 && isLeapYear(year)) {
		max = 29;
	}
	if (day < 1 || day > max) return false;
	return true;
}

function isLeapYear (year) {
	return ((year % 400 == 0) || ((year % 4 == 0)&&(year % 100 != 0)));
}


// isHour (STRING s)
//
// isHour returns true if string s is a valid
// hour number between 0 and 23.

function isHour (s) {
    if (isEmpty(s)) return false;
    return isIntegerInRange (s, 0, 23);
}

// isMinuteSecond (STRING s)
//
// isMinuteSecond returns true if string s is a valid
// minute or second number between 0 and 59.

function isMinuteSecond (s) {
    if (isEmpty(s)) return false;
    return isIntegerInRange (s, 0, 59);
}

// isTime (STRING)
//
// isTime returns true if string argument forms a valid time (HH:mm:ss).

function isTime (s)
{
	var time = s.split(':');

	if (time.length != 3)	return false;

	if (! (isHour(time[0]) && isMinuteSecond(time[1]) && isMinuteSecond(time[2]))) return false;

  return true;
}

function parseDate (s)
{
	if (!isDate(s))
		return null;

	var date = s.split('-');
	return new Date(Number(date[0]),Number(date[1])-1,Number(date[2]));
}

function somaAno(data,nAno){
var novaData=  new Date(data);
novaData.setFullYear(novaData.getFullYear()+nAno);
return novaData;
}
function somaMes(data,nMes){
var novaData=  new Date(data);
novaData.setMonth(novaData.getMonth()+nMes);
return novaData;
}
function somaDia(data,nDia){
var novaData=  new Date(data);
novaData.setDate(novaData.getDate()+nDia);
return novaData;
}

function somaAnoMesDia(data,nAno,nMes,nDia){
var novaData= new Date(data);
novaData=somaAno(novaData,nAno);
novaData=somaMes(novaData,nMes);
novaData=somaDia(novaData,nDia);
return novaData;
}
function isEmptyDate (date) {
	if (date == null) return true;
	if (trim(date) == '') return true;
	date = date.substring(0,4) + date.substring(5,7) + date.substring(8,10);
	return trim(date) == '';
}

function isCodigoPostal (codPostal) {
	if (!codPostal.match(/^[0-9]{4,4}-[0-9]{3,3}$/)) return false;
	return true;
}

function isParte (parte) {
	if (!parte.match(/^[0-9]+\/[0-9]+$/)) return false;
	return true;
}

function isPermilagem (permil) {
	return isEuros(permil); // a formatação da permilagem é parecida à do euro
}

// ATENÇÃO: aceita 2 números depois do T, tal como T00
// retirada a possibilidade de ser p.ex T0+1 a pedido da Engª Gabriela em 2003-12-09
function isTipologia (tipologia) {
	if (tipologia.match(/^([Tt][0-9]{1,3}|[0-9]{1,4})$/)) return true;
//	if (tipologia.match(/^([Tt][0-9]{1,2}(\+[1-9])?|[1-9][0-9]{0,3})$/)) return true;
	return false;
}

function getRepeatedChar (c, size) {
	var str = "";
	for (var i = 0; i < size; i++) {
		str += c;
	}
	return str;
}

function getZeroString (size) {
	return getRepeatedChar('0', size);
}

function formatCasasDecimais (valor, casasDecimais) {
	valor = trim(valor);
	var valorSize = isEmpty(valor) ? 0 : valor.length;
	var empty = getZeroString(casasDecimais - valorSize);
	return isEmpty(valor) ? empty : valor + empty;
}

// formatDecimal (STRING separator, STRING decimal, INTEGER inteiroSize, INTEGER precisao)
//
// formatDecimal returns decimal formatado

function formatDecimal (separador, valor, casasInteiras, casasDecimais) {
	if (isEmpty(valor)) return valor;
	if (isDecimal(separador, valor, casasInteiras, casasDecimais)) return valor;

	valor = trim(valor);
	var pos = valor.indexOf(separador);
	if (pos == -1) return valor + separador + formatCasasDecimais("", casasDecimais);

	var inteiro = trim(valor.substring(0, pos));
	var centimos = trim(valor.substring(pos+1));
	return inteiro + separador + formatCasasDecimais(centimos, casasDecimais);
}

function isDecimal (separador, valor, casasInteiras, casasDecimais) {
	if (isEmpty(valor)) return false;
	var pattern = "[[0-9]{1,"+casasInteiras+"}"+separador+"[0-9]{"+casasDecimais+"}";

	return valor.match(pattern) == valor;
}

function isFormatableDecimal (separador, valor, casasInteiras, casasDecimais) {
	if (isEmpty(valor)) return false;
	var formated = formatDecimal(separador, valor, casasInteiras, casasDecimais);
	return isDecimal(separador, formated, casasInteiras, casasDecimais);
}


function isEuros (text) {
	if (text.length < 4) return false;
	var sep = text.charAt(text.length-3);
	if (sep != ',' && sep != '.') return false;
	var centims = text.substring(text.length - 2);
	if (!centims.match(/^\d\d$/)) return false;
	var euro = text.substring(0, text.length - 3);
	if (!euro.match(/^[0-9\,\.]+$/)) return false;
	return euro.replace(/\,/g,'.') == formatThousands(euro);
}

function formatEuros (text) {
	if (text.length == 0) return text;
	var pos = Math.max(text.lastIndexOf(','), text.lastIndexOf('.'));
	var centims = pos == -1 || pos == text.length - 1 ? '00' : text.substring(pos+1);
	if (centims.length == 1) centims = centims + '0';
	if (centims.length > 2) centims = String(Math.round(Number(centims.substring(0,2)+'.'+centims.substring(2))));
	var euro = pos == -1 ? text : euro = text.substring(0,pos);
	return formatThousands(euro)+','+centims;
}

function removeSeparators (text) {
	if (text.length == 0) return text;	
	while (text.lastIndexOf(',') > 0) text = text.replace(',', '');
	while (text.lastIndexOf('.') > 0) text = text.replace('.', '');	
	return text;
}

function formatThousands (text) {
	text = text.replace(/\D/g,'');
	if (text.length <= 3) return text;
	var mod = (text.length - 1) % 3;
	if (mod == 0) return text.charAt(0) + '.' + formatThousands(text.substring(1));
	return text.charAt(0) + formatThousands(text.substring(1));
}

function getEuroCents (text) {
	if (text.length == 0) return text;
	return Number(text.replace(/\D/g,''));
}

function isSF(s) {
	return (s.length==4 && isPositiveInteger(s));
}

function isNumeroContribuinte(s) {

	if (s.length!=9 || !isPositiveInteger(s)) {
		return false;
	}

	var soma,resto,digi;
    var nif = new Array(9);
  	for (var i=0;i<9;i++) {
    	nif[i] = Number(s.substring(i,i+1));
  	}
  	for (var i=0,soma=0;i<8;i++) {
    	soma += nif[i]*(9-i);
  	}
  	resto = soma%11;
  	digi = 11-resto;
  	if (digi>9) digi=0;
  	return (digi==nif[8]);

}

/*****
** Validador de NIB
*****/
var check_digit_size = 2;
var tamanhoNIB = 21;
var position = tamanhoNIB - check_digit_size;
var size = check_digit_size;

function calculateWeightNib(str) {
	var sum = 0;
	var weight = [91, 77, 95, 58, 64, 84, 86, 28, 61, 74, 85, 57, 93,
				  19, 31, 71, 75, 56, 25, 51, 73, 17, 89, 38, 62, 45, 53, 15, 50, 5, 49,
				  34, 81, 76, 27, 90, 9, 30, 3];

var initfactor = weight.length - str.length;

for (var i = 0; i < str.length; ++i) {
	var ch = str.charCodeAt(i) - 48;
	sum += ch * weight[i + initfactor];
}

	return (97 - (sum % 97) +1);
}

function getCheckDigitNib(str) {
		return parseInt(str.substring(position,position + size));
}

function getNumberNib(str) {
		return str.substring(0, position) + str.substring(position + size);
	}

function isNib(str){
	if(isEmpty(str))
		return false;
	if(str.length != 21)
		return false;
	if(str.replace('0','')=='')
		return false;	
  
	return getCheckDigitNib(str) == calculateWeightNib(getNumberNib(str));			
}


function isNumeroContribuinteColectivo(s) {
	if (!isNumeroContribuinte(s)) return false;
  	if ((s.charAt(0)!='5')&&(s.charAt(0)!='6')&&(s.charAt(0)!='7')&&(s.charAt(0)!='9')) return false;
  	return true;
}

function isNumeroContribuinteSingular(s) {
	if (!isNumeroContribuinte(s)) return false;
  	if ((s.charAt(0)!='1')&&(s.charAt(0)!='2')&&(s.charAt(0)!='3')&&(s.charAt(0)!='4')) return false;
  	return true;
}

function isNumeroContribuinteNaoResidente(s) {
	if (!isNumeroContribuinte(s)) return false;
  	if ((s.charAt(0)!='9')||(s.charAt(1)!='8')) return false;
  	return true;
}

/* FUNCTIONS TO REFORMAT DATA. */

// Strips leading and trailing whitespaces from string

function trim (s) {
	if (s.length == 0) return s;
    return s.replace(/^\s*(.*?)\s*$/,'$1');
}

// Strips leading and trailing whitespaces from field value

function trimField (theField)
{
	theField.value = trim(theField.value);
	return theField.value;
}


/* FUNCTIONS TO NOTIFY USER OF INPUT REQUIREMENTS OR MISTAKES. */


// Notify user that required field theField is empty.
// String s describes expected contents of theField.value.
// Put focus in theField and return false.

function warnEmpty (theField, s)
{
	alert(s);
	if (!theField.disabled && String(theField.type)!='hidden' && String(theField.type)!='undefined') {
		theField.focus();
	}
    return false;
}


// Notify user that contents of field theField are invalid.
// String s describes expected contents of theField.value.
// Put select theField, put focus in it, and return false.

function warnInvalid (theField, s)
{
    alert(s);
	if (!theField.disabled && String(theField.type)!='hidden' && String(theField.type)!='undefined') {
		theField.focus();
    	theField.select();
    }
    return false;
}

function asArray(obj) {
    var array = null;
    if (isFormField(obj)) {
        array = new Array(1);
        array[0] = obj;
    } else {
        array = obj;
    }
    return array;
}

function isFormField(obj) {
    return (typeof obj.name != 'undefined');
}

function setSelected (field, value) {
	for (var i = 0; i < field.options.length; i++) {
		var opt = field.options[i];
		if (opt.value == value) {
			opt.selected = true;
			break;
		}
	}
	if (field.options[0].length > 0) field.options[0].selected = true;
}

function isTelefone (value) {
	if (value == '' || trim(value) == '') return false;
	if (value.length != 9) return false;
	if (!isPositiveInteger(value)) return false;
	var ch = value.charAt(0);
	//fixos e telemoveis
	if (ch != '2' && ch != '9') return false;
	return true;
}

function isSenhaValida (value) {
	if (value == '') return false;
	if (value.length < 8) return false;
	if (value.length > 16) return false;
	return true;
}

function isEmailValido (email) {
	return email != '' &&
			trim(email).indexOf(" ") == -1 &&
			email.length > 5 &&
			email.indexOf("@") != -1 &&
			email.charAt(0) != '@' &&
			email.lastIndexOf('@') == email.indexOf('@') &&
			email.indexOf('.') != -1 &&
			email.charAt(0) != '.' &&
			email.charAt(email.indexOf('@')+1) != '.' &&
			email.charAt(email.indexOf('@')-1) != '.' &&
			email.lastIndexOf('.') > email.indexOf('@') &&
			email.lastIndexOf('.') < email.length - 2 &&
			email.toLowerCase() != 'senhas@dgci.min-financas.pt' &&
			email.toLowerCase() != 'consultas_irs@dgci.min-financas.pt' &&
			email.toLowerCase() != 'consultas_irc@dgci.min-financas.pt' &&
			email.toLowerCase() != 'consultas_iva@dgci.min-financas.pt' &&
			email.toLowerCase() != 'tocs@dgci.min-financas.pt' &&
			email.toLowerCase() != 'de_retirselo@dgci.min-financas.pt' &&
			email.toLowerCase() != 'sugestoes@dgci.min-financas.pt' &&
			email.toLowerCase() != 'info@dgci.min-financas.pt';
			//não estão a ser validados os carecteres especiais '?', '?', etc...

}

function validateYear (year) {
	if (isEmpty(year.value)) {
		return warnEmpty(year, "Por favor indique o Ano");
	}
	if (!isYear(year.value)) {
		return warnInvalid(year, "O Ano indicado é inválido");
	}
	return true;
}

function validateContribuinteWithUser (contribuinte) {
	var slashIdx = contribuinte.value.indexOf("/");
	if (slashIdx == -1) {
		return warnInvalid(contribuinte, "Deve introduzir o Nº de Contribuinte seguido de '/' e do Nº de Utilizador");
	}
	else{
		return validateContribuinte(contribuinte);
	}
}

function validateContribuinte (contribuinte) {
	if (isEmpty(contribuinte.value)) {
		return warnEmpty(contribuinte, "Por favor indique o Nº de Contribuinte");
	}

	var nif, userId, slashIdx = contribuinte.value.indexOf("/");
	if (slashIdx == -1) {
	    nif = contribuinte.value;
	    userId = "0";
	} else {
	    nif = contribuinte.value.substring(0, slashIdx);
	    userId = contribuinte.value.substring(slashIdx + 1);
	}

	if (!isNumeroContribuinte(nif)) {
		return warnInvalid(contribuinte, "O Nº de Contribuinte indicado é inválido");
	}

	if (!isInteger(userId)) {
		return warnInvalid(contribuinte, "O Nº de Utilizador indicado é inválido");
	}

	return true;
}

function validateSenha (senha, name) {
	if (!name) name = 'Senha';
	if (isEmpty(senha.value)) {
		return warnEmpty(senha, 'Por favor indique a '+name+'.');
	}
	if (!isSenhaValida(senha.value)) {
		return warnInvalid(senha, "A "+name+" indicada não tem o comprimento correcto:\nDeve conter entre 8 e 16 caracteres!");
	}
	return true;
}

function validateNovaSenha (contribuinte, nova, confirm) {
	if (!validateSenha(nova, 'Nova Senha')) return false;
	if (!validateSenha(confirm, 'Confirmação Nova Senha')) return false;
	if (nova.value == contribuinte.value) {
		return warnInvalid(nova, "A Nova Senha indicada não pode ser igual ao Nº de Contribuinte");
	}
	if (nova.value != confirm.value) {
		return warnInvalid(confirm, "A Confimação Nova Senha indicada é diferente da Nova Senha");
	}
	return true;
}

function validateEmail (email) {
	if (isEmpty(email.value)) {
		return warnEmpty(email, "Para receber notificações, deve preencher o E-mail!");
	}
	if (!isEmailValido(email.value)) {
		return warnInvalid(email, "Por favor, indique um E-mail valido!");
	}
	return true;
}

function validateTelefone (telefone) {
	if (isEmpty(telefone.value)) {
		return warnEmpty(telefone, "Por favor, introduza o seu numero de telefone!");
	}
	if (!isTelefone(telefone.value)) {
		return warnInvalid(telefone, "Por favor, introduza um numero de telefone valido!");
	}
	return true;
}

function validateMorada (morada) {
	if (isEmpty(morada.value)) {
		return warnEmpty(morada, "Por favor indique a Morada Fiscal");
	}
	return true;
}

function validatePergunta (pergunta) {
	if (isEmpty(pergunta.value)) {
		return warnEmpty(pergunta, "Por favor indique a Pergunta");
	}
	return true;
}

function validateResposta (resposta) {
	if (isEmpty(resposta.value)) {
		return warnEmpty(resposta, "Por favor indique a Resposta");
	}
	return true;
}

function validateRange(ffield, min, max, ferror) {
	if (eval(ffield).value.length > 0 && (eval(ffield).value < min || eval(ffield).value > max)) {
   		alert(ferror);
   		eval(ffield).focus();
   		returnVal = false;
   		return false;
	}
	return true;
}

function validateSMS (smson, telefone) {
	if (smson.value == 'on') {
		if (telefone.value.charAt(0) != '2' &&
			telefone.value.charAt(0) != '9') {
			return warnInvalid(telefone, 'Telefone inválido para envio de SMS');
		}
	}
	return true;
}

function autotab(original,destination){
    if (original.getAttribute&&original.value.length==original.getAttribute("maxlength"))
    destination.focus()
}

function isEuros (text) {
	if (text.length < 4) return false;
	var sep = text.charAt(text.length-3);
	if (sep != ',' && sep != '.') return false;
	var centims = text.substring(text.length - 2);
	if (!centims.match(/^\d\d$/)) return false;
	var euro = text.substring(0, text.length - 3);
	if (!euro.match(/^[0-9\,\.]+$/)) return false;
	return euro.replace(/\,/g,'.') == formatThousands(euro);
}

