(function($, win, undef) {
    var errorobj = null,
    msgobj = null,
    msghidden = true;
    var rootpath = document.scripts;
    var css = "default.css";
    rootpath = rootpath[rootpath.length - 1].src.substring(0, rootpath[rootpath.length - 1].src.lastIndexOf("/") + 1);
    if (!css || css.length === 0) {
        alert('argument "csspath" is required !')
    }
    $("<link>").attr({
        rel: "stylesheet",
        type: "text/css",
        href: rootpath + css
    }).appendTo("head");
    var tipmsg = {
        tit: "",
        w: {
            "*": "不能为空！",
            "*6-16": "请填写6到16位任意字符！",
            "n": "请填写数字！",
            "n6-16": "请填写6到16位数字！",
            "s": "不能输入特殊字符！",
            "s6-18": "请填写6到18位字符！",
            "p": "请填写邮政编码！",
            "m": "请填写手机号码！",
            "e": "邮箱地址格式不对！",
            "url": "请填写网址！"
        },
        def: "请填写正确信息！",
        undef: "datatype未定义！",
        reck: "两次输入的内容不一致！",
        r: "通过信息验证！",
        c: "正在检测信息…",
        s: "请{填写|选择}{0|信息}！",
        v: "所填信息没有经过验证，请稍后…",
        p: "正在提交数据…"
    };
    $.Tipmsg = tipmsg;
    var validform = function(forms, settings, inited) {
        var settings = $.extend({},
        validform.defaults, settings);
        settings.datatype && $.extend(validform.util.dataType, settings.datatype);
        var brothers = this;
        brothers.tipmsg = {
            w: {}
        };
        brothers.forms = forms;
        brothers.objects = [];
        if (inited === true) {
            return false
        }
        forms.each(function() {
            if (this.validform_inited == "inited") {
                return true
            }
            this.validform_inited = "inited";
            var curform = this;
            curform.settings = $.extend({},
            settings);
            var $this = $(curform);
            curform.validform_status = "normal";
            $this.data("tipmsg", brothers.tipmsg);
            $this.delegate("[datatype]", "blur",
            function() {
                var subpost = arguments[1];
                validform.util.check.call(this, $this, subpost)
            });
            $this.delegate(":text", "keypress",
            function(event) {
                if (event.keyCode == 13 && $this.find(":submit").length == 0) {
                    $this.submit()
                }
            });
            validform.util.enhance.call($this, curform.settings.tiptype, curform.settings.usePlugin, curform.settings.tipSweep);
            curform.settings.btnSubmit && $this.find(curform.settings.btnSubmit).bind("click",
            function() {
                $this.trigger("submit");
                return false
            });
            $this.submit(function() {
                var subflag = validform.util.submitForm.call($this, curform.settings);
                subflag === undef && (subflag = true);
                return subflag
            });
            $this.find("[type='reset']").add($this.find(curform.settings.btnReset)).bind("click",
            function() {
                validform.util.resetForm.call($this)
            })
        });
        if (settings.tiptype == 1 || (settings.tiptype == 2 || settings.tiptype == 3) && settings.ajaxPost) {
            creatMsgbox()
        }
    };
    validform.defaults = {
        tiptype: 2,
        tipSweep: false,
        showAllError: false,
        postonce: false,
        ajaxPost: true
    };
    validform.util = {
        dataType: {
            "*": /[\w\W]+/,
            "*6-16": /^[\w\W]{6,16}$/,
            "n": /^\d+$/,
            "n6-16": /^\d{6,16}$/,
            "s": /^[\u4E00-\u9FA5\uf900-\ufa2d\w\.\s]+$/,
            "s6-18": /^[\u4E00-\u9FA5\uf900-\ufa2d\w\.\s]{6,18}$/,
            "p": /^[0-9]{6}$/,
            "m": /^13[0-9]{9}$|14[0-9]{9}|15[0-9]{9}$|18[0-9]{9}$/,
            "e": /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
            "url": /^(\w+:\/\/)?\w+(\.\w+)+.*$/
        },
        toString: Object.prototype.toString,
        isEmpty: function(val) {
            return val === "" || val === $.trim(this.attr("tip"))
        },
        getValue: function(obj) {
            var inputval, curform = this;
            if (obj.is(":radio")) {
                inputval = curform.find(":radio[name='" + obj.attr("name") + "']:checked").val();
                inputval = inputval === undef ? "": inputval
            } else {
                if (obj.is(":checkbox")) {
                    inputval = "";
                    curform.find(":checkbox[name='" + obj.attr("name") + "']:checked").each(function() {
                        inputval += $(this).val() + ","
                    });
                    inputval = inputval === undef ? "": inputval
                } else {
                    inputval = obj.val()
                }
            }
            inputval = $.trim(inputval);
            return validform.util.isEmpty.call(obj, inputval) ? "": inputval
        },
        enhance: function(tiptype, usePlugin, tipSweep, addRule) {
            var curform = this;
            curform.find("[datatype]").each(function() {
                if (tiptype == 2) {
                    if ($(this).parent().next().find(".validform_checktip").length == 0) {
                        $(this).parent().next().append("<span class='validform_checktip' />");
                        $(this).siblings(".validform_checktip").remove()
                    }
                } else {
                    if (tiptype == 3 || tiptype == 4) {
                        if ($(this).siblings(".validform_checktip").length == 0) {
                            $(this).parent().append("<span class='validform_checktip' />");
                            $(this).parent().next().find(".validform_checktip").remove()
                        }
                    }
                }
            });
            curform.find("input[recheck]").each(function() {
                if (this.validform_inited == "inited") {
                    return true
                }
                this.validform_inited = "inited";
                var _this = $(this);
                var recheckinput = curform.find("input[name='" + $(this).attr("recheck") + "']");
                recheckinput.bind("keyup",
                function() {
                    if (recheckinput.val() == _this.val() && recheckinput.val() != "") {
                        if (recheckinput.attr("tip")) {
                            if (recheckinput.attr("tip") == recheckinput.val()) {
                                return false
                            }
                        }
                        _this.trigger("blur")
                    }
                }).bind("blur",
                function() {
                    if (recheckinput.val() != _this.val() && _this.val() != "") {
                        if (_this.attr("tip")) {
                            if (_this.attr("tip") == _this.val()) {
                                return false
                            }
                        }
                        _this.trigger("blur")
                    }
                })
            });
            curform.find("[tip]").each(function() {
                if (this.validform_inited == "inited") {
                    return true
                }
                this.validform_inited = "inited";
                var defaultvalue = $(this).attr("tip");
                var altercss = $(this).attr("altercss");
                $(this).focus(function() {
                    if ($(this).val() == defaultvalue) {
                        $(this).val("");
                        if (altercss) {
                            $(this).removeClass(altercss)
                        }
                    }
                }).blur(function() {
                    if ($.trim($(this).val()) === "") {
                        $(this).val(defaultvalue);
                        if (altercss) {
                            $(this).addClass(altercss)
                        }
                    }
                })
            });
            curform.find(":checkbox[datatype],:radio[datatype]").each(function() {
                if (this.validform_inited == "inited") {
                    return true
                }
                this.validform_inited = "inited";
                var _this = $(this);
                var name = _this.attr("name");
                curform.find("[name='" + name + "']").filter(":checkbox,:radio").bind("click",
                function() {
                    setTimeout(function() {
                        _this.trigger("blur")
                    },
                    0)
                })
            });
            curform.find("select[datatype][multiple]").bind("click",
            function() {
                var _this = $(this);
                setTimeout(function() {
                    _this.trigger("blur")
                },
                0)
            });
            curform.find("[plugin]").each(function() {
                var pluginvalue = $(this).attr("plugin");
                $("<script>").attr({
                    type: "text/javascript",
                    src: rootpath + pluginvalue + ".js"
                }).appendTo("head")
            });
            validform.util.usePlugin.call(curform, usePlugin, tiptype, tipSweep, addRule)
        },
        usePlugin: function(plugin, tiptype, tipSweep, addRule) {
            var curform = this,
            plugin = plugin || {};
            if (curform.find("input[plugin='swfupload']").length && typeof(swfuploadhandler) != "undefined") {
                var custom = {
                    custom_settings: {
                        form: curform,
                        showmsg: function(msg, type, obj) {
                            validform.util.showmsg.call(curform, msg, tiptype, {
                                obj: curform.find("input[plugin='swfupload']"),
                                type: type,
                                sweep: tipSweep
                            })
                        }
                    }
                };
                custom = $.extend(true, {},
                plugin.swfupload, custom);
                curform.find("input[plugin='swfupload']").each(function(n) {
                    if (this.validform_inited == "inited") {
                        return true
                    }
                    this.validform_inited = "inited";
                    $(this).val("");
                    swfuploadhandler.init(custom, n)
                })
            }
            if (curform.find("input[plugin='email']").length && $.fn.email) {
                plugin.email = plugin.email || {};
                curform.find("input[plugin='email']").each(function(n) {
                    if (this.validform_inited == "inited") {
                        return true
                    }
                    this.validform_inited = "inited";
                    $(this).email(plugin.email)
                })
            }
            if (curform.find("input[plugin='calendar']").length && calendar) {
                curform.find("input[plugin='calendar']").each(function(n) {
                    if (this.validform_inited == "inited") {
                        return true
                    }
                    this.validform_inited = "inited";
                    var format = $(this).attr("format") || "YYYY-MM-DD hh:mm:ss";
                    var istime = $(this).attr("istime") || true;
                    $(this).addClass("calendar-icon");
                    plugin.calendar = plugin.calendar || {
                        istoday: true,
                        istime: istime,
                        festival: true,
                        format: format
                    };
                    $(this).click(function() {
                        calendar(plugin.calendar)
                    })
                })
            }
            if (curform.find("input[plugin*='password']").length && $.fn.password) {
                plugin.password = plugin.password || {};
                plugin.password.showmsg = function(obj, msg, type) {
                    validform.util.showmsg.call(curform, msg, tiptype, {
                        obj: obj,
                        type: type,
                        sweep: tipSweep
                    })
                };
                curform.find("input[plugin='password']").each(function(n) {
                    if (this.validform_inited == "inited") {
                        return true
                    }
                    this.validform_inited = "inited";
                    $(this).password(plugin.password)
                })
            }
            if (addRule != "addRule" && plugin.jqtransform && $.fn.jqTransSelect) {
                if (curform[0].jqTransSelected == "true") {
                    return
                }
                curform[0].jqTransSelected = "true";
                var jqTransformHideSelect = function(oTarget) {
                    var ulVisible = $(".jqTransformSelectWrapper ul:visible");
                    ulVisible.each(function() {
                        var oSelect = $(this).parents(".jqTransformSelectWrapper:first").find("select").get(0);
                        if (! (oTarget && oSelect.oLabel && oSelect.oLabel.get(0) == oTarget.get(0))) {
                            $(this).hide()
                        }
                    })
                };
                var jqTransformCheckExternalClick = function(event) {
                    if ($(event.target).parents(".jqTransformSelectWrapper").length === 0) {
                        jqTransformHideSelect($(event.target))
                    }
                };
                var jqTransformAddDocumentListener = function() {
                    $(document).mousedown(jqTransformCheckExternalClick)
                };
                if (plugin.jqtransform.selector) {
                    curform.find(plugin.jqtransform.selector).filter('input:submit, input:reset, input[type="button"]').jqTransInputButton();
                    curform.find(plugin.jqtransform.selector).filter("input:text, input:password").jqTransInputText();
                    curform.find(plugin.jqtransform.selector).filter("input:checkbox").jqTransCheckBox();
                    curform.find(plugin.jqtransform.selector).filter("input:radio").jqTransRadio();
                    curform.find(plugin.jqtransform.selector).filter("textarea").jqTransTextarea();
                    if (curform.find(plugin.jqtransform.selector).filter("select").length > 0) {
                        curform.find(plugin.jqtransform.selector).filter("select").jqTransSelect();
                        jqTransformAddDocumentListener()
                    }
                } else {
                    curform.jqTransform()
                }
                curform.find(".jqTransformSelectWrapper").find("li a").click(function() {
                    $(this).parents(".jqTransformSelectWrapper").find("select").trigger("blur")
                })
            }
        },
        getEmptymsg: function(curform) {
            var obj = this;
            var reg = /[\u4E00-\u9FA5\uf900-\ufa2da-zA-Z\s]+/g;
            var empty;
            var label = curform[0].settings.label || ".validform_label";
            label = obj.siblings(label).eq(0).text() || obj.siblings().find(label).eq(0).text() || obj.parent().siblings(label).eq(0).text() || obj.parent().siblings().find(label).eq(0).text();
            label = label.replace(/\s(?![a-zA-Z])/g, "").match(reg);
            label = label ? label.join("") : [""];
            reg = /\{(.+)\|(.+)\}/;
            empty = curform.data("tipmsg").s || tipmsg.s;
            if (label != "") {
                empty = empty.replace(/\{0\|(.+)\}/, label);
                if (obj.attr("recheck")) {
                    empty = empty.replace(/\{(.+)\}/, "");
                    obj.attr("empty", empty);
                    return empty
                }
            } else {
                empty = obj.is(":checkbox,:radio,select") ? empty.replace(/\{0\|(.+)\}/, "") : empty.replace(/\{0\|(.+)\}/, "$1")
            }
            empty = obj.is(":checkbox,:radio,select") ? empty.replace(reg, "$2") : empty.replace(reg, "$1");
            obj.attr("empty", empty);
            return empty
        },
        getErrormsg: function(curform, datatype, recheck) {
            var regxp = /^(.+?)((\d+)-(\d+))?$/,
            regxp2 = /^(.+?)(\d+)-(\d+)$/,
            regxp3 = /(.*?)\d+(.+?)\d+(.*)/,
            mac = datatype.match(regxp),
            temp,
            str;
            if (recheck == "recheck") {
                str = curform.data("tipmsg").reck || tipmsg.reck;
                return str
            }
            var tipmsg_w_ex = $.extend({},
            tipmsg.w, curform.data("tipmsg").w);
            if (mac[0] in tipmsg_w_ex) {
                return curform.data("tipmsg").w[mac[0]] || tipmsg.w[mac[0]]
            }
            for (var name in tipmsg_w_ex) {
                if (name.indexOf(mac[1]) != -1 && regxp2.test(name)) {
                    str = (curform.data("tipmsg").w[name] || tipmsg.w[name]).replace(regxp3, "$1" + mac[3] + "$2" + mac[4] + "$3");
                    curform.data("tipmsg").w[mac[0]] = str;
                    return str
                }
            }
            return curform.data("tipmsg").def || tipmsg.def
        },
        _regcheck: function(datatype, gets, obj, curform) {
            var curform = curform,
            info = null,
            passed = false,
            reg = /\/.+\//g,
            regex = /^(.+?)(\d+)-(\d+)$/,
            type = 3;
            if (reg.test(datatype)) {
                var regstr = datatype.match(reg)[0].slice(1, -1);
                var param = datatype.replace(reg, "");
                var rexp = RegExp(regstr, param);
                passed = rexp.test(gets)
            } else {
                if (validform.util.toString.call(validform.util.dataType[datatype]) == "[object Function]") {
                    passed = validform.util.dataType[datatype](gets, obj, curform, validform.util.dataType);
                    if (passed === true || passed === undef) {
                        passed = true
                    } else {
                        info = passed;
                        passed = false
                    }
                } else {
                    if (! (datatype in validform.util.dataType)) {
                        var mac = datatype.match(regex),
                        temp;
                        if (!mac) {
                            passed = false;
                            info = curform.data("tipmsg").undef || tipmsg.undef
                        } else {
                            for (var name in validform.util.dataType) {
                                temp = name.match(regex);
                                if (!temp) {
                                    continue
                                }
                                if (mac[1] === temp[1]) {
                                    var str = validform.util.dataType[name].toString(),
                                    param = str.match(/\/[mgi]*/g)[1].replace("/", ""),
                                    regxp = new RegExp("\\{" + temp[2] + "," + temp[3] + "\\}", "g");
                                    str = str.replace(/\/[mgi]*/g, "/").replace(regxp, "{" + mac[2] + "," + mac[3] + "}").replace(/^\//, "").replace(/\/$/, "");
                                    validform.util.dataType[datatype] = new RegExp(str, param);
                                    break
                                }
                            }
                        }
                    }
                    if (validform.util.toString.call(validform.util.dataType[datatype]) == "[object RegExp]") {
                        passed = validform.util.dataType[datatype].test(gets)
                    }
                }
            }
            if (passed) {
                type = 2;
                info = obj.attr("sucmsg") || curform.data("tipmsg").r || tipmsg.r;
                if (obj.attr("recheck")) {
                    var theother = curform.find("input[name='" + obj.attr("recheck") + "']:first");
                    if (gets != theother.val()) {
                        passed = false;
                        type = 3;
                        info = obj.attr("error") || validform.util.getErrormsg.call(obj, curform, datatype, "recheck")
                    }
                }
            } else {
                info = info || obj.attr("error") || validform.util.getErrormsg.call(obj, curform, datatype);
                if (validform.util.isEmpty.call(obj, gets)) {
                    info = obj.attr("empty") || validform.util.getErrormsg.call(obj, curform)
                }
            }
            return {
                passed: passed,
                type: type,
                info: info
            }
        },
        regcheck: function(datatype, gets, obj) {
            var curform = this,
            info = null,
            passed = false,
            type = 3;
            if (obj.attr("ignore") === "ignore" && validform.util.isEmpty.call(obj, gets)) {
                if (obj.data("cked")) {
                    info = ""
                }
                return {
                    passed: true,
                    type: 4,
                    info: info
                }
            }
            obj.data("cked", "cked");
            var dtype = validform.util.parseDatatype(datatype);
            var res;
            for (var eithor = 0; eithor < dtype.length; eithor++) {
                for (var dtp = 0; dtp < dtype[eithor].length; dtp++) {
                    res = validform.util._regcheck(dtype[eithor][dtp], gets, obj, curform);
                    if (!res.passed) {
                        break
                    }
                }
                if (res.passed) {
                    break
                }
            }
            return res
        },
        parseDatatype: function(datatype) {
            var reg = /\/.+?\/[mgi]*(?=(,|$|\||\s))|[\w\*-]+/g,
            dtype = datatype.match(reg),
            sepor = datatype.replace(reg, "").replace(/\s*/g, "").split(""),
            arr = [],
            m = 0;
            arr[0] = [];
            arr[0].push(dtype[0]);
            for (var n = 0; n < sepor.length; n++) {
                if (sepor[n] == "|") {
                    m++;
                    arr[m] = []
                }
                arr[m].push(dtype[n + 1])
            }
            return arr
        },
        showmsg: function(msg, type, o, triggered) {
            if (msg == undef) {
                return
            }
            if (triggered == "bycheck" && o.sweep && (o.obj && !o.obj.is(".validform_error") || typeof type == "function")) {
                return
            }
            $.extend(o, {
                curform: this
            });
            if (typeof type == "function") {
                type(msg, o, validform.util.cssctl);
                return
            }
            if (type == 1 || triggered == "byajax" && type != 4) {
                msgobj.find(".validform_content").html(msg)
            }
            if (type == 1 && triggered != "bycheck" && o.type != 2 || triggered == "byajax" && type != 4) {
                msghidden = false;
                msgobj.find(".iframe").css("height", msgobj.outerHeight());
                msgobj.fadeIn();
                msgobjbg.fadeIn();
            }
            if (type == 2 && o.obj) {
                o.obj.parent().next().find(".validform_checktip").html(msg);
                validform.util.cssctl(o.obj.parent().next().find(".validform_checktip"), o.type)
            }
            if ((type == 3 || type == 4) && o.obj) {
                o.obj.siblings(".validform_checktip").html(msg);
                validform.util.cssctl(o.obj.siblings(".validform_checktip"), o.type)
            }
        },
        cssctl: function(obj, status) {
            switch (status) {
            case 1:
                obj.removeClass("validform_right validform_wrong").addClass("validform_checktip validform_loading");
                break;
            case 2:
                obj.removeClass("validform_wrong validform_loading").addClass("validform_checktip validform_right");
                break;
            case 4:
                obj.removeClass("validform_right validform_wrong validform_loading").addClass("validform_checktip");
                break;
            default:
                obj.removeClass("validform_right validform_loading").addClass("validform_checktip validform_wrong")
            }
        },
        check: function(curform, subpost, bool) {
            var settings = curform[0].settings;
            var subpost = subpost || "";
            var inputval = validform.util.getValue.call(curform, $(this));
            if (settings.ignoreHidden && $(this).is(":hidden") || $(this).data("dataIgnore") === "dataIgnore") {
                return true
            }
            if (settings.dragonfly && !$(this).data("cked") && validform.util.isEmpty.call($(this), inputval) && $(this).attr("ignore") != "ignore") {
                return false
            }
            var flag = validform.util.regcheck.call(curform, $(this).attr("datatype"), inputval, $(this));
            if (inputval == this.validform_lastval && !$(this).attr("recheck") && subpost == "") {
                return flag.passed ? true: false
            }
            this.validform_lastval = inputval;
            var _this;
            errorobj = _this = $(this);
            if (!flag.passed) {
                validform.util.abort.call(_this[0]);
                if (!bool) {
                    validform.util.showmsg.call(curform, flag.info, settings.tiptype, {
                        obj: $(this),
                        type: flag.type,
                        sweep: settings.tipSweep
                    },
                    "bycheck"); ! settings.tipSweep && _this.addClass("validform_error")
                }
                return false
            }
            var ajaxurl = $(this).attr("ajaxurl");
            if (ajaxurl && !validform.util.isEmpty.call($(this), inputval) && !bool) {
                var inputobj = $(this);
                if (subpost == "postform") {
                    inputobj[0].validform_subpost = "postform"
                } else {
                    inputobj[0].validform_subpost = ""
                }
                if (inputobj[0].validform_valid === "posting" && inputval == inputobj[0].validform_ckvalue) {
                    return "ajax"
                }
                inputobj[0].validform_valid = "posting";
                inputobj[0].validform_ckvalue = inputval;
                validform.util.showmsg.call(curform, curform.data("tipmsg").c || tipmsg.c, settings.tiptype, {
                    obj: inputobj,
                    type: 1,
                    sweep: settings.tipSweep
                },
                "bycheck");
                validform.util.abort.call(_this[0]);
                var ajaxsetup = $.extend(true, {},
                settings.ajaxurl || {});
                var localconfig = {
                    type: "POST",
                    cache: false,
                    url: ajaxurl,
                    data: "param=" + encodeURIComponent(inputval) + "&name=" + encodeURIComponent($(this).attr("name")),
                    success: function(data) {
                        if ($.trim(data.status) === "y") {
                            inputobj[0].validform_valid = "true";
                            data.info && inputobj.attr("sucmsg", data.info);
                            validform.util.showmsg.call(curform, inputobj.attr("sucmsg") || curform.data("tipmsg").r || tipmsg.r, settings.tiptype, {
                                obj: inputobj,
                                type: 2,
                                sweep: settings.tipSweep
                            },
                            "bycheck");
                            _this.removeClass("validform_error");
                            errorobj = null;
                            if (inputobj[0].validform_subpost == "postform") {
                                curform.trigger("submit")
                            }
                        } else {
                            inputobj[0].validform_valid = data.info;
                            validform.util.showmsg.call(curform, data.info, settings.tiptype, {
                                obj: inputobj,
                                type: 3,
                                sweep: settings.tipSweep
                            });
                            _this.addClass("validform_error")
                        }
                        _this[0].validform_ajax = null
                    },
                    error: function(data) {
                        if (data.status == "200") {
                            if (data.responseText == "y") {
                                ajaxsetup.success({
                                    "status": "y"
                                })
                            } else {
                                ajaxsetup.success({
                                    "status": "n",
                                    "info": data.responseText
                                })
                            }
                            return false
                        }
                        if (data.statusText !== "abort") {
                            var msg = "status: " + data.status + "; statusText: " + data.statusText;
                            validform.util.showmsg.call(curform, msg, settings.tiptype, {
                                obj: inputobj,
                                type: 3,
                                sweep: settings.tipSweep
                            });
                            _this.addClass("validform_error")
                        }
                        inputobj[0].validform_valid = data.statusText;
                        _this[0].validform_ajax = null;
                        return true
                    }
                };
                if (ajaxsetup.success) {
                    var temp_suc = ajaxsetup.success;
                    ajaxsetup.success = function(data) {
                        localconfig.success(data);
                        temp_suc(data, inputobj)
                    }
                }
                if (ajaxsetup.error) {
                    var temp_err = ajaxsetup.error;
                    ajaxsetup.error = function(data) {
                        localconfig.error(data) && temp_err(data, inputobj)
                    }
                }
                ajaxsetup = $.extend({},
                localconfig, ajaxsetup, {
                    dataType: "json"
                });
                _this[0].validform_ajax = $.ajax(ajaxsetup);
                return "ajax"
            } else {
                if (ajaxurl && validform.util.isEmpty.call($(this), inputval)) {
                    validform.util.abort.call(_this[0]);
                    _this[0].validform_valid = "true"
                }
            }
            if (!bool) {
                validform.util.showmsg.call(curform, flag.info, settings.tiptype, {
                    obj: $(this),
                    type: flag.type,
                    sweep: settings.tipSweep
                },
                "bycheck");
                _this.removeClass("validform_error")
            }
            errorobj = null;
            return true
        },
        submitForm: function(settings, flg, url, ajaxPost, sync) {
            var curform = this;
            if (curform[0].validform_status === "posting") {
                return false
            }
            if (settings.postonce && curform[0].validform_status === "posted") {
                return false
            }
            var beforeCheck = settings.beforeCheck && settings.beforeCheck(curform);
            if (beforeCheck === false) {
                return false
            }
            var flag = true,
            inflag;
            curform.find("[datatype]").each(function() {
                if (flg) {
                    return false
                }
                if (settings.ignoreHidden && $(this).is(":hidden") || $(this).data("dataIgnore") === "dataIgnore") {
                    return true
                }
                var inputval = validform.util.getValue.call(curform, $(this)),
                _this;
                errorobj = _this = $(this);
                inflag = validform.util.regcheck.call(curform, $(this).attr("datatype"), inputval, $(this));
                if (!inflag.passed) {
                    validform.util.showmsg.call(curform, inflag.info, settings.tiptype, {
                        obj: $(this),
                        type: inflag.type,
                        sweep: settings.tipSweep
                    });
                    _this.addClass("validform_error");
                    if (!settings.showAllError) {
                        _this.focus();
                        flag = false;
                        return false
                    }
                    flag && (flag = false);
                    return true
                }
                if ($(this).attr("ajaxurl") && !validform.util.isEmpty.call($(this), inputval)) {
                    if (this.validform_valid !== "true") {
                        var thisobj = $(this);
                        validform.util.showmsg.call(curform, curform.data("tipmsg").v || tipmsg.v, settings.tiptype, {
                            obj: thisobj,
                            type: 3,
                            sweep: settings.tipSweep
                        });
                        _this.addClass("validform_error");
                        thisobj.trigger("blur", ["postform"]);
                        if (!settings.showAllError) {
                            flag = false;
                            return false
                        }
                        flag && (flag = false);
                        return true
                    }
                } else {
                    if ($(this).attr("ajaxurl") && validform.util.isEmpty.call($(this), inputval)) {
                        validform.util.abort.call(this);
                        this.validform_valid = "true"
                    }
                }
                validform.util.showmsg.call(curform, inflag.info, settings.tiptype, {
                    obj: $(this),
                    type: inflag.type,
                    sweep: settings.tipSweep
                });
                _this.removeClass("validform_error");
                errorobj = null
            });
            if (settings.showAllError) {
                curform.find(".validform_error:first").focus()
            }
            if (flag) {
                var beforeSubmit = settings.beforeSubmit && settings.beforeSubmit(curform);
                if (beforeSubmit === false) {
                    return false
                }
                curform[0].validform_status = "posting";
                if (settings.ajaxPost || ajaxPost === "ajaxPost") {
                    var ajaxsetup = $.extend(true, {},
                    settings.ajaxpost || {});
                    ajaxsetup.url = url || ajaxsetup.url || settings.url || curform.attr("action");
                    if (sync) {
                        ajaxsetup.async = false
                    } else {
                        if (sync === false) {
                            ajaxsetup.async = true
                        }
                    }
                    if (ajaxsetup.success) {
                        var temp_suc = ajaxsetup.success;
                        ajaxsetup.success = function(data) {
                            settings.callback && settings.callback(data);
                            curform[0].validform_ajax = null;
                            if ($.trim(data.status) === "y") {
                                curform[0].validform_status = "posted"
                            } else {
                                curform[0].validform_status = "normal"
                            }
                            temp_suc(data, curform)
                        }
                    }
                    if (ajaxsetup.error) {
                        var temp_err = ajaxsetup.error;
                        ajaxsetup.error = function(data) {
                            settings.callback && settings.callback(data);
                            curform[0].validform_status = "normal";
                            curform[0].validform_ajax = null;
                            temp_err(data, curform)
                        }
                    }
                    var localconfig = {
                        type: "POST",
                        async: false,
                        data: curform.serializeArray(),
                        success: function(json) {
                            if ($.trim(json.status) == 1) {
                                if (json.tip == 1) {
                                    $(".validform_hints").html(json.data)
                                } else {
                                    if (json.tip == 2) {
                                        validform.util.showmsg.call(curform, json.data, settings.tiptype, {
                                            obj: curform,
                                            type: 3,
                                            sweep: settings.tipSweep
                                        },
                                        "byajax");
                                        curform[0].validform_status = "normal"
                                    } else {
                                        alert(json.data)
                                    }
                                }
                                if (json.url !== "") {
                                    setTimeout(window.location.href = json.url, json.time * 1000)
                                }
                            } else {
                                $(".validform_hints").html(json.data)
                            }
                            settings.callback && settings.callback(json);
                            curform[0].validform_ajax = null
                        },
                        error: function(json) {
                            var msg = "status: " + json.status + "; statusText: " + json.statusText;
                            validform.util.showmsg.call(curform, msg, settings.tiptype, {
                                obj: curform,
                                type: 3,
                                sweep: settings.tipSweep
                            },
                            "byajax");
                            settings.callback && settings.callback(json);
                            curform[0].validform_status = "normal";
                            curform[0].validform_ajax = null
                        }
                    };
                    ajaxsetup = $.extend({},
                    localconfig, ajaxsetup, {
                        dataType: "json"
                    });
                    curform[0].validform_ajax = $.ajax(ajaxsetup)
                } else {
                    if (!settings.postonce) {
                        curform[0].validform_status = "normal"
                    }
                    var url = url || settings.url;
                    if (url) {
                        curform.attr("action", url)
                    }
                    return settings.callback && settings.callback(curform)
                }
            }
            return false
        },
        resetForm: function() {
            var brothers = this;
            brothers.each(function() {
                this.reset && this.reset();
                this.validform_status = "normal"
            });
            brothers.find(".validform_right").text("");
            brothers.find(".password").children().removeClass("bgStrength");
            brothers.find(".validform_checktip").removeClass("validform_wrong validform_right validform_loading");
            brothers.find(".validform_error").removeClass("validform_error");
            brothers.find("[datatype]").removeData("cked").removeData("dataIgnore").each(function() {
                this.validform_lastval = null
            });
            brothers.eq(0).find("input:first").focus()
        },
        abort: function() {
            if (this.validform_ajax) {
                this.validform_ajax.abort()
            }
        }
    };
    $.Datatype = validform.util.dataType;
    validform.prototype = {
        dataType: validform.util.dataType,
        eq: function(n) {
            var obj = this;
            if (n >= obj.forms.length) {
                return null
            }
            if (! (n in obj.objects)) {
                obj.objects[n] = new validform($(obj.forms[n]).get(), {},
                true)
            }
            return obj.objects[n]
        },
        resetStatus: function() {
            var obj = this;
            $(obj.forms).each(function() {
                this.validform_status = "normal"
            });
            return this
        },
        setStatus: function(status) {
            var obj = this;
            $(obj.forms).each(function() {
                this.validform_status = status || "posting"
            });
            return this
        },
        getStatus: function() {
            var obj = this;
            var status = $(obj.forms)[0].validform_status;
            return status
        },
        ignore: function(selector) {
            var obj = this;
            var selector = selector || "[datatype]";
            $(obj.forms).find(selector).each(function() {
                $(this).data("dataIgnore", "dataIgnore").removeClass("validform_error")
            });
            return this
        },
        unignore: function(selector) {
            var obj = this;
            var selector = selector || "[datatype]";
            $(obj.forms).find(selector).each(function() {
                $(this).removeData("dataIgnore")
            });
            return this
        },
        addRule: function(rule) {
            var obj = this;
            var rule = rule || [];
            for (var index = 0; index < rule.length; index++) {
                var o = $(obj.forms).find(rule[index].ele);
                for (var attr in rule[index]) {
                    attr !== "ele" && o.attr(attr, rule[index][attr])
                }
            }
            $(obj.forms).each(function() {
                var $this = $(this);
                validform.util.enhance.call($this, this.settings.tiptype, this.settings.usePlugin, this.settings.tipSweep, "addRule")
            });
            return this
        },
        ajaxPost: function(flag, sync, url) {
            var obj = this;
            $(obj.forms).each(function() {
                if (this.settings.tiptype == 1 || this.settings.tiptype == 2 || this.settings.tiptype == 3) {
                    creatMsgbox()
                }
                validform.util.submitForm.call($(obj.forms[0]), this.settings, flag, url, "ajaxPost", sync)
            });
            return this
        },
        submitForm: function(flag, url) {
            var obj = this;
            $(obj.forms).each(function() {
                var subflag = validform.util.submitForm.call($(this), this.settings, flag, url);
                subflag === undef && (subflag = true);
                if (subflag === true) {
                    this.submit()
                }
            });
            return this
        },
        resetForm: function() {
            var obj = this;
            validform.util.resetForm.call($(obj.forms));
            return this
        },
        abort: function() {
            var obj = this;
            $(obj.forms).each(function() {
                validform.util.abort.call(this)
            });
            return this
        },
        check: function(bool, selector) {
            var selector = selector || "[datatype]",
            obj = this,
            curform = $(obj.forms),
            flag = true;
            curform.find(selector).each(function() {
                validform.util.check.call(this, curform, "", bool) || (flag = false)
            });
            return flag
        },
        config: function(setup) {
            var obj = this;
            setup = setup || {};
            $(obj.forms).each(function() {
                var $this = $(this);
                this.settings = $.extend(true, this.settings, setup);
                validform.util.enhance.call($this, this.settings.tiptype, this.settings.usePlugin, this.settings.tipSweep)
            });
            return this
        }
    };
    $.fn.validform = function(settings) {
        return new validform(this, settings)
    };


    function creatMsgbox() {
        if ($("#validform_msg").length !== 0) {
            return false
        }
        if (tipmsg.tit != "") {
            msgtit = '<div class="validform_title">' + tipmsg.tit + '<a class="validform_close" href="javascript:void(0);">&chi;</a></div>'
        } else {
            msgtit = ""
        }

        msgobjbg = $('<div id="validform_msgbg" style="height:'+document.body.scrollHeight+'px"></div>').appendTo("body");
        msgobj = $('<div id="validform_msg">' + msgtit + '<div class="validform_info"><div class="validform_icon_1"></div><div class="validform_content"></div></div><div id="validform_shade"></div></div>').appendTo("body");
        setInterval(function() {
            msgobj.fadeOut();
            msgobjbg.fadeOut()
        },
        3000);
        msgobj.find("a.validform_close").click(function() {
            msgobj.hide();
            msghidden = true;
            if (errorobj) {
                errorobj.focus().addClass("validform_error")
            }
            return false
        }).focus(function() {
            this.blur()
        });
    }


})(jQuery, window);
