(function ($) {
    $.fn.customDirtyChecker = function (data) {
        if (data === 'check') {
            let isClean = true;
            this.each((index, element) => {
                if (!checkAllElementsClean($(element))) {
                    isClean = false;
                    return false;
                }
            });

            return isClean;
        }

        this.each((index, element) => {
            prepareDirtyChecker($(element), setDefaults(data, $(element)));
        });
    };

    function setDefaults(data, $element) {
        let elementData = data ? Object.assign({}, data) : {};

        return elementData;
    }

    function prepareDirtyChecker($element, data) {
        $element.find("input:not(.custom-dirty-checker-ignore), select:not(.custom-dirty-checker-ignore)").each((index, child) => {
            let $child = $(child);
            let childVal;

            if ($child.is(':checkbox')) {
                childVal = $child.attr("checked") ? "true" : "false";
            }
            else if ($child.attr("multiple")) {
                childVal = $child.val() ? $child.val().toString() : undefined;
            }
            else {
                childVal = $child.val();
            }

            $child.attr("custom-dirty-checker-value", childVal);
        });
    }

    function checkAllElementsClean($element) {
        let allElementsClean = true;
        $element.find("input:not(.custom-dirty-checker-ignore), select:not(.custom-dirty-checker-ignore)").each((index, child) => {
            let $child = $(child);
            let childValue;

            if ($child.is(':checkbox')) {
                childValue = $child.attr("checked") ? "true" : "false";
            }
            else if ($child.attr("multiple")) {
                childValue = $child.val() ? $child.val().toString() : undefined;
            }
            else {
                childValue = $child.val();

                if (childValue === null) childValue = undefined;
            }

            if ($child.attr("custom-dirty-checker-value") !== childValue) {
                allElementsClean = false;
                return false;
            }
        });

        return allElementsClean;
    }
}(jQuery));


$(document).ready(function () {
    $(".custom-dirty-checker").customDirtyChecker();
});