﻿
(function($) {

    // -------------------------------------------- jQuery.fn.jForm ----------------------------------------
    var vtt;
    var jFormElementSelectorsList = "input,select,textarea";
    jQuery.fn.jForm = function(options) {
        $this = this;
        return new function() {
            jQuery.extend(this, new jForm($this, options));
        };
    }

    function jForm(el, options) {
        this.form = el[0];
        this.el = el;
        if (typeof (vtt) == "undefined") vtt = $("#VTT");
    }

    jForm.prototype = {


        datatype: function() {
            var _datatype = this.el.attr('datatype')
            return (_datatype == null) ? '' : _datatype.toLowerCase();
        },

        reset: function() {
            $(jFormElementSelectorsList, this.form).each(function(i, el) {
                var type = this.type;
                var tag = this.tagName.toLowerCase();
                if (type == 'text' || type == 'password' || tag == 'textarea')
                    this.value = '';
                else if (type == 'checkbox' || type == 'radio')
                    this.checked = false;
                else if (tag == 'select') {
                    this.selectedIndex = 0;
                    $(this).change();
                }
            });
        },

        validate: function() {

            if (this.form == null) return false;

            var result = true;
            var oField = null;
            var oAvailabilityCheck = null;
            var ScrollToExecuted = false;
            $(jFormElementSelectorsList, this.form).each(function(i, el) {

                var passwordCounter, passwordField;

                var jF = $(this).jField();
                jF.el.val($.trim(jF.el.val()));


                if (jF.datatype() == '' && jF.mandatory() == false) return true;
                if (jF.mandatory() == false && jF.el.val() == '') return true;

                if (!jF.validate()) {
                    result = false;
                    jF.setInvalid();
                    if (!ScrollToExecuted) {
                        jF.el[0].scrollIntoView(true);
                        ScrollToExecuted = true;
                    }
                    return true;
                }

                if ((jF.type() == 'password' || jF.datatype() == 'password') && jF.datatype() != 'passwordrepeat' && passwordCounter == 0) {
                    passwordCounter++;
                    passwordField = el;
                }
                else if ((jF.type() == 'password' || jF.datatype() == 'password') && jF.datatype() != 'passwordrepeat' && passwordCounter == 1) {
                    if (passwordField.value != jF.el.val()) {
                        result = false;
                        passwordField.value = "";
                        return true;
                    }
                }
                jF.setValid();

            });

            jF = null;
            return result;
        }


    }


    // -------------------------------------------- jQuery.fn.jField ----------------------------------------
    jQuery.fn.jField = function(setvalidity) {

        $this = this;
        return new function() {
            jQuery.extend(this, new jField($this, setvalidity));
        };
    }

    function jField(el, setvalidity) {
        this.el = el;
        this.form = $(el[0].form);
        this.jForm = this.form.jForm();
        if (setvalidity != undefined) this.setvalidity = setvalidity;
    }

    jField.prototype = {

        el: null,
        form: null,
        jForm: null,
        setvalidity: true,

        valid: {
            errortype: null,
            ContainsValidCharsOnly: function(Value, ValidChars) {
                for (var i = 0; i < Value.length; i++) {
                    if (ValidChars.indexOf(Value.charAt(i)) == -1) return false;
                }
                return true;
            },

            ContainsInValidChars: function(Value, InValidChars) {
                for (var i = 0; i < Value.length; i++) {
                    if (InValidChars.indexOf(Value.charAt(i)) != -1) return true;
                }
                return false;
            },

            email: function(sEmail) {
                if (this.ContainsInValidChars(sEmail, "!#$'%^&*()+=<>?/,\|~`\"[]") || sEmail.indexOf('@') <= 1 || (sEmail.lastIndexOf(".") < sEmail.indexOf("@") + 2)) {
                    this.errortype = 'invalidchars';
                    return false;
                }

                return true;
            },

            phone: function(sPhone) {
                if (sPhone.length < 6 || sPhone.length > 15) {
                    this.errortype = 'invalidlength';
                    return false;
                }

                if (!this.ContainsValidCharsOnly(sPhone, ".0123456789()-+ ")) {
                    this.errortype = 'invalidchars';
                    return false;
                }

                return true;
            },

            username: function(sUserName) {
                if (sUserName.length < 4 || sUserName.length > 15) {
                    this.errortype = 'invalidlength';
                    return false;
                }

                var leftChar = String(sUserName).substring(0, 1);
                if (leftChar == '_' || leftChar == '.' || leftChar == '-' || !this.ContainsValidCharsOnly(sUserName, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890._-')) {
                    this.errortype = 'invalidchars';
                    return false;
                }

                return true;
            },


            numeric: function(sNumber, bFloat) {
                if (!this.ContainsValidCharsOnly(sNumber, "0123456789," + (bFloat ? '.' : ''))) {
                    this.errortype = 'invalidchars';
                    return false;
                }

                return true;
            },

            humanname: function(sName) {
                if (this.ContainsInValidChars(sName, "!@#$%^&*()_+=<>?/.,\|~`\"[]")) {
                    this.errortype = 'invalidchars';
                    return false;
                }

                return true;
            },

            password: function(sPassword) {

                if (sPassword.length < 6 || sPassword.length > 12) {
                    this.errortype = 'invalidlength';
                    return false;
                }

                if (this.ContainsInValidChars(sPassword, "'^,\"")) {
                    this.errortype = 'invalidchars';
                    return false;
                }

                return true;
            }
        },

        mandatory: function() {
            var _mandatory = this.el.attr('mandatory');
            return (_mandatory == null) ? false : ((_mandatory.toLowerCase() == 'true') ? true : false);
        },

        datatype: function() {
            var _datatype = this.el.attr('datatype')
            return (_datatype == null) ? '' : _datatype.toLowerCase();
        },

        minlength: function() {
            var _minlength = this.el.attr('minlength')
            return (_minlength == null) ? 0 : parseInt(_minlength);
        },

        maxlength: function() {
            var _maxlength = this.el.attr('maxlength')
            return (_maxlength == null) ? '' : parseInt(_maxlength);
        },

        minvalue: function() {
            var MinValue = this.el.attr('minvalue');
            return (MinValue == null) ? null : parseFloat(this.el.attr('minvalue'));
        },

        maxvalue: function() {
            var MaxValue = this.el.attr('maxvalue');
            return (MaxValue == null) ? null : parseFloat(this.el.attr('maxvalue'));
        },

        empty: function() {
            return $.trim(this.el.val()) != '' ? true : false;
        },

        message: function(val) {
            if (val != undefined) {
                this.el.attr('message', val);
            }
            else {
                return this.el.attr('message')
            }
        },

        originalmessage: function() {
            return this.el.attr('originalmessage')
        },

        originalvalue: function() {
            return this.el.attr('originalvalue')
        },

        type: function() {
            var _type = this.el[0].type;
            return (_type == null) ? '' : _type.toLowerCase();
        },

        setValid: function() {

            this.el.removeAttr("invalid");

            if (this.type() == 'checkbox') {
                this.el.parent().removeClass("InvalidCheckBoxValue");
            }
            else {
                this.el.removeClass("InvalidFieldValue");
            }

            this.el.unbind("focus");
            this.el.unbind("blur");
            this.el.unbind("mouseover");
            this.el.unbind("mouseout");
        },

        setInvalid: function() {

            if (this.el.attr("PostBinding") != 'true') {
                this.el.bind('ShowToolTip', function(e, bTimeout, message) { $(this).jField().ShowToolTip(bTimeout, message); });
                this.el.bind('HideToolTip', function(e) { $(this).jField().HideToolTip(); });
            }
            this.el.attr("PostBinding", 'true');

            this.el.attr("invalid", "true");
            if (this.type() == 'checkbox') {
                this.el.parent().addClass("InvalidCheckBoxValue");
            }
            else {
                this.el.addClass("InvalidFieldValue");
            }

            this.el.bind("focus", { "ff": this.el }, function(e) {
                $(this).trigger('HideToolTip', { timeout: true });
                $(this).jField().setValid();
            });

            this.el.bind("blur", { "ff": this.el }, function(e) {
                $(this).trigger('HideToolTip');
            });

            this.el.bind("mouseover", { "ff": this.el }, function(e) {
                $(this).trigger('ShowToolTip');
            });

            this.el.bind("mouseout", { "ff": this.el }, function(e) {
                $(this).trigger('HideToolTip');
            });
        },

        messages: jFormConstants.prototype.messages,

        showAlternativeValues: function() {

        },

        hideAlternativeValues: function() {

        },

        validate: function() {

            this.errortype = null;
            this.el.val($.trim(this.el.val()));

            if (this.type() != 'checkbox' && this.originalvalue() != null && !this.empty() && this.originalvalue() == this.el.val()) {
                this.message(this.originalmessage());
                if (this.setvalidity) this.setInvalid();
                return false;
            }

            if (this.mandatory() && (this.el.val().length == 0 || (this.type() == 'checkbox' && !this.el.is(":checked")))) {
                this.message((this.messages[this.datatype()] == undefined) ? this.messages.general.empty : this.messages[this.datatype()].empty);
                if (this.setvalidity) this.setInvalid();
                return false;
            }

            var result = false;
            var setMessage = true;
            switch (this.datatype()) {
                case 'username':
                    result = this.valid.username(this.el.val());
                    break;

                case 'nickname':
                    result = this.valid.nickname(this.el.val());
                    break;

                case 'password':
                case 'passwordrepeat':
                    result = this.valid.password(this.el.val());
                    break;

                case 'email':
                    result = this.valid.email(this.el.val());
                    break;

                case 'phone':
                case 'fax':
                case 'mobilephone':
                case 'cellphone':
                    result = this.valid.phone(this.el.val());
                    break;

                case 'numeric':
                    result = this.valid.numeric(this.el.val(), true);
                    if (result && this.minvalue() != null && this.maxvalue() != null) {
                        var FieldValue = parseFloat(this.el.val().replace(',', ''));
                        result = (FieldValue >= this.minvalue() && FieldValue <= this.maxvalue());
                        if (!result) { this.valid.errortype = 'invalidrange'; }
                    }
                    break;


                case 'numericrange':
                    var vala = this.el.val().split('-');

                    if (vala.length == 1) {
                        if (!this.valid.numeric(vala[0])) {
                            result = false;
                            break;
                        }
                        if (this.minvalue() != null && this.maxvalue() != null) {
                            result = (vala[0] >= this.minvalue() && vala[0] <= this.maxvalue())
                            this.valid.errortype = 'invalidrange';
                            break;
                        }
                        result = true;
                        break;
                    }

                    if (vala.length != 2) {
                        result = false;
                        break;
                    }

                    if (vala.length == 2 && (vala[1] == '' || vala[0] == '')) {
                        this.valid.errortype = 'invalidrange';
                        result = false;
                        break;
                    }

                    if (!this.valid.numeric(vala[0]) || !this.valid.numeric(vala[1])) {
                        result = false;
                        break;
                    }

                    if (this.minvalue() != null && this.maxvalue() != null) {
                        result = (vala[0] >= this.minvalue() && vala[0] <= this.maxvalue() && vala[1] >= this.minvalue() && vala[1] <= this.maxvalue())
                        if (!result) this.valid.errortype = 'invalidrange';
                        break;
                    }
                    result = true;
                    break;

                case 'firstname':
                case 'fullname':
                case 'lastname':
                case 'middlename':
                    result = this.valid.humanname(this.el.val());
                    break;

                default:
                    result = true;
            }

            if (!result) {
                this.el.attr('message', (this.messages[this.datatype()] == undefined) ? this.messages.general[this.valid.errortype] : this.messages[this.datatype()][this.valid.errortype]);
                if (this.valid.errortype == 'invalidrange') {
                    this.el.attr('message', this.el.attr('message') + "<HR/>" + "<B>" + this.messages.validrangeis + " : " + this.el.attr("minvalue") + " - " + this.el.attr("maxvalue") + "</B>");
                }

                if (this.valid.errortype == 'invalidlength') {
                    if (this.el.attr("minlength") != undefined && this.el.attr("maxlength") != undefined) {
                        this.el.attr('message', this.el.attr('message') + "<HR/>" + "<B>" + this.messages.validlengthis + " : " + this.el.attr("minlength") + " - " + this.el.attr("maxlength") + "</B>");
                    }
                    else {
                        this.el.attr('message', this.el.attr('message'));
                    }
                }

                if (this.setvalidity) this.setInvalid();
            }
            else {
                if (this.setvalidity) this.setValid();
            }

            return result
        },

        //--------------- showToolTip --------------- 
        ShowToolTip: function(options) {
            if (this.el.attr("invalid") != "true" && options.message == undefined) return;

            if (typeof (vtt) == "undefined") return;

            var vttPosition = this.el.position();
            var vttRightMargin = (RTL == false) ? (this.el.outerWidth() + 5) : -vtt.outerWidth() - 5;

            vtt.css("top", vttPosition.top + "px");
            vtt.css("left", (vttPosition.left + vttRightMargin) + "px");
            vtt.css("height", "21px");

            if (options != undefined && options.message != undefined && options.message != null) {
                $("div", vtt).html(options.message);
            }
            else {
                if (this.originalmessage() != null && this.originalmessage().length > 0 && (this.el.val() == this.originalvalue()))
                    $("div", vtt).html(this.originalmessage());
                else {
                    if (this.message() != null) {
                        $("div", vtt).html(this.message());
                    }
                    else {
                        $("div", vtt).html((this.messages[this.datatype()] == undefined) ? this.messages.general.invalidchars : this.messages[this.datatype()].invalidchars);
                    }
                }
            }

            $(this.el).parent().append(vtt);

            if (options == undefined || options.timeout == undefined || !options.timeout) {
                vtt.show();
            }
            else {
                var f = this.el;
                vtt.show();
                setTimeout(function() {
                    f.jField().hideToolTip(this.el, vtt);
                }, 3000);
            }
        },

        //--------------- hideToolTip ---------------	
        HideToolTip: function() {
            if (typeof (vtt) != "undefined") vtt.hide();
        }
    }

})(jQuery);


