(function ($) {
    var apiKey = $.getApiKey();
    var affiliateid = '';
    var subaffiliateid = '';
    var phonetype = '';
    var emailstatus = '';

    var servicetimeout = 10000;

    var emailcallstatus = false;
    var namecallstatus = false;
    var ipcallstatus = false;
    var phonecallstatus = false;
    var addresscallstatus = false;

    var services = $.getServices();
    var serviceURL = "http://www.xverify.com/services/"
    var x_forms = [];
    function formatErrors(errors, msg) {
        var formatedErrors = {};
        $.each(errors, function (i, error, msg) {
            formatedErrors[error[0]] = msg;
        });
        return formatedErrors;
    }
    function verifyParameters() {
        var allVars = getUrlVars();
        v1 = allVars['v1'];
        v2 = allVars['v2'];

        if (jQuery.trim(v1) != '' && v1 != undefined) {
            affiliateid = jQuery.trim(v1);

            if (jQuery.trim(v2) != '' && v2 != undefined)
                subaffiliateid = v2;
        }
        //		alert("AFF id" + affiliateid + "sub" + subaffiliateid);
    }
    function getUrlVars() {
        var vars = [], hash;
        var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
        for (var i = 0; i < hashes.length; i++) {
            hash = hashes[i].split('=');
            vars.push(hash[0]);
            vars[hash[0]] = hash[1];
        }
        return vars;
    }

    function checkServiceExist(serviceName) {
        var serviceStr = services;
        var serviceArray = serviceStr.split(",");

        var return_value = false;
        for (var i = 0; i < serviceArray.length; i++) {
            if (serviceName == serviceArray[i]) {
                return_value = true;
                break;
            }
        }
        return return_value;

    }

    $.xVerify = {
        serviceURI: serviceURL,
        email: function (email, callback, options) {
            //var options = options || {};			
            var url = serviceURL + "emails/verify/?type=json&apikey=" + apiKey + "&v1=" + affiliateid + "&v2=" + subaffiliateid + "&emailstatus=" + emailstatus + "&callback=?";

            emailcallstatus = true;
            setTimeout(function () { emailtimeout(email, callback); }, servicetimeout);

            $.getJSON(
					  url, { "email": email },
					  function (json) {
					      var service_email = json["email"];
					      if (service_email.error) {
					          service_email.errors_json = formatErrors(service_email.error, service_email.message);
					      }
					      emailcallstatus = false;
					      callback(service_email);
					  });
        },
        ipVerify: function (ip, callback, options) {
            //var options = options || {};			
            var url = serviceURL + "ipdata/verify/?type=json&apikey=" + apiKey + "&v1=" + affiliateid + "&v2=" + subaffiliateid + "&callback=?";

            ipcallstatus = true;
            setTimeout(function () { iptimeout(ip, callback); }, servicetimeout);

            $.getJSON(
					  url, { "ip": ip },
					  function (json) {
					      var service_ip = json["ipdata"];
					      if (service_ip.error) {
					          service_ip.errors_json = formatErrors(service_ip.error, service_ip.message);
					      }
					      ipcallstatus = false;
					      callback(service_ip);
					  });
        },
        phone: function (phone, callback, options) {
            var url = serviceURL + "phone/verify/?type=json&apikey=" + apiKey + "&v1=" + affiliateid + "&v2=" + subaffiliateid + "&phonetype=" + phonetype + "&callback=?";

            //now - strip out any (, ), space, or -... then submit to verify!
            phone = phone.replace("(", "");
            phone = phone.replace(")", "");
            phone = phone.replace("-", "");
            phone = phone.replace(" ", "");
            phonecallstatus = true;
            setTimeout(function () { phonetimeout(phone, callback); }, servicetimeout);

            $.getJSON(url, { "phone": phone }, function (json) {
                var service_phone = json["phone"];
                if (service_phone.error) {
                    service_phone.errors_json = formatErrors(service_phone.error, service_phone.message);
                }
                phonecallstatus = false;
                callback(service_phone);
            });
        },

        address: function (address, callback, options) {
            var options = options || {};
            var url = serviceURL + "address/verify/?type=json&apikey=" + apiKey + "&v1=" + affiliateid + "&v2=" + subaffiliateid + "&callback=?";

            addresscallstatus = true;
            setTimeout(function () { addresstimeout(address, callback); }, servicetimeout);
            // TODO: Clean this up. 
            var formated_address = { "street": address.street.val(), "zip": address.zip.val() };
            if (address.city) formated_address["city"] = address.city.val();
            if (address.state) formated_address["state"] = address.state.val();

            $.getJSON(url, formated_address, function (json) {
                var res_address = json["address"];
                if (res_address.error) {
                    res_address.errors_json = formatErrors(res_address.error);
                }

                addresscallstatus = false;
                callback(res_address);
            });
        },

        name: function (names, callback, options) {
            var options = options || {};
            var url = serviceURL + "name/verify/?type=json&apikey=" + apiKey + "&v1=" + affiliateid + "&v2=" + subaffiliateid + "&callback=?";

            namecallstatus = true;
            setTimeout(function () { nametimeout(names, callback); }, servicetimeout);

            // TODO: Clean this up. 
            var formated_name = { "firstname": names.firstname.val(), "lastname": names.lastname.val() };
            $.getJSON(url, formated_name, function (json) {
                var res_name = json["name"];
                if (res_name.error) {
                    res_name.errors_json = formatErrors(res_name.error);
                }
                namecallstatus = false;
                callback(res_name);
            });
        },

        addField: function (values, callback, options) {
            var url = serviceURL + "scoring/register?callback=?";
            $.getJSON(
					  url, { "value": '' },
					  function (json) {
					      var time = json["time"];
					      callback(time);
					  });
        }
    };

    function emailtimeout(email, callback) {

        if (emailcallstatus == true) {
            var res_name = new Object();
            res_name.error = false;
            res_name.address = email;
            callback(res_name);
        }
    }

    function nametimeout(names, callback) {

        if (namecallstatus == true) {
            var res_name = new Object();
            res_name.error = false;
            res_name.last = names.lastname.val();
            res_name.first = names.firstname.val();
            callback(res_name);
        }
    }


    function iptimeout(ip, callback) {

        if (ipcallstatus == true) {
            var res_name = new Object();
            res_name.error = false;
            callback(res_name);
        }
    }


    function phonetimeout(phone, callback) {

        if (phonecallstatus == true) {
            var res_name = new Object();
            res_name.error = false;
            callback(res_name);
        }
    }


    function addresstimeout(address, callback) {

        if (addresscallstatus == true) {
            var res_name = new Object();
            res_name.error = false;
            /*
            var formated_address = {"street" : address.street.val(), "zip" : address.zip.val()};
            if(address.city) formated_address["city"] = address.city.val();
            if(address.state) formated_address["state"] = address.state.val();
            */

            res_name.zip = address.zip.val();
            res_name.address1 = address.street.val();

            if (address.city) res_name.city = address.city.val();
            if (address.state) res_name.state = address.state.val();

            callback(res_name);
        }
    }
    function addxVerifyTip(field) {
        var loading_div_id = field.id + "_loadingmsg";
        var loading_div = "<div class='xverify_loading_msg' id='" + loading_div_id + "'><table class='xverify_msg'><tr valign='center'><td>Verifying</td><td><img src='http://www.xverify.com/images/loader.gif'/></td></tr></table></div>";
        $("body").prepend(loading_div);

    }

    function checkEmailSyntax(str) {
        str = jQuery.trim(str);
        var at = "@"
        var dot = "."
        var lat = str.indexOf(at)
        var lstr = str.length
        var ldot = str.indexOf(dot)
        if (str.indexOf(at) == -1) {
            return false
        }

        if (str.indexOf(at) == -1 || str.indexOf(at) == 0 || str.indexOf(at) == lstr) {
            return false
        }

        if (str.indexOf(dot) == -1 || str.indexOf(dot) == 0 || str.indexOf(dot) == lstr) {
            return false
        }

        if (str.indexOf(at, (lat + 1)) != -1) {
            return false
        }

        if (str.substring(lat - 1, lat) == dot || str.substring(lat + 1, lat + 2) == dot) {
            return false
        }

        if (str.indexOf(dot, (lat + 2)) == -1) {
            return false
        }

        if (str.indexOf(" ") != -1) {
            return false
        }

        return true
    }

    function removexVerifyTip(field) {
        var loading_div_id = field.id + "_loadingmsg";
        $("#" + loading_div_id).remove();

    }

    function initxVerifyTip(field, options) {
        if (options == null) {
            options = { message_position: "center right" };
        }
        var x_tip = $(field).tooltip({
            // place tooltip on the right edge 
            position: options.message_position,
            // a little tweaking of the position 
            offset: [-2, 10],
            // use a simple show/hide effect 
            effect: "fade",
            // custom opacity setting 
            opacity: 0.7,
            // use this single tooltip element 
            tip: '#' + field.id + "_loadingmsg",
            events: { input: "change, focus" },
            effect: "fade",
            api: true
        });
        return x_tip;
    }

    $.fn.xEmail = function (form, options) {
        if (checkServiceExist('email')) {
            var x_form = form;
            var x_field_state = "unverified";
            var ex_tip = null;


            // TODO: Find out how to extend this
            var new_methods = {
                getxVerifyState: function () { return x_field_state },
                getxVerifyTip: function () { return x_tip },
                setxVerifyTip: function (tip) { x_tip = tip }
            }

            this.each(function () {
                var self = this, $self = $(this);
                addxVerifyTip(self);
                ex_tip = initxVerifyTip(self, { message_position: x_form.getMessagePos() });
                ex_tip.onBeforeHide(function (event) {
                    if (x_field_state != "valid") {
                        event.preventDefault();
                    }
                });
                $(self).blur(function () {
                    if (x_field_state == "processing" || x_field_state == "invalid") {
                        ex_tip.getTip().show();
                    }
                });
                $(self).change(function (event) {
                    var form = $(self).parents('form:first')[0];
                    var sub = null;
                    if (x_form.disableSub()) {
                        var sub = $(form).find("input[type='submit']")[0];
                    }
                    if (sub == null) {
                        var sub = $(form).find("input[type='image']")[0];
                    }
                    var ltip = ex_tip.getTip();
                    if (checkEmailSyntax(self.value)) {
                        ltip.removeClass("xverify_error_msg");
                        ltip.addClass("xverify_loading_msg");
                        ltip.html("<table class='xverify_message'><tr valign='center'><td>Verifying</td><td><img src='http://www.xverify.com/images/loader.gif'/></td></tr></table>");
                    }
                    else if (jQuery.trim(self.value) == '') {
                        ltip.removeClass("xverify_loading_msg");
                        ltip.addClass("xverify_error_msg");
                        ltip.html("<p>Please enter email address</p>");
                        return;
                    }
                    else {
                        ltip.removeClass("xverify_loading_msg");
                        ltip.addClass("xverify_error_msg");
                        ltip.html("<p>Invalid Email Syntax</p>");
                        return;
                    }


                    if (sub) sub.disabled = true;
                    x_form.setFormState("processing");
                    x_field_state = "processing";
                    sendrequest = true;
                    gdomains = getdomainfromemail(jQuery.trim(self.value));
                    //ex_tip.show();
                    if (gdomains == 'yahoo' || gdomains == 'rocketmail' || gdomains == 'ymail') {
                        current_option = getYahooOption();
                        sendrequest = false;

                        if (current_option == 1) {
                            sendrequest = true;
                        }
                        else if (current_option == 2) {
                            sendrequest = true;
                        }
                        else if (current_option == 3) {
                            sendrequest = true;
                        }
                        else if (current_option == 4) {
                            sendrequest = true;
                        }
                    }

                    if (sendrequest == true) {
                        $.xVerify.email(self.value, function (email) {
                            if (email.error) {
                                //var field = email.errors[0][0];
                                var msg = x_form.getErrMsgs().email || email.message;
                                var etip = ex_tip.getTip();
                                etip.html("<p>" + msg + "</p>");
                                etip.addClass("xverify_error_msg");
                                etip.removeClass("xverify_loading_msg");
                                x_form.setFormState("invalid");
                                x_field_state = "invalid";
                                action = x_form.attr("action");
                            } else {
                                x_form.setFormState("valid");
                                x_field_state = "valid";
                                if (sub) sub.disabled = false;
                                $(self).val(email.address);
                                ex_tip.hide();
                            }
                        });
                    }
                });
            });
            return this;
        }
    }

    function checkPhoneSyntax(str) {
        //changed from 10 to 14 based on phone # with () and -
        if (str.length < 10) {
            return false
        }

        rePhoneNumber = new RegExp(/^[1-9]\d{2}\d{3}\d{4}$/);
        //rePhoneNumber = new RegExp(/^(?:\([2-9]\d{2}\)\ ?|[2-9]\d{2}(?:\-?|\ ?))[2-9]\d{2}[- ]?\d{4}$/);

        if (!rePhoneNumber.test(str)) {
            return false;
        }
        return true;
    }
    // Start xform
    $.fn.xPhone = function (form, phone, selectphonetype) {
        if (checkServiceExist('phone')) {
            var x_form = form;
            var x_field_state = "unverified";
            var x_tip = null;
            var self = this, $self = $(this);

            var new_methods = {
                getxVerifyState: function () { return x_field_state },
                getxVerifyTip: function () { return x_tip },
                setxVerifyTip: function (tip) { x_tip = tip }
            }

            this.each(function () {
                var self = this, $self = $(this);
                addxVerifyTip(self);
                x_tip = initxVerifyTip(self, { message_position: x_form.getMessagePos() })
                x_tip.onBeforeHide(function (event) {
                    if (x_field_state != "valid") {
                        event.preventDefault();
                    }
                })

                $(self).blur(function () {
                    if (x_field_state == "processing" || x_field_state == "invalid") {
                        x_tip.show();
                    }
                });

                function handleVerify(field) {
                    var num = null;
                    num = $("#PhoneNumber1").val() + $("#PhoneNumber2").val() + $("#PhoneNumber3").val();
                    var v1 = $("#PhoneNumber1").val();
                    var v2 = $("#PhoneNumber2").val();
                    var v3 = $("#PhoneNumber3").val();
                    
                    var ltip = x_tip.getTip();

                    if ((v1.length != 3 || v2.length != 3 || v3.length != 4) && self.id!="PhoneNumber3") {
                        ltip.hide();
                        return;
                    }
                    var form = $(field).parents('form:first')[0];
                    var sub = null;
                    if (x_form.disableSub()) {
                        var sub = $(form).find("input[type='submit']")[0];
                    }
                    if (sub == null) {
                        var sub = $(form).find("input[type='image']")[0];
                    }


                    //alert("'" + num + "'");
                    phonetype = selectphonetype;

                    if (checkPhoneSyntax(num)) {
                        ltip.removeClass("xverify_error_msg");
                        ltip.addClass("xverify_loading_msg");
                        ltip.html("<table class='xverify_message'><tr valign='center'><td>Verifying</td><td><img src='http://www.xverify.com/images/loader.gif'/></td></tr></table>");
                    }
                    else if (jQuery.trim(num) == '') {
                        ltip.removeClass("xverify_loading_msg");
                        ltip.addClass("xverify_error_msg");
                        ltip.html("<p>Please enter phone number</p>");
                        return;
                    }
                    else {
                        if (sub) sub.disabled = true;
                        ltip.removeClass("xverify_loading_msg");
                        ltip.addClass("xverify_error_msg");
                        ltip.html("<p>Invalid Phone: " + num + "</p>");
                        return;
                    }

                    if (num) {
                        var ltip = x_tip.getTip();
                        ltip.removeClass("xverify_error_msg");
                        ltip.addClass("xverify_loading_msg");
                        ltip.html("<table class='xverify_msg'><tr valign='center'><td>Verifying</td><td><img src='http://www.xverify.com/images/loader.gif'/></td></tr></table>");
                        //x_tip.show();
                        if (sub) sub.disabled = true;
                        x_form.setFormState("processing");
                        x_field_state = "processing";
                        $.xVerify.phone(num, function (response_phone) {
                            //x_tip.show();
                            if (response_phone.error) {

                                var msg = x_form.getErrMsgs().phone || response_phone.message;
                                var etip = x_tip.getTip();
                                etip.html("<p>" + msg + "</p>");
                                etip.addClass("xverify_error_msg");
                                etip.removeClass("xverify_loading_msg");
                                x_form.setFormState("invalid");
                                x_field_state = "invalid";

                            } else {
                                x_form.setFormState("valid");
                                x_field_state = "valid";
                                if (sub) sub.disabled = false;
                                x_tip.hide();
                            }
                        });
                    }
                }

                $(self).change(function () {
                    handleVerify(self);
                });
            });
            return this;
        }
    }

    $.fn.xAddField = function (form, options) {
        var x_form = form;
        $.xVerify.addField('', function (response_name) {
            field = '<input type="hidden" name="start_time" value=' + response_name + ' />';
            //					alert(field);
            x_form.append(field);
        });

    }

    $.fn.xIpVerify = function (form, ip) {
        if (checkServiceExist('ip_verify')) {
            var x_form = form;
            var x_field_state = "unverified";
            var x_tip = null;
            var self = this, $self = $(this);

            var new_methods = {
                getxVerifyState: function () { return x_field_state },
                getxVerifyTip: function () { return x_tip },
                setxVerifyTip: function (tip) { x_tip = tip }
            }

            this.each(function () {
                var self = this, $self = $(this);
                addxVerifyTip(self);
                x_tip = initxVerifyTip(self, { message_position: x_form.getMessagePos() })
                x_tip.onBeforeHide(function (event) {
                    if (x_field_state != "valid") {
                        event.preventDefault();
                    }
                })

                $(self).blur(function () {
                    if (x_field_state == "processing" || x_field_state == "invalid") {
                        x_tip.show();
                    }
                });

                function handleVerify(field) {
                    var form = $(field).parents('form:first')[0];
                    var sub = null;
                    if (x_form.disableSub()) {
                        var sub = $(form).find("input[type='submit']")[0];
                    }
                    if (sub == null) {
                        var sub = $(form).find("input[type='image']")[0];
                    }

                    var num = null;
                    var ltip = x_tip.getTip();
                    num = self.value;

                    ipvalue = checkIpVerifySyntax(self.value);

                    if (ipvalue == true) {
                        ltip.removeClass("xverify_error_msg");
                        ltip.addClass("xverify_loading_msg");
                        ltip.html("<table class='xverify_message'><tr valign='center'><td>Verifying</td><td><img src='http://www.xverify.com/images/loader.gif'/></td></tr></table>");
                    }
                    else {
                        if (sub) sub.disabled = true;
                        ltip.removeClass("xverify_loading_msg");
                        ltip.addClass("xverify_error_msg");
                        ltip.html("<p>" + ipvalue + "</p>");
                        return;
                    }

                    if (num) {
                        var ltip = x_tip.getTip();
                        ltip.removeClass("xverify_error_msg");
                        ltip.addClass("xverify_loading_msg");
                        ltip.html("<table class='xverify_msg'><tr valign='center'><td>Verifying</td><td><img src='http://www.xverify.com/images/loader.gif'/></td></tr></table>");
                        //x_tip.show();
                        if (sub) sub.disabled = true;
                        x_form.setFormState("processing");
                        x_field_state = "processing";
                        $.xVerify.ipVerify(num, function (response_ip) {
                            //x_tip.show();
                            if (response_ip.error) {

                                var msg = x_form.getErrMsgs().ip || response_ip.message;
                                var etip = x_tip.getTip();
                                etip.html("<p>" + msg + "</p>");
                                etip.addClass("xverify_error_msg");
                                etip.removeClass("xverify_loading_msg");
                                x_form.setFormState("invalid");
                                x_field_state = "invalid";

                            } else {
                                x_form.setFormState("valid");
                                x_field_state = "valid";
                                if (sub) sub.disabled = false;
                                x_tip.hide();
                            }
                        });
                    }
                }

                $(self).change(function () {
                    handleVerify(self);
                });
            });
            return this;
        }



    }

    function checkAddressField(zip, street) {
        zip = jQuery.trim(zip);
        street = jQuery.trim(street);
        if (zip == '' || street == '') {
            return false
        }
        return true
    }

    function checkNameField(first, last) {
        first = jQuery.trim(first);
        last = jQuery.trim(last);
        if (first == '' || last == '') {
            return false
        }
        return true
    }

    function checkIpVerifySyntax(IPvalue) {
        errorString = "";
        theName = "IPaddress";
        var ipPattern = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
        var ipArray = IPvalue.match(ipPattern);
        if (IPvalue == "0.0.0.0")
            errorString = errorString + theName + ': ' + IPvalue + ' is a special IP address and cannot be used here.';
        else if (IPvalue == "255.255.255.255")
            errorString = errorString + theName + ': ' + IPvalue + ' is a special IP address and cannot be used here.';
        if (ipArray == null)
            errorString = errorString + theName + ': ' + IPvalue + ' is not a valid IP address.';
        else {
            for (i = 0; i < 4; i++) {
                thisSegment = ipArray[i];
                if (thisSegment > 255) {
                    errorString = errorString + theName + ': ' + IPvalue + ' is not a valid IP address.';
                    i = 4;
                }
                if ((i == 0) && (thisSegment > 255)) {
                    errorString = errorString + theName + ': ' + IPvalue + ' is a special IP address and cannot be used here.';
                    i = 4;
                }
            }
        }
        extensionLength = 3;
        if (errorString == "")
            return true;
        else
            return errorString;
    }

    $.fn.xAddress = function (form, address) {
        if (checkServiceExist('address')) {
            var x_form = form;
            var x_addr_state = "unverified";
            var addr_x_tip = null;

            function getxVerifyState() { return x_field_state };
            function getxVerifyTip() { return addr_x_tip };
            function setxVerifyTip(tip) {
                addr_x_tip = tip
            };

            var ba = this;
            this.each(function () {
                var handleAddressChange = function (field) {
                    var sub = null;

                    if (x_form.disableSub()) {
                        var sub = $(form).find("input[type='submit']")[0];
                    }
                    if (sub == null) {
                        var sub = $(form).find("input[type='image']")[0];
                    }

                    if (sub) sub.disabled = true;
                    if (address.zip.val() && address.street.val()) {
                        if (!getxVerifyTip()) {
                            addr_x_tip = initxVerifyTip(address.street, { message_position: x_form.getMessagePos() })
                            addr_x_tip.onBeforeHide(function (event) {
                                if (x_addr_state != "valid") {
                                    event.preventDefault();
                                }
                            });


                        }

                        if (checkAddressField(address.zip.val(), address.street.val())) {
                            var ttip = addr_x_tip.getTip();
                            ttip.removeClass("xverify_error_msg");
                            ttip.addClass("xverify_loading_msg");
                            ttip.html("<table class='xverify_msg'><tr valign='center'><td>Verifying</td><td><img src='http://www.xverify.com/images/loader.gif'/></td></tr></table>");
                            if (!addr_x_tip.isShown()) {
                                addr_x_tip.show();
                            }
                        }
                        else {
                            var atip = getxVerifyTip().getTip();
                            atip.removeClass("xverify_loading_msg");
                            atip.addClass("xverify_error_msg");
                            atip.html("<p>Please enter required address field</p>");
                            if (!addr_x_tip.isShown()) {
                                addr_x_tip.show();
                            }
                            return;
                        }




                        $.xVerify.address(address, function (response_address) {
                            try {
                                var sub = $(form).find("input[type='submit']")[0];
                                //getxVerifyTip().show();
                                if (response_address.error) {

                                    var msg = x_form.getErrMsgs().address || response_address.message;

                                    var etip = addr_x_tip.getTip();
                                    etip.removeClass("xverify_loading_msg");
                                    etip.addClass("xverify_error_msg");
                                    etip.html("<p>" + msg + "</p>");
                                    x_form.setFormState("invalid");
                                    x_field_state = "invalid";

                                } else {

                                    address.zip.val(response_address.zip);
                                    address.street.val(response_address.address1);

                                    if (address.unit != "null") {
                                        if (response_address.unit) {
                                            $(address.unit).val(response_address.unit);
                                        }
                                    }

                                    if (address.city) $(address.city).val(response_address.city);
                                    if (address.state) $(address.state).val(response_address.state);


                                    var etip = addr_x_tip.getTip();
                                    x_form.setFormState("valid");
                                    x_field_state = "valid";
                                    if (sub) sub.disabled = false;
                                    etip.hide();
                                }


                            } catch (e) {
                                getxVerifyTip().hide();
                            }
                        });
                    }
                }

                if (address.street && address.zip) {
                    addxVerifyTip(address.street);
                    $(address.zip).change(function () {
                        var x_addr_state = "processing";
                        //handleAddressChange(address.street);
                        $(address.street).trigger('change');
                    });
                    $(address.street).blur(function () {
                        if (x_addr_state == "invalid") {
                            getxVerifyTip().getTip().show();
                        }
                    });
                    $(address.street).change(function () {
                        var x_addr_state = "processing";
                        handleAddressChange(address.street);
                    });
                    if (address.city) {
                        $(address.city).change(function () {
                            var x_addr_state = "processing";
                            handleAddressChange(address.street);
                        });
                    }
                    if (address.state) {
                        $(address.state).change(function () {
                            var x_addr_state = "processing";
                            handleAddressChange(address.street);
                        });
                    }
                }
            });
        }
    }
    $.fn.xName = function (form, names) {
        if (checkServiceExist('name')) {
            var x_form = form;
            var x_addr_state = "unverified";
            var addr_x_tip = null;

            function getxVerifyState() { return x_field_state };
            function getxVerifyTip() { return addr_x_tip };
            function setxVerifyTip(tip) {
                addr_x_tip = tip
            };

            var ba = this;
            this.each(function () {
                var handleNameChange = function (field) {
                    var sub = null;

                    if (x_form.disableSub()) {
                        var sub = $(form).find("input[type='submit']")[0];
                    }
                    if (sub == null) {
                        var sub = $(form).find("input[type='image']")[0];
                    }

                    if (sub) sub.disabled = true;
                    if (names.lastname.val() && names.firstname.val()) {
                        if (!getxVerifyTip()) {
                            addr_x_tip = initxVerifyTip(names.firstname, { message_position: x_form.getMessagePos() })
                            addr_x_tip.onBeforeHide(function (event) {
                                if (x_addr_state != "valid") {
                                    event.preventDefault();
                                }
                            });


                        }

                        if (checkNameField(names.firstname.val(), names.lastname.val())) {
                            var ttip = addr_x_tip.getTip();
                            ttip.removeClass("xverify_error_msg");
                            ttip.addClass("xverify_loading_msg");
                            ttip.html("<table class='xverify_msg'><tr valign='center'><td>Verifying</td><td><img src='http://www.xverify.com/images/loader.gif'/></td></tr></table>");
                            if (!addr_x_tip.isShown()) {
                                addr_x_tip.show();
                            }
                        }
                        else {
                            var atip = getxVerifyTip().getTip();
                            atip.removeClass("xverify_loading_msg");
                            atip.addClass("xverify_error_msg");
                            atip.html("<p>Please enter required name field</p>");
                            if (!addr_x_tip.isShown()) {
                                addr_x_tip.show();
                            }
                            return;
                        }




                        $.xVerify.name(names, function (response_name) {
                            try {
                                var sub = $(form).find("input[type='submit']")[0];
                                //getxVerifyTip().show();
                                if (response_name.error) {

                                    var msg = x_form.getErrMsgs().address || response_name.message;

                                    var etip = addr_x_tip.getTip();
                                    etip.removeClass("xverify_loading_msg");
                                    etip.addClass("xverify_error_msg");
                                    etip.html("<p>" + msg + "</p>");
                                    x_form.setFormState("invalid");
                                    x_field_state = "invalid";

                                } else {
                                    names.lastname.val(response_name.last);
                                    names.firstname.val(response_name.first);
                                    var etip = addr_x_tip.getTip();
                                    x_form.setFormState("valid");
                                    x_field_state = "valid";
                                    if (sub) sub.disabled = false;
                                    etip.hide();
                                }


                            } catch (e) {
                                getxVerifyTip().hide();
                            }
                        });
                    }
                }

                if (names.firstname && names.firstname) {
                    addxVerifyTip(names.firstname);
                    $(names.firstname).blur(function () {
                        if (x_addr_state == "invalid") {
                            getxVerifyTip().getTip().show();
                        }
                    });
                    $(names.firstname).change(function () {
                        var x_addr_state = "processing";
                        handleNameChange(names.firstname);
                    });
                    if (names.lastname) {
                        $(names.lastname).change(function () {
                            var x_addr_state = "processing";
                            handleNameChange(names.firstname);
                        });
                    }
                }
            });
        }
    }
    $.fn.xVerifyForm = function (fields, callback, options) {
        var settings = options || { disableSub: true };
        settings.message_position = $.getMessagePos();
        verifyParameters();
        var x_form = this;
        var xverify_msg_position = settings.message_position;
        var x_fields = [];
        var x_form_state = "unverified";
        var err_msgs = settings.error_messages || {};
        var newMethods = {
            getxVerifyFields: function () { return x_fields },
            setFormState: function (state) { bite_form_state = state },
            disableSub: function () { return settings.disableSub },
            getFormState: function () { return x_form_state },
            getErrMsgs: function () { return err_msgs },
            getMessagePos: function () {
                return xverify_msg_position;
            },
            isPending: function () { return (bite_form_state == "pending") }
        }
        $.extend(this, newMethods);

        this.each(function () {




            $("input", this).filter(function () {
                var fid = this.getAttribute('className') ? this.getAttribute('className') : this.getAttribute('class');
                if (fid == null) { var fid = this.id ? this.id : this.name; }
                //console.log(fid)
                fid = fid.toLowerCase();

                if (fid.indexOf("v1") >= 0 && affiliateid == '') {
                    affiliateid = this.value;
                }
                if (fid.indexOf("v2") >= 0 && subaffiliateid == '') {
                    subaffiliateid = this.value;
                }


                if (fid.indexOf("xverify_email") >= 0) {
                    $(this).xEmail(x_form);
                    x_fields.push(this);
                    return true;
                } else if (fid.indexOf("xverify_ipverify") >= 0) {
                    $(this).xIpVerify(x_form);
                    x_fields.push(this);
                    return true;
                }
                else if (fid.indexOf("xverify_phone") >= 0) {
                    var phone = { number: $(this) }
                    $(this).xPhone(x_form, phone, '');
                    x_fields.push(this);
                    return true;
                } else if (fid.indexOf("xverify_cell") >= 0) {
                    var phone = { number: $(this) }
                    $(this).xPhone(x_form, phone, 'cell');
                    x_fields.push(this);
                    return true;
                } else if (fid.indexOf("xverify_landline") >= 0) {
                    var phone = { number: $(this) }
                    $(this).xPhone(x_form, phone, 'landline');
                    x_fields.push(this);
                    return true;
                } else if (fid.indexOf("xverify_voip") >= 0) {
                    var phone = { number: $(this) }
                    $(this).xPhone(x_form, phone, 'voip');
                    x_fields.push(this);
                    return true;
                } else {
                    return false;
                }
            });

            var address = {};
            var field_names = {
                street: ["xverify_street"],
                unit: ["xverify_apartment"],
                city: ["xverify_city"],
                state: ["xverify_state", "xverify_region"],
                zip: ["xverify_zip", "xverify_postal"]
            };

            $("input", this).filter(function () {
                var fid = this.getAttribute('className') ? this.getAttribute('className') : this.getAttribute('class');
                if (fid == null) { var fid = this.id ? this.id : this.name; }
                var field = this;
                $.each(field_names, function (attr, names) {
                    $(names).each(function (i, val) {
                        //console.log(val);
                        if (fid && (fid.toLowerCase().indexOf(val) >= 0)) {
                            if ((fid.toLowerCase().indexOf("client") >= 0) || (fid.toLowerCase().indexOf("view") >= 0)) {
                                // do nothing
                            } else {
                                address[attr] = $(field);
                            }
                            return true;
                        }
                    })
                })
                return true;
            });

            $("select", this).filter(function () {
                var fid = this.getAttribute('className') ? this.getAttribute('className') : this.getAttribute('class');
                if (fid == null) { var fid = this.id ? this.id : this.name; }

                //var fid = this.id ? this.id : this.name;
                var field = this;
                $.each(field_names, function (attr, names) {
                    $(names).each(function (i, val) {
                        if (fid && (fid.toLowerCase().indexOf(val) >= 0)) {
                            if ((fid.toLowerCase().indexOf("client") >= 0) || (fid.toLowerCase().indexOf("view") >= 0)) {
                                // do nothing
                            } else {
                                address[attr] = $(field);
                            }
                            return true;
                        }
                    })
                })
                return true;
            });

            if (!address["street"]) {
                $("input", this).filter(function () {
                    var fid = this.getAttribute('className') ? this.getAttribute('className') : this.getAttribute('class');
                    if (fid == null) { var fid = this.id ? this.id : this.name; }

                    var field = this;
                    if (fid && (fid.toLowerCase() == "addr")) {
                        address["street"] = $(field);
                    }
                    return true;
                });
            }
            if (address.street && address.zip) {
                $(address.zip).xAddress(x_form, address);
                x_fields.push(address.zip);
            }

            var username = {};
            var field_names = {
                firstname: ["xverify_firstname"],
                lastname: ["xverify_lastname"]
            };

            $("input", this).filter(function () {
                var fid = this.getAttribute('className') ? this.getAttribute('className') : this.getAttribute('class');
                if (fid == null) { var fid = this.id ? this.id : this.name; }

                var field = this;
                $.each(field_names, function (attr, names) {
                    $(names).each(function (i, val) {
                        if (fid && (fid.toLowerCase().indexOf(val) >= 0)) {
                            if ((fid.toLowerCase().indexOf("client") >= 0) || (fid.toLowerCase().indexOf("view") >= 0)) {
                                // do nothing
                            } else {
                                username[attr] = $(field);
                            }
                            return true;
                        }
                    })
                })
                return true;
            });

            if (username.firstname && username.lastname) {
                $(username.firstname).xName(x_form, username);
                x_fields.push(username.firstname);
            }


        });


        $(this).xAddField(x_form);

        x_forms.push(x_form);
        return this;
    };

})(jQuery);


