
var Validator=Class.create();
Validator.prototype={
    initialize:function(className,error,test,options){
        if(typeof test=='function'){
            this.options=$H(options);
            this._test=test;
        }else{
            this.options=$H(test);
            this._test=function(){
                return true
                };
            
    }
    this.error=error||'Validation failed.';
    this.className=className;
},
test:function(v,elm){
    return(this._test(v,elm)&&this.options.all(function(p){
        return Validator.methods[p.key]?Validator.methods[p.key](v,elm,p.value):true;
    }));
}
}
Validator.methods={
    pattern:function(v,elm,opt){
        return Validation.get('IsEmpty').test(v)||opt.test(v)
        },
    minLength:function(v,elm,opt){
        return v.length>=opt
        },
    maxLength:function(v,elm,opt){
        return v.length<=opt
        },
    min:function(v,elm,opt){
        return v>=parseFloat(opt)
        },
    max:function(v,elm,opt){
        return v<=parseFloat(opt)
        },
    notOneOf:function(v,elm,opt){
        return $A(opt).all(function(value){
            return v!=value;
        })
        },
    oneOf:function(v,elm,opt){
        return $A(opt).any(function(value){
            return v==value;
        })
        },
    is:function(v,elm,opt){
        return v==opt
        },
    isNot:function(v,elm,opt){
        return v!=opt
        },
    equalToField:function(v,elm,opt){
        return v==$F(opt)
        },
    notEqualToField:function(v,elm,opt){
        return v!=$F(opt)
        },
    include:function(v,elm,opt){
        return $A(opt).all(function(value){
            return Validation.get(value).test(v,elm);
        })
        }
    }
var Validation=Class.create();
Validation.prototype={
    initialize:function(form,options){
        this.options=Object.extend({
            onSubmit:true,
            stopOnFirst:false,
            immediate:false,
            focusOnError:true,
            useTitles:false,
            onFormValidate:function(result,form){},
            onElementValidate:function(result,elm){}
        },options||{});
    this.form=$(form);
    if(this.options.onSubmit)Event.observe(this.form,'submit',this.onSubmit.bind(this),false);
    if(this.options.immediate){
        var useTitles=this.options.useTitles;
        var callback=this.options.onElementValidate;
        Form.getElements(this.form).each(function(input){
            Event.observe(input,'blur',function(ev){
                Validation.validate(Event.element(ev),{
                    useTitle:useTitles,
                    onElementValidate:callback
                });
            });
        });
    }
},
onSubmit:function(ev){
    if(!this.validate())Event.stop(ev);
},
validate:function(){
    var result=false;
    var useTitles=this.options.useTitles;
    var callback=this.options.onElementValidate;
    if(this.options.stopOnFirst){
        result=Form.getElements(this.form).all(function(elm){
            return Validation.validate(elm,{
                useTitle:useTitles,
                onElementValidate:callback
            });
        });
    }else{
        result=Form.getElements(this.form).collect(function(elm){
            return Validation.validate(elm,{
                useTitle:useTitles,
                onElementValidate:callback
            });
        }).all();
    }
    if(!result&&this.options.focusOnError){
        Form.getElements(this.form).findAll(function(elm){
            return $(elm).hasClassName('validation-failed')
            }).first().focus()
        }
    this.options.onFormValidate(result,this.form);
    return result;
},
reset:function(){
    Form.getElements(this.form).each(Validation.reset);
}
}
Object.extend(Validation,{
    validate:function(elm,options){
        options=Object.extend({
            useTitle:false,
            onElementValidate:function(result,elm){}
        },options||{});
    elm=$(elm);
    var cn=elm.classNames();
    return result=cn.all(function(value){
        var test=Validation.test(value,elm,options.useTitle);
        options.onElementValidate(test,elm);
        return test;
    });
},
test:function(name,elm,useTitle){
    var v=Validation.get(name);
    var prop='__advice'+name.camelize();
    try{
        if(Validation.isVisible(elm)&&!v.test($F(elm),elm)){
            if(!elm[prop]){
                var advice=Validation.getAdvice(name,elm);
                if(advice==null){
                    var errorMsg=useTitle?((elm&&elm.title)?elm.title:v.error):v.error;
                    advice='<div class="validation-advice" id="advice-'+name+'-'+Validation.getElmID(elm)+'" style="display:none">'+errorMsg+'</div>'
                    switch(elm.type.toLowerCase()){
                        case'checkbox':case'radio':
                            var p=elm.parentNode;
                            if(p){
                            new Insertion.Bottom(p,advice);
                        }else{
                            new Insertion.After(elm,advice);
                        }
                        break;
                        default:
                            new Insertion.After(elm,advice);
                    }
                    advice=Validation.getAdvice(name,elm);
                }
                if(typeof Effect=='undefined'){
                    advice.style.display='block';
                }else{
                    new Effect.Appear(advice,{
                        duration:1
                    });
                }
            }
        elm[prop]=true;
        elm.removeClassName('validation-passed');
        elm.addClassName('validation-failed');
        return false;
    }else{
        var advice=Validation.getAdvice(name,elm);
        if(advice!=null)advice.hide();
        elm[prop]='';
        elm.removeClassName('validation-failed');
        elm.addClassName('validation-passed');
        return true;
    }
}catch(e){
    throw(e)
    }
},
isVisible:function(elm){
    while(elm.tagName!='BODY'){
        if(!$(elm).visible())return false;
        elm=elm.parentNode;
    }
    return true;
},
getAdvice:function(name,elm){
    return $('advice-'+name+'-'+Validation.getElmID(elm))||$('advice-'+Validation.getElmID(elm));
},
getElmID:function(elm){
    return elm.id?elm.id:elm.name;
},
reset:function(elm){
    elm=$(elm);
    var cn=elm.classNames();
    cn.each(function(value){
        var prop='__advice'+value.camelize();
        if(elm[prop]){
            var advice=Validation.getAdvice(value,elm);
            advice.hide();
            elm[prop]='';
        }
        elm.removeClassName('validation-failed');
        elm.removeClassName('validation-passed');
    });
},
add:function(className,error,test,options){
    var nv={};
    
    nv[className]=new Validator(className,error,test,options);
    Object.extend(Validation.methods,nv);
},
addAllThese:function(validators){
    var nv={};
    
    $A(validators).each(function(value){
        nv[value[0]]=new Validator(value[0],value[1],value[2],(value.length>3?value[3]:{}));
    });
    Object.extend(Validation.methods,nv);
},
get:function(name){
    return Validation.methods[name]?Validation.methods[name]:Validation.methods['_LikeNoIDIEverSaw_'];
},
methods:{
    '_LikeNoIDIEverSaw_':new Validator('_LikeNoIDIEverSaw_','',{})
    }
});
Validation.add('IsEmpty','',function(v){
    return((v==null)||(v.length==0));
});
Validation.addAllThese([['required','<span style=\'color: #EF7E08; font-weight:bold\'>&Eacute;ste campo es obligatorio.</span>',function(v){
    return!Validation.get('IsEmpty').test(v);}],
    
['validate-number','<span style=\'color: #EF7E08; font-weight:bold\'>Introduzca un n&uacute;mero v&aacute;lido.</span>',function(v){
                return Validation.get('IsEmpty').test(v)||(!isNaN(v)&&!/^\s+$/.test(v));}],

['validate-digits','<span style=\'color: #EF7E08; font-weight:bold\'>Por favor, use s&oacute;lo n&uacute;meros en este campo, evite espacios u otros caracteres que ni sean d&iacute;gitos.</span>',function(v){
    return Validation.get('IsEmpty').test(v)||!/[^\d]/.test(v);}],


['validate-alpha','<span style=\'color: #EF7E08; font-weight:bold\'>Por favor, use solo letras (A-Z) en este campo.</span>',function(v){
    return Validation.get('IsEmpty').test(v)||/^[a-zA-Z]+$/.test(v)
    }],

['validate-alphanum','<span style=\'color: #EF7E08; font-weight:bold\'>Por favor, use solo letras (a-z) y n&uacute;meros (0-9) s&oacute;lo en este &aacute;mbito. Sin espacios ni otros caracteres est&aacute;n permitidos.</span>',function(v){
    return Validation.get('IsEmpty').test(v)||!/\W/.test(v)
    }],

['validate-date','<span style=\'color: #EF7E08; font-weight:bold\'>Por favor, introduzca una fecha v&aacute;lida.</span>',function(v){
    var test=new Date(v);
    return Validation.get('IsEmpty').test(v)||!isNaN(test);}],

['validate-email','<span style=\'color: #EF7E08; font-weight:bold\'>Por favor, introduzca una direcci&oacute;n de <br/>correo electr&oacute;nico v&aacute;lida.</span>',function(v){
    return Validation.get('IsEmpty').test(v)||/\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/.test(v)
    }],['validate-url','<span style=\'color: #EF7E08; font-weight:bold\' >Introduzca una direcci&oacute;n URL correcta del tipo \'http:\/\/www.dominio.com \'.</span>',function(v){
    return Validation.get('IsEmpty').test(v)||/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i.test(v)||/^(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i.test(v)
    }],
    
['validate-date-au','<span style=\'color: #EF7E08; font-weight:bold\' >Por favor, use este formato de fecha: dd / mm / aaaa. Por ejemplo 17/03/2023 para el 17 de marzo de 2023.</span>',function(v){
    if(Validation.get('IsEmpty').test(v))return true;
    var regex=/^(\d{2})\/(\d{2})\/(\d{4})$/;
    if(!regex.test(v))return false;
    var d=new Date(v.replace(regex,'$2/$1/$3'));
    return(parseInt(RegExp.$2,10)==(1+d.getMonth()))&&(parseInt(RegExp.$1,10)==d.getDate())&&(parseInt(RegExp.$3,10)==d.getFullYear());}],
    
['validate-currency-dollar','Please enter a valid $ amount. For example $100.00 .',function(v){
    return Validation.get('IsEmpty').test(v)||/^\$?\-?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}\d*(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/.test(v)
    }],['validate-selection','<span style=\'color: #EF7E08; font-weight:bold\'>Por favor, haga una selecci&oacute;n.</span>',function(v,elm){
    return elm.options?elm.selectedIndex>0:!Validation.get('IsEmpty').test(v);}],

['validate-year','<span style=\'color: #EF7E08; font-weight:bold\'>El a&ntilde;o no es v&aacute;lido.</span>',function(v,elm){
    return Validation.get('IsEmpty').test(v)||/^\d{4}$/.test(v)    }],
       
['validate-telefono','<span style=\'color: #EF7E08; font-weight:bold\'>El tel&eacute;fono no es v&aacute;lido.</span>',function(v,elm){
    return Validation.get('IsEmpty').test(v)||/^[0-9]{2,3}[0-9]{6,7}$/.test(v)    }],
    
['validate-fax','<span style=\'color: #EF7E08; font-weight:bold\'>El fax no es v&aacute;lido.</span>',function(v,elm){
    return Validation.get('IsEmpty').test(v)||/^[0-9]{2,3}[0-9]{6,7}$/.test(v)    }],
    
['validate-one-required','<span style=\'color: #EF7E08; font-weight:bold\'>Por favor, seleccione una de las opciones anteriores.</span>',function(v,elm){
    var p=elm.parentNode;
    var options=p.getElementsByTagName('INPUT');
    return $A(options).any(function(elm){
        return $F(elm);
    });
}]]);