;(function($) {

    var span_classes = [ '.form_base_required_error',
                         '.form_base_required_valid',
                         '.form_base_required_asterisk',
                         '.form_base_required_asterisk_red',
                         '.form_base_select_required_asterisk',
                         '.form_base_select_required_asterisk_red',
                         '.form_base_check_placeholder' ];

    $.formcheck = {
        defaults: {
            'poll_interval' : 500
        }
    };

    $.formcheck.settings = function(element) {
        return $.data(element, 'formcheck');
    }

    $.formcheck.go = function() {

        var settings = $.formcheck.settings(this);

        var element = this;

        setInterval(function() {
            $.formcheck.poll.call(element);
        }, settings.poll_interval);

        $(this).find('input:visible,select:visible').each(function() {

            $.data(this, 'formcheck', settings);
            $.formcheck.check_element.call(this);
        });
    }

    $.formcheck.poll = function() {

        var $form = $(this);

        $(this).find('input,select').each(function() {
            $.formcheck.check_element.call(this);
        });
    }

    $.formcheck.check_element = function() {

        var settings = $.formcheck.settings(this);

        var $element = $(this);

        if (($element.data('formcheck_value') === undefined) || ($element.data('formcheck_value') !== $element.val())) {

            var required = $element.parent('div').find('span.sr_hidden').length > 0;

            $element.parent('div').find(span_classes.join()).each(function() {

                if ($element.find('option').length > 0) {

                    var in_error = $element.parent('div').find('span.form_base_select_required_error,span.form_base_select_required_error').length > 0;

                    if (required) {

                        if (in_error && $.trim($element.val()).length > 0) {

                            $(this).removeClass('form_base_required_error').addClass('form_base_required_valid');

                        } else if (in_error && $.trim($element.val()).length == 0) {

                            $(this).removeClass('form_base_required_valid').addClass('form_base_required_error');

                        } else if (!in_error && $element.attr('defaultValue').length == 0 && $.trim($element.val()).length > 0) {

                            $(this).addClass('form_base_required_valid');
                        }
                    }

                } else {

                    var in_error = $element.parent('div').find('span.form_base_required_error,span.form_base_required_valid').length > 0;

                    if (required) {

                        if (in_error && $.trim($element.val()).length > 0) {

                            $(this).removeClass('form_base_required_error').addClass('form_base_required_valid');

                        } else if (in_error && $.trim($element.val()).length == 0) {

                            $(this).removeClass('form_base_required_valid').addClass('form_base_required_error');

                        } else if (!in_error && $element.attr('defaultValue').length == 0 && $.trim($element.val()).length > 0) {

                            $(this).addClass('form_base_required_valid');
                        }
                    }
                }
            });

            $element.data('formcheck_value', $element.val());
        }
    }

    $.fn.extend({

        formcheck: function(settings) {

            settings = $.extend({}, $.formcheck.defaults, settings);

            return this.each(function() {

                $.data(this, 'formcheck', settings);
                $.formcheck.go.call(this);
            });
        }
    });

})(jQuery);