/**
 * GRAPPELLI INLINES
 * jquery-plugin for inlines (stacked and tabular)
 */


(function($) {
    $.fn.grp_inline = function(options) {
        var defaults = {
            prefix: "form",                         // The form prefix for your django formset
            addText: "add another",                 // Text for the add link
            deleteText: "remove",                   // Text for the delete link
            addCssClass: "grp-add-handler",             // CSS class applied to the add link
            removeCssClass: "grp-remove-handler",       // CSS class applied to the remove link
            deleteCssClass: "grp-delete-handler",       // CSS class applied to the delete link
            emptyCssClass: "grp-empty-form",            // CSS class applied to the empty row
            formCssClass: "grp-dynamic-form",           // CSS class applied to each form in a formset
            predeleteCssClass: "grp-predelete",
            onBeforeInit: function(form) {},        // Function called before a form is initialized
            onBeforeAdded: function(inline) {},     // Function called before a form is added
            onBeforeRemoved: function(form) {},     // Function called before a form is removed
            onBeforeDeleted: function(form) {},     // Function called before a form is deleted
            onAfterInit: function(form) {},         // Function called after a form has been initialized
            onAfterAdded: function(form) {},        // Function called after a form has been added
            onAfterRemoved: function(inline) {},    // Function called after a form has been removed
            onAfterDeleted: function(form) {}       // Function called after a form has been deleted
        };
        options = $.extend(defaults, options);
        
        return this.each(function() {
            var inline = $(this); // the current inline node
            var totalForms = inline.find("#id_" + options.prefix + "-TOTAL_FORMS");
            // set autocomplete to off in order to prevent the browser from keeping the current value after reload
            totalForms.attr("autocomplete", "off");
            // init inline and add-buttons
            initInlineForms(inline, options);
            initAddButtons(inline, options);
            // button handlers
            addButtonHandler(inline.find("a." + options.addCssClass), options);
            removeButtonHandler(inline.find("a." + options.removeCssClass), options);
            deleteButtonHandler(inline.find("a." + options.deleteCssClass), options);
        });
    };

    getFormIndex = function(elem, options, regex) {
        var formIndex = elem.find("[id^='id_" + options.prefix + "']").attr('id');
        if (!formIndex) { return -1; }
        return parseInt(regex.exec(formIndex)[1], 10);
    };
    
    updateFormIndex = function(elem, options, replace_regex, replace_with) {
        elem.find(':input,span,table,iframe,label,a,ul,p,img,div').each(function() {
            var node = $(this),
                node_id = node.attr('id'),
                node_name = node.attr('name'),
                node_for = node.attr('for'),
                node_href = node.attr("href"),
                node_class = node.attr("class"),
                node_onclick = node.attr("onclick");
            if (node_id) { node.attr('id', node_id.replace(replace_regex, replace_with)); }
            if (node_name) { node.attr('name', node_name.replace(replace_regex, replace_with)); }
            if (node_for) { node.attr('for', node_for.replace(replace_regex, replace_with)); }
            if (node_href) { node.attr('href', node_href.replace(replace_regex, replace_with)); }
            if (node_class) { node.attr('class', node_class.replace(replace_regex, replace_with)); }
            if (node_onclick) { node.attr('onclick', node_onclick.replace(replace_regex, replace_with)); }
        });
        // update prepopulate ids for function initPrepopulatedFields
        elem.find('.prepopulated_field').each(function() {
            var dependency_ids = $(this).data('dependency_ids') || [],
                dependency_ids_updated = [];
            $.each(dependency_ids, function(i, id) {
                dependency_ids_updated.push(id.replace(replace_regex, replace_with));
            });
            $(this).data('dependency_ids', dependency_ids_updated);
        });
    };

    var initPrepopulatedFields = function(elem, options) {
        elem.find('.prepopulated_field').each(function() {
            var dependency_ids = $(this).data('dependency_ids') || [];
            $(this).prepopulate(dependency_ids, $(this).attr('maxlength'));
        });
    };
    
    initInlineForms = function(elem, options) {
        elem.find("div.grp-module").each(function() {
            var form = $(this);
            // callback
            options.onBeforeInit(form);
            // add options.formCssClass to all forms in the inline
            // except table/theader/add-item
            if (form.attr('id') !== "") {
                form.not("." + options.emptyCssClass).not(".grp-table").not(".grp-thead").not(".add-item").addClass(options.formCssClass);
            }
            // add options.predeleteCssClass to forms with the delete checkbox checked
            form.find("li.grp-delete-handler-container input").each(function() {
                if ($(this).is(":checked") && form.hasClass("has_original")) {
                    form.toggleClass(options.predeleteCssClass);
                }
            });
            // callback
            options.onAfterInit(form);
        });
    };
    
    initAddButtons = function(elem, options) {
        var totalForms = elem.find("#id_" + options.prefix + "-TOTAL_FORMS");
        var maxForms = elem.find("#id_" + options.prefix + "-MAX_NUM_FORMS");
        var addButtons = elem.find("a." + options.addCssClass);
        // hide add button in case we've hit the max, except we want to add infinitely
        if ((maxForms.val() !== '') && (maxForms.val()-totalForms.val()) <= 0) {
            hideAddButtons(elem, options);
        }
    };
    
    addButtonHandler = function(elem, options) {
        elem.bind("click", function() {
            var inline = elem.parents(".grp-group"),
                totalForms = inline.find("#id_" + options.prefix + "-TOTAL_FORMS"),
                maxForms = inline.find("#id_" + options.prefix + "-MAX_NUM_FORMS"),
                addButtons = inline.find("a." + options.addCssClass),
                empty_template = inline.find("#" + options.prefix + "-empty");
            // callback
            options.onBeforeAdded(inline);
            // create new form
            var index = parseInt(totalForms.val(), 10),
                form = empty_template.clone(true);
            form.removeClass(options.emptyCssClass)
                .attr("id", empty_template.attr('id').replace("-empty", index));
            // update form index
            var re = /__prefix__/g;
            updateFormIndex(form, options, re, index);
            // after "__prefix__" strings has been substituted with the number
            // of the inline, we can add the form to DOM, not earlier.
            // This way we can support handlers that track live element
            // adding/removing, like those used in django-autocomplete-light
            form.insertBefore(empty_template)
                .addClass(options.formCssClass);
            // update total forms
            totalForms.val(index + 1);
            // hide add button in case we've hit the max, except we want to add infinitely
            if ((maxForms.val() !== 0) && (maxForms.val() !== "") && (maxForms.val() - totalForms.val()) <= 0) {
                hideAddButtons(inline, options);
            }
            // prepopulate fields
            initPrepopulatedFields(form, options);
            // callback
            options.onAfterAdded(form);
        });
    };
    
    removeButtonHandler = function(elem, options) {
        elem.bind("click", function() {
            var inline = elem.parents(".grp-group"),
                form = $(this).parents("." + options.formCssClass).first(),
                totalForms = inline.find("#id_" + options.prefix + "-TOTAL_FORMS"),
                maxForms = inline.find("#id_" + options.prefix + "-MAX_NUM_FORMS"),
                re = /-(\d+)-/,
                removedFormIndex = getFormIndex(form, options, re);
            // callback
            options.onBeforeRemoved(form);
            // remove form
            form.remove();
            // update total forms
            totalForms.val(parseInt(totalForms.val(), 10) - 1);
            // show add button in case we've dropped below max
            if ((maxForms.val() !== 0) && (maxForms.val() - totalForms.val()) > 0) {
                showAddButtons(inline, options);
            }
            // update form index (only forms with a higher index than the removed form)
            inline.find("." + options.formCssClass).each(function() {
                var form = $(this),
                    formIndex = getFormIndex(form, options, re);
                if (formIndex > removedFormIndex) {
                    updateFormIndex(form, options, re, "-" + (formIndex - 1) + "-");
                }
            });
            // callback
            options.onAfterRemoved(inline);
        });
    };
    
    deleteButtonHandler = function(elem, options) {
        elem.bind("click", function() {
            var deleteInput = $(this).prev(),
                form = $(this).parents("." + options.formCssClass).first();
            // callback
            options.onBeforeDeleted(form);
            // toggle options.predeleteCssClass and toggle checkbox
            if (form.hasClass("has_original")) {
                form.toggleClass(options.predeleteCssClass);
                if (deleteInput.prop("checked")) {
                    deleteInput.removeAttr("checked");
                } else {
                    deleteInput.prop("checked", true);
                }
            }
            // callback
            options.onAfterDeleted(form);
        });
    };
    
    hideAddButtons = function(elem, options) {
        var addButtons = elem.find("a." + options.addCssClass);
        addButtons.hide().parents('.grp-add-item').hide();
        // last row with stacked/tabular
        addButtons.closest('.grp-module.grp-transparent').hide();
    };
    
    showAddButtons = function(elem, options) {
        var addButtons = elem.find("a." + options.addCssClass);
        addButtons.show().parents('.grp-add-item').show();
        // last row with stacked/tabular
        addButtons.closest('.grp-module.grp-transparent').show();
    };
    
})(grp.jQuery);
