/*
	@copyright Seem
*/
function Validator(array) {
	/**
		hold all fields that validator must validade. 
		array
			[id] : {
				l : string, // label
				r : boolean, // requirie
				f : string, // format
				m : string // mensagem a ser enviada
				min : real // valor minimo aceito
				max : real // valor máximo aceito
			}
	*/
	if(array != undefined) {
		this.fields = array;
	} else {
		this.fields = new Array();
	}
	
	this.add = function (array) {
		for(var id in array) {
			this.fields[id] = array[id];
		}
	}	
	
	/** Search element in html */
	this._searchElement = function (idOrName) {
		var e = document.getElementsByName(idOrName);
		if(e != null) {
			return e;
		}
		
		e = document.getElementById(idOrName);
		if(e != null) return e;
		
		return null;
	}

	/** 
		Validate fields
	*/
	this.validate = function () {
		this.first = null;
		this.errors = Array();
		
		for(var id in this.fields) {
			// process object data
			var objects = this._searchElement(id);
			if(objects == null) {
				alert("Exception: Element '"+id+"' not found by ID or NAME!");
				continue; 
			}
			var array = objects.length != undefined;
			
			// remove object from array if is unique
			var object = array ? objects[0] : objects;
			if(array && objects.length == 1) {
				object = objects[0];
				array = false;
			}
			
//			this.first = object;
//			this.errors[this.errors.length] = id + " " + object.type;
		
			var value = "";
			var format = this.fields[id]['f'] != undefined ? this.fields[id]['f'] : '';
			var require = this.fields[id]['r'] != undefined ? this.fields[id]['r'] : false;
			var label = this.fields[id]['l'] != undefined ? this.fields[id]['l'] : id;
			var message = this.fields[id]['m'] != undefined ? this.fields[id]['m'] : undefined;
		
			// separate values
			if(object.type == 'textarea' || object.type == 'text' || object.type == 'password' || object.type == 'hidden' || object.type == 'file') {
				// text fields
				value = object.value;
			} else if(object.type == 'checkbox') {
				// check box
				if(array) {
					for(var j = 0 ; j < objects.length ; j ++) {
						if(objects[j].checked)
							value = objects[j].value;
					}	
				} else {
					if(object.checked)
						value = object.value;
				}
			} else if(object.type == 'select-one' || object.type == 'select-multiple') {
				// select
				value = object.options[object.selectedIndex].value;
			} else if(object.type == 'radio') {
				// radios
				if(array) {
					for(var j = 0 ; j < objects.length ; j ++) {
						if(objects[j].checked)
							value = objects[j].value;
					}
				} else {
					if(object.checked)
						value = object.value;
				}
			} else {
				alert('Exception: Input type ('+ (object.type ? object.type : 'undefined') +') for field ' + id + ' not found!');
			}

			var errorsLen = this.errors.length;
			if(require && value.length == 0) {
				if (label == '') {
					this.errors[this.errors.length] = '';
				} else {
					this.errors[this.errors.length] = label + ' é um campo obrigatório!';
				}
			} else if(value.length == 0) {
			} else if(format == 'integer' && !/^[\+\-]?\d*$/.test(value)) {
				this.errors[this.errors.length] = '"'+value+'" não é um inteiro válido para o campo '+label+'!';
			} else if(format == 'real' && !/^[\+\-]?[\d\.]*\,?\d*$/.test(value)) {
				this.errors[this.errors.length] = '"'+value+'" não é um valor real (Ex: 1.234,56) válido para o campo '+label+'!';
			} else if(format == 'id' && !/^[a-zA-Z_][\w\n_]*$/.test(value)) {
				this.errors[this.errors.length] = '"'+value+'" não é um valor válido para o campo '+label+', apenas letras e números são permitidos, não pode começar por número e ter espaços!';
			} else if(format == 'alpha' && !/^[a-zA-Z\.\-\s\á\ã\â\é\ê\í\ó\ô\õ\ç]*$/.test(value)) {
				this.errors[this.errors.length] = '"'+value+'" não é um valor válido para o campo '+label+', apenas letras são permitidas!';
			} else if(format == 'alphanum' && !/^[\w\s\á\ã\â\é\ê\í\ó\ô\õ\ç]+$/.test(value)) {
				this.errors[this.errors.length] = '"'+value+'" não é um valor válido para o campo '+label+', apenas letras e números são permitidos!';
			} else if(format == 'email' && !/^[\w-\.]+\@[\w\.-]+\.[a-zA-Z]{2,4}$/.test(value)) {
				this.errors[this.errors.length] = '"'+value+'" não é um e-mail válido para o campo '+label+'!';
			} else if(format == 'currency' && !/^R?\$?\s*[\+\-]?[\d\.]*\,?\d*$/.test(value)) {
				this.errors[this.errors.length] = '"'+value+'" não é um valor monetário (Ex: 1.234,56) válido para o campo '+label+'!';
			} else if(format == 'password') {
				if(!/^[a-zA-Z0-9]*$/.test(value))
					this.errors[this.errors.length] = 'O campo '+label+' deve apenas conter números e letras!';
				if(value.length < 6 || value.length > 8)
					this.errors[this.errors.length] = 'O campo '+label+' deve ter entre 6 a 8 caracteres!';
				if(!/[0-9]+/.test(value))
					this.errors[this.errors.length] = 'O campo '+label+' deve ter pelo menos um número!';
				if(!/[a-zA-Z]+/.test(value))
					this.errors[this.errors.length] = 'O campo '+label+' deve ter pelo menos uma letra!';
			} else if(format == 'date') {
				var ok = false;
				if(/^\d{2}\/\d{2}\/\d{4}$/.test(value)) {
					var parts = value.split('/');
					ok = (parts[0] >= 1 && parts[0] <= 31) && (parts[1] >= 1 && parts[1] <= 12) && (parts[2] >= 1900 && parts[2] <= 2100);
				}
				if(!ok) this.errors[this.errors.length] = '"'+value+'" não é uma data (ex: 01/01/2001) válida para o campo '+label+'!';
			} else if(format == 'time') {
				var ok = false;
				if(/^\d{1,2}:\d{1,2}(:\d{2})?$/.test(value)) {
					var parts = value.split(':');
					ok = (parts[0] >= 0 && parts[0] <= 24) && (parts[1] >= 0 && parts[1] < 60) && (parts.length == 2 || (parts[2] >= 0 && parts[2] < 60));
				}
				if(!ok) this.errors[this.errors.length] = '"'+value+'" não é uma hora válida (ex: 12:30:00) para o campo '+label+'!';
			} else if(format == 'cep' && !/^\d?\d\d\d\d-?\d\d\d$/.test(value)) {
				this.errors[this.errors.length] = '"'+value+'" não é um CEP válido (ex: 12345-678) para o campo '+label+'!';
			} else if(format == 'cpf') {
				// remove symbols
				while(value.indexOf('.') != -1)
					value = value.replace('.', '');
				while(value.indexOf('-') != -1)
					value = value.replace('-', '');
		
				var i; 
				var s = value;
				var c = s.substr(0,9); 
				var dv = s.substr(9,2); 
				var d1 = 0; 
				var ok = false;
		
				for (i = 0; i < 9; i++) { 
					d1 += c.charAt(i)*(10-i); 
				} 
				
				if (d1 != 0) {
					d1 = 11 - (d1 % 11); 
					if (d1 > 9) d1 = 0; 
					if (dv.charAt(0) == d1) {
						d1 *= 2; 
						for (i = 0; i < 9; i++) { 
							d1 += c.charAt(i)*(11-i); 
						} 
				
						d1 = 11 - (d1 % 11); 
						if (d1 > 9) d1 = 0; 
						ok = true;
					}
				}
				if (dv.charAt(1) != d1 || !ok) 
					this.errors[this.errors.length] = '"'+value+'" não é um CPF válido para o campo '+label+'!';
			} else if(this.fields[id]['min'] != undefined && value < this.fields[id]['min']) {
				this.errors[this.errors.length] = 'No campo '+label+' você deve usar um valor MAIOR que '+this.fields[id]['min']+'!';
			} else if(this.fields[id]['max'] != undefined && value > this.fields[id]['max']) {
				this.errors[this.errors.length] = 'No campo '+label+' você deve usar um valor MENOR que '+this.fields[id]['max']+'!';
			}

			var hasError = (errorsLen != this.errors.length);
			
			// send a custon message
			if(hasError && message != undefined) {
				// override default message 
				this.errors[this.errors.length-1] = message;
			}
			
			// get first to focus
			if(hasError && this.first == null) {
				if(array) 
					this.first = objects[0];
				else
					this.first = object;
			}
		}
		
		// show errors
		if(this.errors.length > 0) {
			var buffer = "";
			for(var i = 0 ; i < this.errors.length ; i++) {
				buffer += this.errors[i] + "\n";
			}
			this.first.focus();
			alert(buffer);
			return false;
		} else {
			return true;
		}
	}
}
