/****************** Devy.UI.Forms.Validators.Base **********************/

Type.registerNamespace('Devy.UI.Forms.Validators');

Devy.UI.Forms.Validators.Base = function() {
    Devy.UI.Forms.Validators.Base.initializeBase(this);

    //Miembros
    this._FieldToValidate = null;
    this._ErrorMessage = "";

    this._ErrorMessageJQ = null;
    this._IsValid = false;

    this._AutoValidate = false;
    this._AutoValidationDelegate = null;
    this._AutoValidationEventsHooked = false;

    this._RenderErrorMessage = false;
}

Devy.UI.Forms.Validators.Base.prototype = {
    //*********************************************************************
    //Publicos
    set_FieldToValidate: function(value) {
        this._FieldToValidate = value;
        this._toogleAutoValidationEventsHooking();
    },
    get_FieldToValidate: function() { return this._FieldToValidate; },

    set_AutoValidate: function(value) {
        this._AutoValidate = value;
        this._toogleAutoValidationEventsHooking();
    },
    get_AutoValidate: function() { return this._AutoValidate; },

    _toogleAutoValidationEventsHooking: function() {
        if (!this._AutoValidationDelegate)
            this._AutoValidationDelegate = Function.createDelegate(this, this.Validate);

        if (this._AutoValidationEventsHooked && !this._AutoValidate) {
            //Esta hookeado, lo eliminamos
            $removeHandler(this._FieldToValidate, "blur", this._AutoValidationDelegate);
            this._AutoValidationEventsHooked = false;
        }
        else if (this._AutoValidate && !this._AutoValidationEventsHooked) {
            if (this._FieldToValidate) {
                $addHandler(this._FieldToValidate, "blur", this._AutoValidationDelegate);
                this._AutoValidationEventsHooked = true;
            }
        }
    },

    set_ErrorMessage: function(value) { this._ErrorMessage = value; },
    get_ErrorMessage: function() {
        var ret = this._ErrorMessage;
        if (!ret) ret = this.get_DefaultErrorMessage();
        return ret;
    },

    set_RenderErrorMessage: function(value) { this._RenderErrorMessage = value; },
    get_RenderErrorMessage: function() { return this._RenderErrorMessage; },

    get_IsValid: function() {
        return this._IsValid;
    },

    get_DefaultErrorMessage: function() { return "Este campo no es válido"; },

    dispose: function() {
        if (this._FieldToValidate) $clearHandlers(this._FieldToValidate);
        Devy.UI.Forms.Validators.Base.callBaseMethod(this, 'dispose');
    },

    Validate: function() {
        this._IsValid = this._DoValidation();

        if (this._RenderErrorMessage) {
            if (!this._ErrorMessageJQ) this._initializeErrorMessageJQ();


            if (this._IsValid) {
                this._ErrorMessageJQ.hide();
            }
            else {
                this._ErrorMessageJQ.html('<span>' + Devy.Util.HTMLEncode(this.get_ErrorMessage()) + '<span>');
                this._ErrorMessageJQ.show();
            }
        }


        if (this._IsValid) {
            this._raiseEvent('validationSuccess', '');
        }
        else {
            this._raiseEvent('validationError', this.get_ErrorMessage());
        }

        return this._IsValid;
    },

    _getFieldValue: function() {
        if (this._FieldToValidate.get_Value)
            return this._FieldToValidate.get_Value();
        else
            return this._FieldToValidate.value;
    },

    _DoValidation: function() {
        //Debe ser sobreescrita por las clases derivadas
        return true;
    },

    _initializeErrorMessageJQ: function() {
        this._ErrorMessageJQ = $('<p class="ValidationError"></p>').hide();
        this._ErrorMessageJQ.insertAfter(this._FieldToValidate);
    },

    //Mis eventos    
    get_events: function() {
        if (!this._events) {
            this._events = new Sys.EventHandlerList();
        }
        return this._events;
    },
    add_validationError: function(handler) {
        this.get_events().addHandler('validationError', handler);
    },
    remove_validationError: function(handler) {
        this.get_events().removeHandler('validationError', handler);
    },
    add_validationSuccess: function(handler) {
        this.get_events().addHandler('validationSuccess', handler);
    },
    remove_validationSuccess: function(handler) {
        this.get_events().removeHandler('validationSuccess', handler);
    },

    _raiseEvent: function(eventName, eventArgs) {
        var handler = this.get_events().getHandler(eventName);

        var theEventArgs = null;
        if (handler) {
            if (!eventArgs) {
                theEventArgs = Sys.EventArgs.Empty;
            }
            else {
                theEventArgs = eventArgs;
            }

            handler(this, theEventArgs);
        }
    }
}

Devy.UI.Forms.Validators.Base.registerClass('Devy.UI.Forms.Validators.Base', Sys.Component);


/** Devy.UI.Forms.Validators.Required *************************************/
Devy.UI.Forms.Validators.Required = function() {
    Devy.UI.Forms.Validators.Required.initializeBase(this);
}

Devy.UI.Forms.Validators.Required.prototype = {
    get_DefaultErrorMessage: function() { return "Requerido"; },
    _DoValidation: function() {
        var strValue = this._getFieldValue()
        if (strValue)
            strValue = strValue.toString();
        else
            strValue = "";

        if (strValue.length > 0)
            return true;
        else
            return false;
    }
}
Devy.UI.Forms.Validators.Required.registerClass('Devy.UI.Forms.Validators.Required', Devy.UI.Forms.Validators.Base);
/************************************* Devy.UI.Forms.Validators.Required **/

/** Devy.UI.Forms.Validators.RegularExpression *************************************/
Devy.UI.Forms.Validators.RegularExpression = function() {
    Devy.UI.Forms.Validators.RegularExpression.initializeBase(this);

    this._RegularExpression = '';
    this._RegularExpressionOptions = '';
    this._regex = null;
}

Devy.UI.Forms.Validators.RegularExpression.prototype = {
    set_RegularExpression: function(value) {
        this._RegularExpression = value;
        this._regex = null;
    },
    get_RegularExpression: function() { return this._RegularExpression; },

    set_RegularExpressionOptions: function(value) {
        this._RegularExpressionOptions = value;
        this._regex = null;
    },
    get_RegularExpressionOptions: function() { return this._RegularExpressionOptions; },

    get_DefaultErrorMessage: function() { return "Formato inválido"; },
    _DoValidation: function() {
        var value = this._getFieldValue();
        if (value) {

            if (!this._regex) this._regex = new RegExp(this._RegularExpression, this._RegularExpressionOptions);
            return value.match(this._regex);
        }
        else
            return true;
    }
}
Devy.UI.Forms.Validators.RegularExpression.registerClass('Devy.UI.Forms.Validators.RegularExpression', Devy.UI.Forms.Validators.Base);
/************************************* Devy.UI.Forms.Validators.RegularExpression **/

/** Devy.UI.Forms.Validators.ValidEmail *************************************/
Devy.UI.Forms.Validators.ValidEmail = function() {
    Devy.UI.Forms.Validators.ValidEmail.initializeBase(this);
}

Devy.UI.Forms.Validators.ValidEmail.prototype = {
    get_DefaultErrorMessage: function() { return "Formato de email inválido"; },

    initialize: function() {
        Devy.UI.Forms.Validators.ValidEmail.callBaseMethod(this, 'initialize');

        this.set_RegularExpressionOptions('i'); //ignore case
        this.set_RegularExpression("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$");
    }
}
Devy.UI.Forms.Validators.ValidEmail.registerClass('Devy.UI.Forms.Validators.ValidEmail', Devy.UI.Forms.Validators.RegularExpression);
/************************************* Devy.UI.Forms.Validators.ValidEmail **/

/** Devy.UI.Forms.Validators.ValidWebSite *************************************/
Devy.UI.Forms.Validators.ValidWebSite = function() {
    Devy.UI.Forms.Validators.ValidWebSite.initializeBase(this);
}

Devy.UI.Forms.Validators.ValidWebSite.prototype = {
    get_DefaultErrorMessage: function() { return "Debe comenzar con http:// o https:// y ser una dirección válida"; },

    initialize: function() {
        Devy.UI.Forms.Validators.ValidWebSite.callBaseMethod(this, 'initialize');

        this.set_RegularExpressionOptions('i'); //ignore case
        this.set_RegularExpression("^(http|https)://(([A-Z0-9_-]+)\\.)+[A-Z0-9_-]+$");
    }
}
Devy.UI.Forms.Validators.ValidWebSite.registerClass('Devy.UI.Forms.Validators.ValidWebSite', Devy.UI.Forms.Validators.RegularExpression);
/************************************* Devy.UI.Forms.Validators.ValidWebSite **/

/** Devy.UI.Forms.Validators.ValidDate *************************************/
Devy.UI.Forms.Validators.ValidDate = function() {
    Devy.UI.Forms.Validators.ValidDate.initializeBase(this);
}

Devy.UI.Forms.Validators.ValidDate.prototype = {
    get_DefaultErrorMessage: function() { return "Formato de fecha inválido"; },
    _DoValidation: function() {
        var text = this._getFieldValue();
        if (!text) return true;
        try {
            var tmp = Date.parseLocale(text);
            if (tmp)
                return true;
            else
                return false;
        }
        catch (e) {
            return false;
        }
    }
}
Devy.UI.Forms.Validators.ValidDate.registerClass('Devy.UI.Forms.Validators.ValidDate', Devy.UI.Forms.Validators.Base);
/************************************* Devy.UI.Forms.Validators.ValidDate **/

/** Devy.UI.Forms.Validators.StringLength *************************************/
Devy.UI.Forms.Validators.StringLength = function() {
    Devy.UI.Forms.Validators.StringLength.initializeBase(this);

    this._MinLength = 0;
    this._MaxLength = 0;

    this._DefaultErrorMessage = "";
}

Devy.UI.Forms.Validators.StringLength.prototype = {
    set_MinLength: function(value) { this._MinLength = value; },
    get_MinLength: function() { return this._MinLength; },

    set_MaxLength: function(value) { this._MaxLength = value; },
    get_MaxLength: function() { return this._MaxLength; },

    get_DefaultErrorMessage: function() { return this._DefaultErrorMessage; },

    _DoValidation: function() {
        var text = this._getFieldValue();
        if (!text) return true;

        var len = text.length;

        if (this._MinLength > 0 && this._MaxLength > 0) {
            if (len > this._MaxLength || len < this._MinLength) {

                this._DefaultErrorMessage
                    = String.format('{0} caracteres. Debe tener entre {1} y {2}',
                    len, this._MinLength, this._MaxLength);

                return false;
            }
        }
        else if (this._MinLength > 0) {
            if (len < this._MinLength) {
                this._DefaultErrorMessage
                    = String.format('{0} caracteres. Debe tener un mínimo de {1}',
                    len, this._MinLength);

                return false;
            }
        }
        else if (this._MaxLength > 0) {
            if (len > this._MaxLength) {
                this._DefaultErrorMessage
                    = String.format('{0} caracteres. Debe tener un máximo de {1}',
                    len, this._MaxLength);

                return false;
            }
        }

        return true;
    }
}
Devy.UI.Forms.Validators.StringLength.registerClass('Devy.UI.Forms.Validators.StringLength', Devy.UI.Forms.Validators.Base);
/************************************* Devy.UI.Forms.Validators.StringLength **/

/** Devy.UI.Forms.Validators.NumericRange *************************************/
Devy.UI.Forms.Validators.NumericRange = function() {
    Devy.UI.Forms.Validators.NumericRange.initializeBase(this);

    this._Min = 0;
    this._Max = 0;

    this._DefaultErrorMessage = "";
}

Devy.UI.Forms.Validators.NumericRange.prototype = {
    set_Min: function(value) { this._Min = value; },
    get_Min: function() { return this._Min; },

    set_Max: function(value) { this._Max = value; },
    get_Max: function() { return this._Max; },

    get_DefaultErrorMessage: function() { return this._DefaultErrorMessage; },

    _DoValidation: function() {
        var text = this._getFieldValue();
        if (!text) return true;

        var numero = parseFloat(text);

        if (this._Min !== undefined && this._Max > 0) {
            if (numero > this._Max || numero < this._Min) {

                this._DefaultErrorMessage
                    = String.format('Debe ser un número entre {0} y {1}',
                    this._Min, this._Max);

                return false;
            }
        }
        else if (this._Min > 0) {
            if (numero < this._Min) {
                this._DefaultErrorMessage
                    = String.format('Debe ser mayor o igual que {0}',
                    this._Min);

                return false;
            }
        }
        

        return true;
    }
}
Devy.UI.Forms.Validators.NumericRange.registerClass('Devy.UI.Forms.Validators.NumericRange', Devy.UI.Forms.Validators.Base);
/************************************* Devy.UI.Forms.Validators.NumericRange **/


/****************** Static Factory Methots **********************/
Devy.UI.Forms.Validators.CreateRequiredValidator = function(ErrorMessage, FieldToValidate) {
    var ret = new Devy.UI.Forms.Validators.Required();
    ret.set_ErrorMessage(ErrorMessage);
    ret.set_FieldToValidate(FieldToValidate);
    return ret;
}
Devy.UI.Forms.Validators.CreateStringLengthValidator = function(MinLength, MaxLength, ErrorMessage, FieldToValidate) {
    if (MinLength === undefined) MinLength = 0;
    if (MaxLength === undefined) MaxLength = 0;

    var ret = new Devy.UI.Forms.Validators.StringLength();
    ret.set_ErrorMessage(ErrorMessage);
    ret.set_FieldToValidate(FieldToValidate);
    ret.set_MinLength(MinLength);
    ret.set_MaxLength(MaxLength);
    return ret;
}
Devy.UI.Forms.Validators.CreateValidDateValidator = function(ErrorMessage, FieldToValidate) {
    var ret = new Devy.UI.Forms.Validators.ValidDate();
    ret.set_ErrorMessage(ErrorMessage);
    ret.set_FieldToValidate(FieldToValidate);
    return ret;
}
Devy.UI.Forms.Validators.CreateNumericRangeValidator = function(Min, Max, ErrorMessage, FieldToValidate) {
    if (Min === undefined) Min = 0;
    if (Max === undefined) Max = 0;

    var ret = new Devy.UI.Forms.Validators.NumericRange();
    ret.set_ErrorMessage(ErrorMessage);
    ret.set_FieldToValidate(FieldToValidate);
    ret.set_Min(Min);
    ret.set_Max(Max);
    return ret;
}
Devy.UI.Forms.Validators.CreateRegularExpressionValidator = function(RegularExpression, RegularExpressionOptions, ErrorMessage, FieldToValidate) {
    if (RegularExpression === undefined) RegularExpression = '';
    if (RegularExpressionOptions === undefined) RegularExpressionOptions = '';

    var ret = new Devy.UI.Forms.Validators.RegularExpression();
    ret.set_ErrorMessage(ErrorMessage);
    ret.set_FieldToValidate(FieldToValidate);
    ret.set_RegularExpression(RegularExpression);
    ret.set_RegularExpressionOptions(RegularExpressionOptions);
    return ret;
}
Devy.UI.Forms.Validators.CreateValidEmailValidator = function(ErrorMessage, FieldToValidate) {
    var ret = new Devy.UI.Forms.Validators.ValidEmail();
    ret.set_ErrorMessage(ErrorMessage);
    ret.set_FieldToValidate(FieldToValidate);
    ret.initialize();
    return ret;
}
Devy.UI.Forms.Validators.CreateValidWebSiteValidator = function(ErrorMessage, FieldToValidate) {
    var ret = new Devy.UI.Forms.Validators.ValidWebSite();
    ret.set_ErrorMessage(ErrorMessage);
    ret.set_FieldToValidate(FieldToValidate);
    ret.initialize();
    return ret;
}

