(function($)    {
    function form_data(form)   {
        return form.find("input[checked], input[type='text'], input[type='hidden'], input[type='password'], input[type='submit'], option[selected], textarea").filter(':enabled');
    }
    function inputs(form)   {
        return form.find("input, select, textarea");
    }

    $.fn.validate = function(url, settings) {
        settings = $.extend({
            type: 'table',
            callback: false,
            fields: false,
            dom: this,
            event: 'submit'
        }, settings);

        return this.each(function() {
            var form = $(this);
            settings.dom.bind(settings.event, function()  {
                var params = {};
                form_data(form).each(function() {
                    params[ this.name || this.id || this.parentNode.name || this.parentNode.id ] = this.value;
                });

                var status = false;
                if (settings.fields) {
                    params.fields = settings.fields;
                }
                $('#err_'+this.id).remove();
                $.ajax({
                    async: false,
                    data: params,
                    dataType: 'json',
                    error: function(XHR, textStatus, errorThrown)   {
                        status = true;
                    },
                    success: function(data, textStatus) {
                        $.each(params.fields, function(idx, key) {
                            $('#msg_id_'+key).hide();
                            $('#err_id_'+key).remove();
                            $('#ok_id_'+key).remove();
                        });

                        status = data.valid;
                        if (!status)    {
                            if (settings.callback)  {
                                settings.callback(data, form);
                            }
                            else    {
                                is_error = false;
                                $.each(data.errors, function(key, val)  {
                                    if (key == '__all__')   {
                                    }
                                    else {
                                        //$('#err_'+key).remove();
                                        $('#'+key).parent().parent().append('<span id="err_'+key+'" class="sucErr">'+val+'</span>');
                                    }
                                });
                                $.each(params.fields, function(idx, key) {
                                    if (!('id_'+key in data.errors)) {
                                        $('#id_'+key).parent().parent().append('<span id="ok_id_'+key+'" class="sucMsg">　</span>');
                                    }
                                });
                            }
                        }
                        else {
                            $.each(params.fields, function(idx, key) {
                                $('#id_'+key).parent().parent().append('<span id="ok_id_'+key+'" class="sucMsg">　</span>');
                            });
                        }
                    },
                    type: 'POST',
                    url: url
                });
                return status;
            });
        });
    };
})(jQuery);
