/**
 * @description Plugin syntax for jQuery.
 */
(function ($) {
    /**
     * @description Sets plugin namespace for method calling.
     *              Eg. var isFormValid = $('#myForm').nuIsFormValid();
     * @param userOptions Optional options that can be passed in by whatever is calling this.
     */
    $.fn.nuIsFormValid = function(userOptions) {
        var options = $.extend({}, $.fn.nuIsFormValid.defaults, userOptions);

        // First check is to make sure that the supplied element exists and that there is only one element.
        if (this == null || this.size() !== 1) {
            return false;
        }

        // These checks are to make sure that HTML5 validation is supported in the browser,
        // and that there are element types to validate.
        if (!isHtml5ValiditySupported() || !options.validatableElements || options.validatableElements.length === 0) {
            return true;
        }

        // Get all of the child elements that are of the supplied validatableElements type.
        var elementsToValidate = getElementsToValidate(this[0], options.validatableElements);

        // If there are no elements to validate, the form is valid.
        if (elementsToValidate.length === 0) {
            return true;
        }

        // Loop through the child elements and check to see if each is valid.
        for (var i = 0; i < elementsToValidate.length; i++) {
            var childElement = elementsToValidate[i];

            // If a child element is not valid, return false.
            if (childElement.validity && childElement.validity.valid === false) {
                return false;
            }
        }

        // Return true, meaning all validation passed.
        return true;
    };

    // Plugin defaults. The defaults as a property allow easier manipulation outside of the plugin itself.
    $.fn.nuIsFormValid.defaults = {
        validatableElements: ['input', 'textarea']
    };

    function isHtml5ValiditySupported() {
        var inputElement = document.createElement('input');
        return 'validity' in inputElement;
    }

    function getElementsToValidate(formElement, elementTypes) {
        var validatableElements = [];

        for (var i = 0; i < elementTypes.length; i++) {
            var elements = formElement.getElementsByTagName(elementTypes[i]);

            for (var j = 0; j < elements.length; j++) {
                if (elements[j].validity) {
                    validatableElements.push(elements[j]);
                }
            }
        }

        return validatableElements;
    }
}(jQuery));