//var event;
var eventArgs;
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); };

var UpdateLastModified =  {
	anchorId:"lastModified",
	updateDestination: function(newDestination){
		if($(this.anchorId)){
			$(this.anchorId).href = "#" + newDestination;
		}
	}
}



var SetUpInputText = function(input,defValue){
	if(input.type!="text") return;
	input.autocomplete = "off";
	input.defValue = defValue;
	input.edited = function(isEdited){
		Element.addClassName(this,isEdited?"edited":"notEdited")
		Element.removeClassName(this,(!isEdited)?"edited":"notEdited")
	}
	Event.observe(input,"focus",function (e){
		input.clearDef()
		input.edited(true)
	})
	Event.observe(input,"blur",function (e){
		input.checkEdited();
	})
	input.checkEdited = function(){
		if(this.value.trim() == "" || this.value == input.defValue){
			this.value = input.defValue;
			this.edited(false)
		}else{
			this.edited(true)
		}
	}
	input.clearDef = function(){
		if(this.defValue == this.value){this.value="";}
	}
	input.checkEdited()
}
var SetUpInputSelect = function(input){
	if(input.type!="select-one") return;
	input.edited = function(isEdited){
		Element.addClassName(this,isEdited?"edited":"notEdited")
		Element.removeClassName(this,(!isEdited)?"edited":"notEdited")
	}
	Event.observe(input,"focus",function (e){
		input.edited(true)
	})
	Event.observe(input,"blur",function (e){
		input.checkEdited();
	})
	input.checkEdited = function(){
		if(this.options[0].selected){
			this.edited(false)
		}else{
			this.edited(true)
		}
	}
	input.clearDef = function(){
		if(this.defValue == this.value){this.value="";}
	}
	input.checkEdited()
}
var FormValidator = Class.create();
FormValidator.prototype = {
	initialize: function(form){
		this.form = form;
		this.validators = new Array();
		this.validatorGroups = {};
		this.errors = [];
	},
	getInputGroupValidator: function (input){
		var group = this.validatorGroups[input.id]?this.validatorGroups[input.id]:new ValidatorGroup(input);
		this.validatorGroups[input.id] = group;
		group.onValidationPassed = this.validationPassedHandler.bindAsEventListener(this);
		group.onValidationFailed = this.validationFailedHandler.bindAsEventListener(this);
		return group;
	},
	addValidator: function(validator, input, parameters){
		if (typeof validator == 'string') {
			validator = this.createValidator(validator,input,parameters);
		}
		if(validator.input) {
			//validator.input.onfocus = this.focusHandler.bindAsEventListener(this);	
			//validator.input.onblur = this.blurHandler.bindAsEventListener(this);
			Event.observe(validator.input,"focus",this.focusHandler.bindAsEventListener(this));	
			Event.observe(validator.input,"change",this.changeHandler.bindAsEventListener(this));	
			Event.observe(validator.input,"blur",this.blurHandler.bindAsEventListener(this));
			/*this.addEventObserver(validator.input,"onfocus",this.focusHandler.bindAsEventListener(this));	
			this.addEventObserver(validator.input,"onblur",this.blurHandler.bindAsEventListener(this));	*/
			var group = this.getInputGroupValidator(input);
			group.addValidator(validator);
		}
		else
		{
			validator.onValidationPassed = this.validationPassedHandler.bindAsEventListener(this);
			validator.onValidationFailed = this.validationFailedHandler.bindAsEventListener(this);
			this.validators.push(validator);
		}
		return validator;
	},
	//***********************************Borra todas las validaciones que tenemos hasta el momento
	removeValidators: function(){
		this.validators = new Array();
		this.validatorGroups = {};
		this.errors = [];
	},
	//*************************************
	validationPassedHandler: function(){//eventArgs){
		this.callEvent(this.onValidationPassed);
		this.callEvent(this.onValidationPassedJIT);
	},
	callEvent: function(eventFunction){
		if(eventFunction) eventFunction();
	},
	validationFailedHandler: function(){//eventArgs){
		this.errors.push(eventArgs);
		this.callEvent(this.onValidationFailed)
		this.callEvent(this.onValidationFailedJIT)
	},
	focusHandler: function(e){//eventArgs){
		var el = (e.srcElement) ? e.srcElement : e.target;
		if(this.onValidationStart){
			eventArgs = {input:el};
			this.onValidationStart(el);
		}
		this.getInputGroupValidator(el).validate();
	},	
	changeHandler: function(e){//eventArgs){
		var el = (e.srcElement) ? e.srcElement : e.target;
		if(this.onValidationStart){
			eventArgs = {input:el};
			this.onValidationStart(el);
		}
		this.getInputGroupValidator(el).validate();
	},		
	blurHandler: function(e){//eventArgs){
		if(this.onValidationEnd){
			var ev = e ? e : window.event;
			var el = (ev.srcElement) ? ev.srcElement : ev.target;
			eventArgs = {input:el};
			this.onValidationEnd();
		}
	},
	createValidator:function(name,input,parameters){
		switch(name){
			case 'BaseValidator': return new BaseValidator(input,parameters);
			case 'ContainsValidator': return new ContainsValidator(input,parameters);
			case 'IntegerValidator': return new IntegerValidator(input,parameters);
			case 'FloatValidator': return new FloatValidator(input,parameters);
			case 'DateValidator': return new DateValidator(input,parameters);
			case 'AlphaNumericValidator': return new AlphaNumericValidator(input,parameters);
			case 'SelectedValidator': return new SelectedValidator(input,parameters);
			case 'DontChecked': return new DontChecked(input,parameters);
			case 'NifValidator': return new NifValidator(input,parameters);
			case 'NieValidator': return new NieValidator(input,parameters);
			case 'CIFValidator': return new CIFValidator(input,parameters);
			case 'NifCifValidator': return new NifCifValidator(input,parameters);
			case 'CpValidator': return new CpValidator(input,parameters);
			case 'TlfValidator': return new TlfValidator(input,parameters);
			case 'EmailValidator': return new EmailValidator(input,parameters);
			case 'InputDependsSelect': return new InputDependsSelect(input,parameters);
			case 'SeleccionLocalValidator': return new SeleccionLocalValidator(input,parameters);
			case 'RegExpValidator': return new RegExpValidator(input,parameters);
			case 'CnaeValidator': return new CnaeValidator(input,parameters);
			case 'SelectOneCheckValidator': return new SelectOneCheckValidator(input,parameters);
			case 'TipoDocumento': return new TipoDocumento(input,parameters);
			case 'TipoDocumento2': return new TipoDocumento2(input,parameters);
			case 'RadioValidator': return new RadioValidator(input,parameters);		
			case 'RadioValidator2': return new RadioValidator2(input,parameters);	
			case 'RadioValidator3': return new RadioValidator3(input,parameters);	
			case 'RadioValidator4': return new RadioValidator4(input,parameters);	
			case 'RadioValidator5': return new RadioValidator5(input,parameters);	
			case 'RadioValidator6': return new RadioValidator6(input,parameters);	
			case 'RadioValidator7': return new RadioValidator7(input,parameters);	
			case 'RadioValidator8': return new RadioValidator8(input,parameters);
			case 'RadioValidator9': return new RadioValidator9(input,parameters);
			case 'RadioValidator10': return new RadioValidator10(input,parameters);
			case 'RadioValidatorGar': return new RadioValidatorGar(input,parameters);
			case 'RadioValidatorGen': return new RadioValidatorGen(input,parameters);
			case 'TlfPrefValidator': return new TlfPrefValidator(input,parameters);
		}
	},
	validate: function(){
		this.validateAll();
		if(this.onGlobalValidate){
			eventArgs = {result:this.result, errors:this.errors};
			this.onGlobalValidate();
		}
		return this.result;
	},
	onGlobalValidate: null,
	onValidationStart: null,
	onValidationEnd: null,
	onValidationPassed: null,
	onValidationPassedJIT: null,
	onValidationFailed: null,
	onValidationFailedJIT: null,
	result: false,
	validateAll: function(){
		var result = true;
		this.errors = [];
		var i=0
		$H(this.validatorGroups).each(function(group){
			result = group[1].validate() && result;	
		});
		this.validators.each(function(validator){
			result = validator.validate() && result;
		});
		this.result = result;
	}
}

var ValidatorGroup = Class.create();
ValidatorGroup.prototype = {
	initialize: function(input){
		Event.observe(input,"keyup", this.onkeyupHandler.bindAsEventListener(this));	
		Event.observe(input,"change", this.onchangeHandler.bindAsEventListener(this));	
		this.input = input;
		this.validators = [];
		this.validationPassedEventQueue;
		this.result = true;
	},
	addValidator:function(validator){
		validator.onValidationPassed = this.validationPassedHandler.bindAsEventListener(this);
		validator.onValidationFailed = this.validationFailedHandler.bindAsEventListener(this);
		this.validators.push(validator);
	},
	validate: function(){
		if(!this.input.disabled){
			this.validationPassedEventQueue = [];
			this.result = this.validateAll();
			this.throwValidationPassedEvents();
			return this.result;
		}else{
			return true;
		}
	},
	throwValidationPassedEvents: function(){
		if(this.onValidationPassed){
			for(var i=0;i<this.validationPassedEventQueue.length;i++){
				eventArgs = this.validationPassedEventQueue[i];			
				this.onValidationPassed();
			}
		}
	},
	validateAll: function (){
		for(var i=0;i<this.validators.length;i++){
			if(!this.validators[i].validate()) return false;
		}
		return true;
	},
	onkeyupHandler: function(e){
		var ev = e ? e : window.event;
		var el = (ev.srcElement) ? ev.srcElement : ev.target;
		eventArgs = {input:el};
		this.validate();
	},
	onchangeHandler: function(e){
		var ev = e ? e : window.event;
		var el = (ev.srcElement) ? ev.srcElement : ev.target;
		if(el.type == 'SELECT'){
			eventArgs = {input:el};
			this.validate();
		}
	},	
	onValidationPassed: null,
	onValidationFailed: null,
	validationPassedHandler: function(){//eventArgs){
		this.validationPassedEventQueue.push(eventArgs);
	},
	validationFailedHandler: function(){//eventArgs){
		if(this.onValidationFailed){
			//event = eventArgs;
			this.onValidationFailed();
		}
	}
}


var ValidationSummary = Class.create();
ValidationSummary.prototype = {
	initialize: function(fV, summary, parameters){
		this.fV = fV;
		this.summary = summary;
		this.parameters = Object.extend({
			focusOnFail: false,
			id: "validationSummary",
			passedClass:"corrected",
			showAlert:false,
			alertMessage:'Check the errors in the form.\n Access key to review: Alt+0'
		},
		parameters ||{}
		);
		this.id = this.parameters.id;
		this.makeAnchor();
		this.fV.onGlobalValidate = this.globalValidateHandler.bindAsEventListener(this);
		this.fV.onValidationPassed = this.validationPassedHandler.bindAsEventListener(this);
		this.fV.onValidationFailed = this.validationFailedHandler.bindAsEventListener(this);
	},
	validationPassedHandler: function(){//eventArgs){
		Element.addClassName($(eventArgs.errorId),this.parameters.passedClass);
	},
	validationFailedHandler: function(){//eventArgs){
		Element.removeClassName($(eventArgs.errorId),this.parameters.passedClass);
	},
	globalValidateHandler: function(){//eventArgs){
		if(eventArgs.result){
			Element.hide(this.summary);
		}
		else
		{
			Element.show(this.summary);
			this.loadValidationErrors(eventArgs.errors)
			this.navigate();
		}
	},
	loadValidationErrors:function(errors){
			var ul = this.errorList();
			var summaryErrors =  this.processErrors(errors);
			summaryErrors.each(function (node){ul.appendChild(node)});
	},
	navigate:function(){
		if(this.parameters.focusOnFail)	document.location = "#" + this.id;
		if(this.parameters.showAlert) alert(this.parameters.alertMessage);
		UpdateLastModified.updateDestination(this.id);
	},
	makeAnchor:function(){
		if($(this.id)){alert("Duplicated ValidationSummary id")}
		var anchor = document.createElement("a");
		anchor.id = this.id;
		this.summary.appendChild(anchor);
	},
	processErrors: function (errors){
		var lis = [];
		errors.each(
			function(valError){
				var li = document.createElement("li");
				li.id = valError.errorId;
				lis.push(li);
				if(valError.input){
					var link = document.createElement("a");
					link.innerHTML = valError.message;
					link.href = "#";
					link.input = valError.input;
					link.onclick = function(){
						this.input.focus();
						return false;
					}
					li.appendChild(link);
				}else{
					li.innerHTML = valError.message;
				}
			}
		)
		return lis; 
	},
	errorList: function(){
		var ul;
		if(this.summary.getElementsByTagName("ul").length>0){
			ul = this.summary.getElementsByTagName("ul")[0];
			$A(ul.childNodes).each(function(node){ul.removeChild(node);})
		}
		else {
			ul = document.createElement("ul");
			this.summary.appendChild(ul);
		}
		return ul;
	}
}

var JitValidation = Class.create();
JitValidation.prototype = {
	initialize: function(fV, parameters){
		this.fV = fV;
		this.parameters = Object.extend({
			infoWindowClass:'JITInfoWindow',
			showAlert:false,
			horizontalOffset:2,
			verticalOffset:2,
			editingStyle:'editing',
			validationErrorStyle:'validationError',
			alertHeader:'Check the following error:\n',
			alertFooter:''
			
		},
		parameters ||{}
		);
		this.currentErrorId = "";
		this.editingInput = false;
		this.createInfoWindow();
		this.fV.onValidationStart = this.validationStartHandler.bindAsEventListener(this);
		this.fV.onValidationEnd = this.validationEndHandler.bindAsEventListener(this);
		this.fV.onValidationFailedJIT = this.validationFailedHandler.bindAsEventListener(this);
		this.fV.onValidationPassedJIT = this.validationPassedHandler.bindAsEventListener(this);
	},
	validationPassedHandler: function(){//eventArgs){
		if(this.currentErrorId == eventArgs.errorId) {
			this.currentErrorId = "";
			this.hideInfoWindow();
			this.unmarkError();
		}
	},
	validationFailedHandler: function(){//eventArgs){
		this.message = eventArgs.message;
		this.infoWindow.innerHTML = this.message;
		this.currentErrorId = eventArgs.errorId;
		this.showInfoWindow();	
		this.markError();
	},
	validationStartHandler: function(el){//eventArgs){
		this.currentInput = el;
		this.editingInput = true;
		this.moveInfoWindow();
		this.markInput();
	},
	validationEndHandler: function(){
		this.confirmEndEdit();
		this.hideInfoWindow();
		this.unmarkInput();
		this.editingInput = false;
		
	},
	confirmEndEdit:function(){
		if(this.parameters.showAlert &&  this.currentErrorId!=""){
			return alert(this.parameters.alertHeader + this.message + this.parameters.alertFooter);
		}
	},
	markError:function(){
		Element.addClassName(this.currentInput, this.parameters.validationErrorStyle)
		if(this.parameters.errorLabelStyle && eventArgs.input && eventArgs.input.JITLabel) {//this.currentInput.JITLabel) {
			Element.addClassName(eventArgs.input.JITLabel, this.parameters.errorLabelStyle)
		}
	},
	markInput:function(){
		if(eventArgs.input){
			Element.addClassName(eventArgs.input, this.parameters.editingStyle)
		}
	},
	unmarkError:function(){
		Element.removeClassName(eventArgs.input, this.parameters.validationErrorStyle)
		if(this.parameters.errorLabelStyle && eventArgs.input.JITLabel) {
			Element.removeClassName(eventArgs.input.JITLabel, this.parameters.errorLabelStyle)
		}
	},
	unmarkInput:function(){
		Element.removeClassName(eventArgs.input, this.parameters.editingStyle)
	},
	showInfoWindow: function (){
		if(this.editingInput){
			if(this.infoWindowIfr){
				var dims = Element.getDimensions(this.infoWindow);
				this.infoWindowIfr.style.height = (dims.height+2)+"px";
				this.infoWindowIfr.style.width = (dims.width+2)+"px";
				Element.show(this.infoWindowIfr);
				
			}
			if(this.parameters.showInfoWindow){
				this.parameters.showInfoWindow(this.infoWindow);
			}else{
				Element.show(this.infoWindow);
			}
		}
	},
	hideInfoWindow: function (){
		if(this.infoWindowIfr){Element.hide(this.infoWindowIfr)}
		if(this.parameters.hideInfoWindow){
			this.parameters.hideInfoWindow(this.infoWindow);
		}else{
			Element.hide(this.infoWindow);
		}
	},
	createInfoWindow: function(){
		var iW = document.createElement("div");
		iW.className = this.parameters.infoWindowClass;
		iW.style.display = "none";
		iW.style.position = "absolute";
		iW.style.zIndex = 1000;
		document.body.appendChild(iW);
		this.infoWindow = iW;
		if(document.all){
			var ifr = document.createElement("iframe");
			ifr.style.display = "none";
			ifr.style.position = "absolute";
			ifr.style.zIndex = 999
			//ifr.src = "/_utils/ifrcont.html"
			ifr.frameBorder="0";
			ifr.marginWidth="0"; 
			ifr.marginHeight="0";
			document.body.appendChild(ifr);
			this.infoWindowIfr = ifr;
		}
	},
	moveInfoWindow: function(){
		this.moveWindow(this.infoWindow);
		if(this.infoWindowIfr){this.moveWindow(this.infoWindowIfr)}
	},
	moveWindow: function(w){
		position = this.inputPosition();
		w.style.left = (position.left + this.parameters.horizontalOffset) + "px";
		w.style.top = (position.bottom + this.parameters.verticalOffset) + "px";
	}
	,
	inputPosition: function(){
		var selectedPosX = 0;
		var selectedPosY = 0;
		var theElement = eventArgs.input;
		if (!theElement) return;
		var theElemHeight = theElement.offsetHeight;
		var theElemWidth = theElement.offsetWidth;
		while(theElement != null){
		  selectedPosX += theElement.offsetLeft;
		  selectedPosY += theElement.offsetTop;
		  theElement = theElement.offsetParent;
		}
		position = { 
			top: selectedPosY,
			left: selectedPosX,
			bottom: (selectedPosY + theElemHeight),
			right: (selectedPosX + theElemWidth)
		}
		return position;
	}
}



var BaseValidator = Class.create();
BaseValidator.counter = 0;
BaseValidator.prototype = {
	initialize: function(input, parameters){
		this.input = input;
		this.id = this.newId();
		this.parameters = Object.extend({
				message: "Error: " + input.id,
				required: false
			},
			parameters ||{}
		);
		if(this.concreteInitialize) this.concreteInitialize();
	},
	newId: function(){
		BaseValidator.counter++;
		return "FV_V"+BaseValidator.counter;
	},
	onValidationPassed: null,
	onValidationFailed: null,
	validate:function(){
		this.result =  (!this.parameters.required || (this.input.value != "")) && this.concreteValidate();
		if(this.result){
			this.throwValidationPassed();
		}else{
			this.throwValidationFailed();
		}
		return this.result;
	},
	throwValidationPassed: function(){
		if(this.onValidationPassed){
			eventArgs = this.getEventArgs();
			this.onValidationPassed();
		}
	},
	throwValidationFailed: function(){
		if(this.onValidationFailed){
			eventArgs = this.getEventArgs();
			this.onValidationFailed();
		}
	},
	getEventArgs:function (){
		return	{
			errorId:this.id,
			input:this.input,
			message:this.parameters.message
		};
	},
	concreteValidate: function(){
	}
}

var ContainsValidator = Class.create();
ContainsValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			return (this.input.value.indexOf(this.parameters.text)>=0);
		}
	}
)

var IntegerValidator = Class.create();
IntegerValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			if(this.input.value == "") return true;
			var value = parseInt(this.input.value);
			var result = true;
			if (isNaN(value)){
				result = false;
			}else{
				if(this.input.value != value) this.input.value = value;
			}
			result = result && ((this.parameters.min == undefined) || (value >= this.parameters.min));
			result = result && ((this.parameters.max == undefined) || (value <= this.parameters.max));
			return result;
		}
	}
)

var FloatValidator = Class.create();
FloatValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			if(this.input.value == "") return true;
			if(this.parameters.commaForDecimal){this.input.value = this.input.value.replace(".",",")}
			var origValue = this.input.value;
			if(this.parameters.commaForDecimal){origValue = origValue.replace(",",".")}
			var newValue = parseFloat(origValue);
			var result = true;
			if(isNaN(newValue)){
				result = false;
			}else{
				if(origValue != newValue) {
					if(this.parameters.commaForDecimal) {
						this.input.value = newValue.toString().replace(".",",");
					}else{
						this.input.value = newValue;
					}
				}
			}
			result = result && ((this.parameters.min == undefined) || (newValue >= this.parameters.min));
			result = result && ((this.parameters.max == undefined) || (newValue <= this.parameters.max));
			return result;
		}
	}
)


var DateValidator = Class.create();
DateValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			if(this.input.value == "") return true;
			var data = this.input.value.split("/");
			var result = true;
			if(data.length!=3){
				return false;
			}
			var day = parseInt(data[0]);
			var month = parseInt(data[1]);
			var year = parseInt(data[2]);
			if(isNaN(day) || isNaN(month) || isNaN(year) || (day != data[0]) || (month != data[1]) || (year != data[2]) ){
				return false;
			}
			var date = new Date();
			month -= 1; //meses de 0 a 11
			date.setFullYear(year,month,day)
			if((date.getFullYear() != year) || (date.getMonth() != month) || (date.getDate() != day) )
			{ 
				return false;
			}
			result = result && ((this.parameters.min == undefined) || (date >= this.parameters.min));
			result = result && ((this.parameters.max == undefined) || (date <= this.parameters.max));
			return result;
		}
	}
)

var AlphaNumericValidator = Class.create();
AlphaNumericValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			if(this.input.value == "") return true;
			var data = this.input.value.search("[^A-Za-z0-9/Ññ ÁÉÍÓÚáéíóú'/-]"); 
			var result = true;
			if(this.input.value.length > 0 &&  data >= 0)
				{return false;}
			return result;
		}
	}
)


var SelectedValidator = Class.create();
SelectedValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			if(this.input.selectedIndex == 0) return false;
			var result = true;
			return result;
		}
	}
)

var TlfPrefValidator = Class.create();
TlfPrefValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			
			var result = true;
			var data = this.input.value.search("[^0-9]"); 

			//limita a números de 9 o 10 dígitos o números de 9 o 10 dígitos más prefijo (0034 o +34 por ejemplo)
		
			if( ((this.input.value.length !=10 && this.input.value.length !=9) || data >= 0) && ((this.input.value.length !=13 && this.input.value.length !=12) || this.input.value.substring(0,1)!='+') && ((this.input.value.length !=14 && this.input.value.length !=13) || this.input.value.substring(0,2)!='00')){
				return false;
				}				
			return result;
		}
	}
)

var DontChecked = Class.create();
DontChecked.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){	
			if(this.input.checked == 0) return false;
			var result = true;
			return result;
		}
	}
)
var InputDependsSelect = Class.create();
InputDependsSelect.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			var result = false;
			return result;
			//if($(this.parameters.idSelectPadre).value == this.parameters.idSelectPadreValor){

		}
	}
)
var NifValidator2 = Class.create();
NifValidator2.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			if(this.input.value == "") return true;

			var data = this.input.value;
			data = data.toUpperCase(); 
			var dataLong = this.input.value.length;
			var result = true;
			if (!/^[ABCDEFGHKLMNPQS]/.test(data)) {
				var letraIntroducida = data.substr(dataLong - 1, dataLong).toUpperCase();
				var n = parseInt(data.substr(0, dataLong - 1));
				var d =(n/23);
				d = Math.floor(d);
				var e = (d*23);
				var r = (n-e);
				var letraNIF = new Array('T','R','W','A','G','M','Y','F','P','D','X','B','N','J','Z','S','Q','V','H','L','C','K','E','T');
				var letraCorrecta = letraNIF[r];
				if(letraCorrecta != letraIntroducida){
					return false;
				}
			}
			return result;
		}
	}
)

var CnaeValidator = Class.create();
CnaeValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			if(this.input.value == "") return true;
			var value  = this.input.value;
			return (value.substr(0,2)!='95'); //Distinto de Hogares que emplean personal doméstico
		}
	}
)

var NifValidator = Class.create();
NifValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			if(this.input.value == "") return true;

			var value  = this.input.value;
			var dni=value.substring(0,value.length-1);
			var let=value.charAt(value.length-1);
			if (!isNaN(let))
			{
				return false;
			}
			if (isNaN(dni))
			{
				return false;
			}
			var cadena="TRWAGMYFPDXBNJZSQVHLCKET"
			var posicion = dni % 23;
			var letra = cadena.substring(posicion,posicion+1);
			if (letra!=let.toUpperCase())
			{
				return false;
			}
			return true;
		}
	}
)

var NieValidator = Class.create();
NieValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			if(this.input.value == "") return true;

			var value  = this.input.value;
			var primLetr=value.substring(0,1);
			primLetr=primLetr.toUpperCase();
			var nif=value.substring(1,value.length);
			if((primLetr!="X")&&(primLetr!="Y")&&(primLetr!="Z")){
				return false;	
			}else{
				//validamos el resto(elemento sin la X) como si fuera un nif
				var dni=nif.substring(0,nif.length-1);
				var let=nif.charAt(nif.length-1);
				if (!isNaN(let))
				{
					return false;
				}
				if (isNaN(dni))
				{
					return false;
				}
				var cadena="TRWAGMYFPDXBNJZSQVHLCKET"
				var posicion = dni % 23;
				var letra = cadena.substring(posicion,posicion+1);
				if (letra!=let.toUpperCase())
				{
					return false;
				}
				return true;
			}	
		}
	}
)

var CIFValidator = Class.create(); 
CIFValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			if(this.input.value == "") return true;
			var data = this.input.value;
			data = data.toUpperCase(); 
			var dataLong = this.input.value.length;
			var result = true;
			var pares = 0; 
			var impares = 0; 
			var suma; 
			var ultima; 
			var unumero; 
			var uletra = new Array("J", "A", "B", "C", "D", "E", "F", "G", "H", "I"); 
			var xxx; 

			var regular = /^([ABCDEFGHKLMNPQS]\d\d\d\d\d\d\d[0-9,A-J]){1}$/; 
			if (!regular.test(data)){
			return false; 
			}      
			ultima = data.substr(8,1); 

			for (var cont = 1 ; cont < 7 ; cont ++){ 
			xxx = (2 * parseInt(data.substr(cont++,1))).toString() + "0"; 
			impares += parseInt(xxx.substr(0,1)) + parseInt(xxx.substr(1,1)); 
			pares += parseInt(data.substr(cont,1)); 
			} 
			xxx = (2 * parseInt(data.substr(cont,1))).toString() + "0"; 
			impares += parseInt(xxx.substr(0,1)) + parseInt(xxx.substr(1,1)); 

			suma = (pares + impares).toString(); 
			unumero = parseInt(suma.substr(suma.length - 1, 1)); 
			unumero = (10 - unumero).toString(); 
			if(unumero == 10) unumero = 0; 

			if ((ultima == unumero) || (ultima == uletra[unumero])){
				return true;  
			}else{ 
				return false;
			}
		}
	}
)

var NifCifValidator = Class.create();
NifCifValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			if(this.input.value == "") return true;

			var data = this.input.value;
			data = data.toUpperCase(); 
			var dataLong = this.input.value.length;
			var result = true;
			if (!/^[ABCDEFGHKLMNPQS]/.test(data)) {
				var letraIntroducida = data.substr(dataLong - 1, dataLong).toUpperCase();
				var n = parseInt(data.substr(0, dataLong - 1));
				var d =(n/23);
				d = Math.floor(d);
				var e = (d*23);
				var r = (n-e);
				var letraNIF = new Array('T','R','W','A','G','M','Y','F','P','D','X','B','N','J','Z','S','Q','V','H','L','C','K','E','T');
				var letraCorrecta = letraNIF[r];
				if(letraCorrecta != letraIntroducida){
					return false;
				}
			}else{
				var pares = 0; 
				var impares = 0; 
				var suma; 
				var ultima; 
				var unumero; 
				var uletra = new Array("J", "A", "B", "C", "D", "E", "F", "G", "H", "I"); 
				var xxx; 

				var regular = /^([ABCDEFGHKLMNPQS]\d\d\d\d\d\d\d[0-9,A-J]){1}$/; 
				if (!regular.test(data)){
				return false; 
				}      
				ultima = data.substr(8,1); 

				for (var cont = 1 ; cont < 7 ; cont ++){ 
				xxx = (2 * parseInt(data.substr(cont++,1))).toString() + "0"; 
				impares += parseInt(xxx.substr(0,1)) + parseInt(xxx.substr(1,1)); 
				pares += parseInt(data.substr(cont,1)); 
				} 
				xxx = (2 * parseInt(data.substr(cont,1))).toString() + "0"; 
				impares += parseInt(xxx.substr(0,1)) + parseInt(xxx.substr(1,1)); 

				suma = (pares + impares).toString(); 
				unumero = parseInt(suma.substr(suma.length - 1, 1)); 
				unumero = (10 - unumero).toString(); 
				if(unumero == 10) unumero = 0; 

				if ((ultima == unumero) || (ultima == uletra[unumero])){
					result = true; 
				}else{ 
					return false; 
				}			
			}
			return result;
		}
	}
)
var CpValidator = Class.create();
CpValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			if(this.input =="") return true;
			var result = true;
			var data = this.input.value.search("[^0-9]"); 
			if( this.input.value.length !=5 || data >= 0){
				return false;
			}
			return result;
		}
	}
)





var TlfValidator = Class.create();
TlfValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			if(this.input =="") return true;
			var result = true;
			var data = this.input.value.search("[^0-9]"); 
			if(this.input.value.length < 9 || data >= 0){
				return false;
			}
			return result;
		}
	}
)		


	
var EmailValidator = Class.create();
EmailValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			if(this.input =="") return true;
			var result = true;
			if(this.input.value.indexOf('@') == -1 || this.input.value.indexOf('.') == -1){
				return false;
			}
			return result;
		}
	}
)

var SeleccionLocalValidator = Class.create();
SeleccionLocalValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			 var result = true;
			 if($(this.parameters.select).value == this.parameters.ifThisValue){
				var data = this.input.value.search("[^A-Za-z0-9/Ññ ÁÉÍÓÚáéíóú'/-]"); 
				var result = true;
				if(this.input.value.length > 0 &&  data >= 0)
					{return false;}
				if(this.input.value.length == 0){return false}
			 }
			return result;
		}
	}
)





var RegExpValidator = Class.create();
RegExpValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteInitialize: function(){
			this.parameters = Object.extend({
				notEmpty: false,
				isLatin: false,
				isInteger: false,
				isDigit: false,
				is2Digits: false,
				isCUPSElectricidad: false,
				isCUPSGas: false,
				isContratoPS: false,
				is4Digits: false,
				is5Digits: false,
				is10Digits: false,
				isEmail: false,
				isURL: false,
				isSomething: false
			},
			this.parameters);
			this.regExp = this.getRegExp();
		},
		concreteValidate: function(){
			if(this.input.value != ""){
				return this.regExp.test(this.input.value);}
			return true;
		},
		getRegExp: function(){
			if(this.parameters.notEmpty){
				return /^(.+)$/;
			}
			if(this.parameters.isLatin){
				return /^[ÀÈÌÒÙàèìòùÁÉÍÓÚÝáéíóúýÂÊÎÔÛâêîôûÃÑÕãñõÄËÏÖÜäëïöü¡¿çÇßØøÅåÆæÞþÐð""”“\w\d-'´.,&amp;#@:?!()$\/]+[ÀÈÌÒÙàèìòùÁÉÍÓÚÝáéíóúýÂÊÎÔÛâêîôûÃÑÕãñõÄËÏÖÜäëïöü¡¿çÇßØøÅåÆæÞþÐð""”“\w\d\s-'´.,&amp;#@:?!()$\/]*$/
			}
			if(this.parameters.isInteger){
				return /^\d+$/;
			}
			if(this.parameters.is4Digits){
				return /^([0-9]{4})$/;
			}
			if(this.parameters.is5Digits){
				return /^([0-9]{5})$/;
			}
			if(this.parameters.is2Digits){
				return /^([0-9]{2})$/;
			}
			if(this.parameters.isDigit){
				return /^([0-9])$/;
			}
			if(this.parameters.isCUPSElectricidad){
				return /^([a-zA-Z0-9]{22})$/;
			}		
			if(this.parameters.isCUPSGas){
				return /^([a-zA-Z0-9]{20})$/;
			}
			if(this.parameters.isContratoPS){
				return /^([0-9]{1,12})$/;
			}					
			if(this.parameters.is9Digits){
				return /^([0-9]{9})$/;
			}
			if(this.parameters.is10Digits){
				return /^([0-9]{10})$/;
			}
			if(this.parameters.isEmail){
				return /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
			}
			if(this.parameters.isURL){
				return /^(http:\/\/www.|https:\/\/www.|ftp:\/\/www.|www.){1}([\w]+)(.[\w]+){1,2}$/;
			}
			if(this.parameters.isSomething){
				return /^(.+)$/;
			}
			if(this.parameters.regExp){
				return this.parameters.regExp; 
			}
		}
	}
)



var SelectOneCheckValidator = Class.create();
SelectOneCheckValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			 var result =  ( $("servicio1").checked || $("servicio2").checked  || $("servicio4").checked  || $("servicio6").checked)
			return result;
		}
	}
)

//función para validar en la campaña de energía solar, si ha seleccionado el radio de tipo de usuario(obligatorio). 
//Los valores posibles son empresas(E) o el de promotores(P).
var RadioValidator = Class.create();
RadioValidator.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			var result =  ( $("tipoUsuarioE").checked || $("tipoUsuarioP").checked )
			return result;
		}
	}
)

//función para validar en la campaña de luz, si ha seleccionado el radio de cliente si/no(obligatorio). 
var RadioValidator2 = Class.create();
RadioValidator2.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			var result =  ( $("ClienteESi").checked || $("ClienteENo").checked )
			return result;
		}
	}
)

//función para validar en la campaña de energía solar, si ha seleccionado el radio de tipo de usuario(obligatorio). 
//Los valores posibles son empresas(E) o el de promotores(P).
var RadioValidator3 = Class.create();
RadioValidator3.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			var result =  ( $("cantidadP").checked || $("cantidadC").checked || $("cantidadE").checked )
			return result;
		}
	}
)

var RadioValidator4 = Class.create();
RadioValidator4.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			var result =  ( $("coloresM").checked || $("coloresB").checked)
			return result;
		}
	}
)

var RadioValidator5 = Class.create();
RadioValidator5.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			var result =  ( $("calidadB").checked || $("calidadM").checked)
			return result;
		}
	}
)

var RadioValidator6 = Class.create();
RadioValidator6.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			var result =  ( $("interesaM").checked || $("interesaR").checked || $("interesaF").checked )
			return result;
		}
	}
)

var RadioValidator7 = Class.create();
RadioValidator7.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			var result =  ( $("tonoF").checked || $("tonoC").checked)
			return result;
		}
	}
)

var RadioValidator8 = Class.create();
RadioValidator8.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			var result =  ( $("disponeS").checked || $("disponeN").checked)
			return result;
		}
	}
)

var RadioValidator9 = Class.create();
RadioValidator9.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			var result =  ( $("situacionA").checked || $("situacionB").checked || $("situacionC").checked)
			return result;
		}
	}
)

var RadioValidator10 = Class.create();
RadioValidator10.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			var result =  ( $("tipoViviendaE").checked || $("tipoViviendaP").checked)
			return result;
		}
	}
)

var RadioValidatorGar = Class.create();
RadioValidatorGar.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			var result = $("tipoViviendaNO").checked;
				return !result;
		}
	}
)

// Validador genérico de radiobuttons
var RadioValidatorGen = Class.create();
RadioValidatorGen.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			elemento = this.input.name;
			var result = false;
			var valores = $("formulario").getInputs('radio', elemento);
			valores.each(function(item) {
				if (item.checked) result = true;
			});
			return result;
		}
	}
)




















//función para validar diferentes tipos de documento en función de la selección que realice el usuario en el combo "Tipo de Documento"
//valida NIF, CIF y NIE...El pasaporte no se valida

var TipoDocumento = Class.create();
TipoDocumento.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			
			if(this.input.value == "") return true;
			
			if ($('tipo_cliente').selectedIndex == 1){
				//validamos el cif
				var data = this.input.value;
				data = data.toUpperCase(); 
				var dataLong = this.input.value.length;
				var result = true;
				var pares = 0; 
				var impares = 0; 
				var suma; 
				var ultima; 
				var unumero; 
				var uletra = new Array("J", "A", "B", "C", "D", "E", "F", "G", "H", "I"); 
				var xxx; 
	
				var regular = /^([ABCDEFGHKLMNPQS]\d\d\d\d\d\d\d[0-9,A-J]){1}$/; 
				if (!regular.test(data)){
				return false; 
				}      
				ultima = data.substr(8,1); 
	
				for (var cont = 1 ; cont < 7 ; cont ++){ 
				xxx = (2 * parseInt(data.substr(cont++,1))).toString() + "0"; 
				impares += parseInt(xxx.substr(0,1)) + parseInt(xxx.substr(1,1)); 
				pares += parseInt(data.substr(cont,1)); 
				} 
				xxx = (2 * parseInt(data.substr(cont,1))).toString() + "0"; 
				impares += parseInt(xxx.substr(0,1)) + parseInt(xxx.substr(1,1)); 
	
				suma = (pares + impares).toString(); 
				unumero = parseInt(suma.substr(suma.length - 1, 1)); 
				unumero = (10 - unumero).toString(); 
				if(unumero == 10) unumero = 0; 
	
				if ((ultima == unumero) || (ultima == uletra[unumero])){
					return true;  
				}else{ 
					return false;
				}
			}else if($('tipo_cliente').selectedIndex == 2){
				//validamos el NIF
				var value  = this.input.value;
				var dni=value.substring(0,value.length-1);
				var let=value.charAt(value.length-1);
				if (!isNaN(let))
				{
					return false;
				}
				if (isNaN(dni))
				{
					return false;
				}
				var cadena="TRWAGMYFPDXBNJZSQVHLCKET"
				var posicion = dni % 23;
				var letra = cadena.substring(posicion,posicion+1);
				if (letra!=let.toUpperCase())
				{
					return false;
				}
				return true;
			}else if($('tipo_cliente').selectedIndex == 4){ 
				//validamos el nie
				var value  = this.input.value;
				var primLetr=value.substring(0,1);
				primLetr=primLetr.toUpperCase();
				var nif=value.substring(1,value.length);
				if((primLetr!="X")&&(primLetr!="Y")&&(primLetr!="Z")) {
					return false;	
				}else{
					//validamos el resto(elemento sin la X) como si fuera un nif
					var dni=nif.substring(0,nif.length-1);
					var let=nif.charAt(nif.length-1);
					if (!isNaN(let))
					{
						return false;
					}
					if (isNaN(dni))
					{
						return false;
					}
					var cadena="TRWAGMYFPDXBNJZSQVHLCKET"
					var posicion = dni % 23;
					var letra = cadena.substring(posicion,posicion+1);
					if (letra!=let.toUpperCase())
					{
						return false;
					}
					return true;
				}	
			}
			return true;
		}
	}
)



var TipoDocumento2 = Class.create();
TipoDocumento2.prototype = Object.extend(
	Object.extend({},BaseValidator.prototype), 
	{
		concreteValidate: function(){
			
			// alert('Valor objeto: ' + this.input.value);
			
			if(this.input.value == "") return true;
			
			//alert ('Valor Combo: ' + $('tipo_cliente').value);
			
			if ($('tipo_cliente').value == 'F'){
				//validamos el cif
				var data = this.input.value;
				data = data.toUpperCase(); 
				var dataLong = this.input.value.length;
				var result = true;
				var pares = 0; 
				var impares = 0; 
				var suma; 
				var ultima; 
				var unumero; 
				var uletra = new Array("J", "A", "B", "C", "D", "E", "F", "G", "H", "I"); 
				var xxx; 
	
				var regular = /^([ABCDEFGHKLMNPQS]\d\d\d\d\d\d\d[0-9,A-J]){1}$/; 
				if (!regular.test(data)){
				return false; 
				}      
				ultima = data.substr(8,1); 
	
				for (var cont = 1 ; cont < 7 ; cont ++){ 
				xxx = (2 * parseInt(data.substr(cont++,1))).toString() + "0"; 
				impares += parseInt(xxx.substr(0,1)) + parseInt(xxx.substr(1,1)); 
				pares += parseInt(data.substr(cont,1)); 
				} 
				xxx = (2 * parseInt(data.substr(cont,1))).toString() + "0"; 
				impares += parseInt(xxx.substr(0,1)) + parseInt(xxx.substr(1,1)); 
	
				suma = (pares + impares).toString(); 
				unumero = parseInt(suma.substr(suma.length - 1, 1)); 
				unumero = (10 - unumero).toString(); 
				if(unumero == 10) unumero = 0; 
	
				if ((ultima == unumero) || (ultima == uletra[unumero])){
					return true;  
				}else{ 
					return false;
				}
			}else if($('tipo_cliente').value == 'I'){
				//validamos el NIF
				var value  = this.input.value;
				var dni=value.substring(0,value.length-1);
				var let=value.charAt(value.length-1);
				if (!isNaN(let))
				{
					return false;
				}
				if (isNaN(dni))
				{
					return false;
				}
				var cadena="TRWAGMYFPDXBNJZSQVHLCKET"
				var posicion = dni % 23;
				var letra = cadena.substring(posicion,posicion+1);
				if (letra!=let.toUpperCase())
				{
					return false;
				}
				return true;
			}else if($('tipo_cliente').value == 'C'){ 
				//validamos el nie
				var value  = this.input.value;
				var primLetr=value.substring(0,1);
				primLetr=primLetr.toUpperCase();
				var nif=value.substring(1,value.length);
				if((primLetr!="X")&&(primLetr!="Y")&&(primLetr!="Z")) {
					return false;	
				}else{
					//validamos el resto(elemento sin la X) como si fuera un nif
					var dni=nif.substring(0,nif.length-1);
					var let=nif.charAt(nif.length-1);
					if (!isNaN(let))
					{
						return false;
					}
					if (isNaN(dni))
					{
						return false;
					}
					var cadena="TRWAGMYFPDXBNJZSQVHLCKET"
					var posicion = dni % 23;
					var letra = cadena.substring(posicion,posicion+1);
					if (letra!=let.toUpperCase())
					{
						return false;
					}
					return true;
				}	
			}
			return true;
		}
	}
)
