var mongoforms = {
    NESTING_SEPARATOR: '__',
    DEFAULT_PREPREFIX: 'inline-'
};

(function($){
    // add regex filter: http://james.padolsey.com/javascript/regex-selector-for-jquery/
    $.expr[':'].regex = function(elem, index, match) {
        var matchParams = match[3].split(','),
            validLabels = /^(data|css):/,
            attr = {
                method: matchParams[0].match(validLabels) ? 
                            matchParams[0].split(':')[0] : 'attr',
                property: matchParams.shift().replace(validLabels,'')
            },
            regexFlags = 'ig',
            regex = new RegExp(matchParams.join('').replace(/^\s+|\s+$/g,''), regexFlags);
        return regex.test(jQuery(elem)[attr.method](attr.property));
    }

    mongoforms.FINAL_INDEX_PATTERN = mongoforms.NESTING_SEPARATOR + '\\d+$';
    mongoforms.FINAL_INDEX_RE = new RegExp(mongoforms.FINAL_INDEX_PATTERN);

    $(".add-another-link").live("click", function(){
        mongoforms.add_inline($(this).attr('prefix'));
        $(this).trigger('add_inline_callback');
        return false;
    });

    mongoforms.add_inline = function(prefix, preprefix){
        if(typeof(preprefix) == 'undefined'){
            preprefix = mongoforms.DEFAULT_PREPREFIX;
        }
        // find last inline (empty, hidden)
        var last_inline = mongoforms.find_last_inline(preprefix+prefix);
        // duplicate it
        var second_last_inline = last_inline.clone(true);
        second_last_inline.insertBefore(last_inline);
        // increment index on last inline (and all enclosed elements)
        var old_prefix = mongoforms.name_prefix_from_inline_id(
            last_inline.attr('id'), preprefix);
        var new_prefix = mongoforms.get_next_id(old_prefix);
        mongoforms.update_id(last_inline, old_prefix, new_prefix);
        last_inline.find('[name*='+old_prefix+']').each(
            function(index, element){
                mongoforms.update_id(element, old_prefix, new_prefix);
            }
        );
        $(['id', 'for']).each(function(index, attr){
            last_inline.find('['+attr+'*='+old_prefix+']').each(
                function(index, element){
                    mongoforms.update_id(element, old_prefix, new_prefix);
                }
            );
        });
        // include raw-id lookup elements
        last_inline.find('[id^=lookup_id_'+old_prefix+']').each(
            function(index, element){
                mongoforms.update_id(element, old_prefix, new_prefix);
            }
        );
        second_last_inline.show();
        $("*[id^=field-group-]", second_last_inline).show();

        //var empty_name = old_prefix + mongoforms.NESTING_SEPARATOR +
        //    'EMPTY_INLINE';
        // -- made matching less strict to handle relation inlines too:
        second_last_inline.find(
            'input[name$=EMPTY_INLINE]').attr('checked', false);
        second_last_inline.removeClass('last').removeClass('empty');
    };

    mongoforms.name_prefix_from_inline_id = function(id, preprefix){
        return id.slice(preprefix.length);
    };

    mongoforms.update_id = function(element, prefix, new_prefix){
        $(['name', 'id', 'for']).each(function(index, attribute){
            if($(element).attr(attribute)){
                $(element).attr(
                    attribute,
                    $(element).attr(attribute).replace(prefix, new_prefix));
                // is it dangerous not to restrict match to leading?
                // -- recursive matches could be problematic?
            }
        });
    };

    mongoforms.get_index_from_id = function(id){
        return parseInt(id.split(mongoforms.NESTING_SEPARATOR).reverse()[0])
    };

    mongoforms.get_next_id = function(id){
        var parts = id.split(mongoforms.NESTING_SEPARATOR);
        var old_index = parts.reverse()[0];
        var index_length = old_index.length;
        return id.slice(0, -index_length) + (parseInt(old_index)+1);
    };

    mongoforms.find_last_inline = function(prefix){
        //var inlines = $('li[id^='+prefix+']');
        var inlines = $('li:regex(id,^'+prefix+'_*[0-9]*$)');
        
        inlines.sort(function(a,b){
            var a_id = mongoforms.get_index_from_id($(a).attr('id'));
            var b_id = mongoforms.get_index_from_id($(b).attr('id'));
            return a_id - b_id;
        });
        return inlines.last();
        // or simply return $('li[id^='+prefix+'].last') ?
    };

    mongoforms.get_empty_field = function(container){
        var group_name = $(container).attr('id').replace('field-group-','');
        var empty_field_name = group_name + mongoforms.NESTING_SEPARATOR +
            'EMPTY_EMBEDDED_DOCUMENT';
        return $(container).find('[name=' + empty_field_name + ']');
    };

    mongoforms.get_container = function(empty_field){
        var group_name = $(empty_field).attr('name').replace(
            mongoforms.NESTING_SEPARATOR + 'EMPTY_EMBEDDED_DOCUMENT', '');
        var container_id = 'field-group-'+group_name;
        return $('#'+container_id);
    };

    mongoforms.update_container_display = function(container){
        var empty_field = mongoforms.get_empty_field(container);
        if(empty_field.attr('checked') == true){
            container.addClass('disabled');
        }
        else{
            container.removeClass('disabled');
        }
    };

    $(function(){
        // hide empty inlines
        $('li[id^='+mongoforms.DEFAULT_PREPREFIX+']').each(
            function(index, element){
                var id = $(element).attr('id');
                var prefix = id.replace(mongoforms.FINAL_INDEX_RE, '');
                mongoforms.find_last_inline(prefix).hide();
            }
        );
        // show add-another buttons
        $('li.add-another').show();

		$('#id_biography__EMPTY_EMBEDDED_DOCUMENT').attr('checked', false);

        // link EMPTY_EMBEDDED_DOCUMENT checkboxes to their field groups
        $('[name$=EMPTY_EMBEDDED_DOCUMENT]').live('change', function(){
            var container = mongoforms.get_container($(this));
            mongoforms.update_container_display(container);
        });

        // update initial display for all field groups
        $('ul[id^=field-group-]').each(function(){
            mongoforms.update_container_display($(this));
        });

        // have all input fields uncheck any containing EMPTY_EMBEDDED_DOCUMENT
        // fields upon change
        $('select,textarea,input:not([name$=EMPTY_EMBEDDED_DOCUMENT])').live(
            'change', function(){
                var field = $(this);
                $(this).parents().each(function(){
                    if($(this).attr('id') && $(this).attr('id').search('field-group-') == 0){
                        var empty_field = mongoforms.get_empty_field($(this));
                        empty_field.attr('checked', false);
                        mongoforms.update_container_display($(this));
                    }
                });
            }
        );
    });
})(django.jQuery);

