$(document).ready((function ($jq) {
    function FieldController() {
        this.events = {
            blur: "blur",
            keypress: "keypress",
            paste: "paste"
        };

        this.selectors = {
            textInput: ".contact-form :input[type='text']",
            textArea: ".contact-form textarea",
            emailInput: ".contact-form :input[type='email']",
            phoneInput: ".contact-form :input[type='tel']",
            dateInput: ".contact-form .date-field"
        };

        this.filters = {
            number: RegExp("[0-9]")
        };
    };

    FieldController.prototype = {
        bind: function () {
            var context = this;

            // setup blur for all inputs - check field has value.
            for (let selector in this.selectors) {
                $jq(this.selectors[selector]).unbind(this.events.blur).on(this.events.blur, function (event) {
                    context.evaluateNotEmpty(event, this);
                });
            }

            //setup phone formatting on keypress - format and add dashes.
            $jq(this.selectors.phoneInput).unbind(this.events.keypress).on(this.events.keypress, function (event) {
                context.formatPhoneInput(event, this);
            });

            //setup date formatting on keypress - format and add slashes.
            $(this.selectors.dateInput).unbind(this.events.keypress).on(this.events.keypress, function (event) {
                context.formatDateInput(event, this);
            });

            //setup phone formatting on paste - format and add dashes.
            $jq(this.selectors.phoneInput).unbind(this.events.paste).on(this.events.paste, function (event) {
                event.preventDefault();
                context.pastePhoneInput(event, this);
            });
        },

        evaluateNotEmpty: function (event, input) {
            if (typeof input !== "undefined") {
                if (input.value.length > 0) {
                    input.classList.add("not-empty");
                }
                else {
                    input.classList.remove("not-empty");
                }
            }
            else {
                event.preventDefault();
                return false;
            }
            return input;
        },

        formatPhoneInput: function (event, input) {
            var context = this;
            if (typeof input !== "undefined") {
                var key = String.fromCharCode(event.keyCode);
                if (this.filters.number.test(key) && input.value.length < 12) {
                    var inputValue = input.value;
                    inputValue = inputValue.replace(/-/g, '');
                    inputValue = context.formatPhoneNumber(inputValue);
                    input.value = inputValue;
                }
                else {
                    event.preventDefault();
                    return false;
                }
            }
            return input;
        },
        pastePhoneInput: function (event, input) {
            var context = this;
            if (input !== "undefined") {
                inputData = "";
                if (window.clipboardData && window.clipboardData.getData) {
                    inputData = window.clipboardData.getData('Text');
                }
                else if ((event.originalEvent || event).clipboardData && (event.originalEvent || event).clipboardData.getData) {
                    inputData = (event.originalEvent || event).clipboardData.getData('text/plain');
                }

                inputData = inputData.replace(/\D/g, '');
                if (inputData.length > 10)
                    inputData = inputData.slice(0, 10);

                inputData = context.formatPhoneNumber(inputData);
                input.value = inputData;
                return input;
            }
        },
        formatDateInput: function (event, input) {
            var context = this;
            if (typeof input !== "undefined") {
                var key = String.fromCharCode(event.keyCode);
                if (this.filters.number.test(key) && input.value.length < 10) {
                    var inputValue = input.value;
                    inputValue = inputValue.replace(/\D/g, '');
                    inputValue = context.formatDate(inputValue);
                    input.value = inputValue;
                }
                else {
                    event.preventDefault();
                    return false;
                }
            }
            return input;
        },
        formatPhoneNumber: function (data) {
            if (data.length > 3 && data.length <= 6) {
                data = data.slice(0, 3) + "-" + data.slice(3);
            }
            else if (data.length > 6) {
                data = data.slice(0, 3) + "-" + data.slice(3, 6) + "-" + data.slice(6);
            }
            return data;
        },
        formatDate: function (data) {
            if (data.length >= 2 && data.length <= 4) {
                data = data.slice(0, 2) + "/" + data.slice(2);
            }
            else if (data.length > 4) {
                data = data.slice(0, 2) + "/" + data.slice(2, 4) + "/" + data.slice(4);
            }
            return data;
        }
    };

    $jq.fn.observe_fxbForms = function () {
        var fieldController = new FieldController();
        target = this[0];
        var observer = new MutationObserver(function (mutations) {
            for (var index = 0; index < mutations.length; index++) {
                var mutation = mutations[index];
                if (mutation.type === 'childList' && mutation.addedNodes.length) {
                    mutation.addedNodes.forEach(function (node) {
                        if (node.nodeName == "FORM") {
                            fieldController.bind();
                        }
                    });
                }
            }
        });
        if (target) {
            observer.observe(target, {
                childList: true,
                subtree: true
            });
        }
        fieldController.bind();
    };

    $jq(document).ready(function () {
        $jq('.contact-form').observe_fxbForms();
    });
})(jQuery));