jQuery(document).ready(function () {

    function createDeleteBtn(collectionHolder)
    {
        var removeButtonText = collectionHolder.data('btn-text-delete') || "Delete";
        return $('<button type="button" class="btn btn-danger"></button>')
            .text(removeButtonText)
            .click(function (e) {
                e.preventDefault();
                $(this).parent().remove();
                return false;
            });
    }

    function createAddBtn(collectionHolder)
    {
        var addButtonText = collectionHolder.data('btn-text-add') || "Add";
        return $('<button type="button" class="btn btn-warning"></button>')
            .text(addButtonText)
            .click(function (e) {
                e.preventDefault();
                collectionHolder.append(createForm(collectionHolder));
                return false;
            });
    }

    function createForm(collectionHolder)
    {
        var prototype = collectionHolder.data('prototype');
        var index = collectionHolder.data('index') || 0;
        var subForm = prototype;
        var prefixMatches = prototype.match(new RegExp('="([^"]+)__name__'));
        if (prefixMatches && prefixMatches.length > 1) {
            // This simple pattern matches field names using _ as separator and
            // nested variable names using the field[key1][key2] notation
            var simplePattern = prefixMatches[1].replace(new RegExp('[^a-z0-9]', 'gi'), '..?');
            subForm = subForm.replace(new RegExp('(' + simplePattern + ')__name__', 'g'), "$1" + index);
        }
        var parsedSubForm = $(subForm);
        var nestedCollectionHolders = parsedSubForm.find("[data-prototype]");
        for (var ii = 0, ll = nestedCollectionHolders.length; ii < ll; ii++) {
            var nestedCollectionHolder = $(nestedCollectionHolders[ii]);
            if (0 < nestedCollectionHolder.data('prototype').length) {
                initSubForm(nestedCollectionHolder);
                nestedCollectionHolder.append(createForm(nestedCollectionHolder));
            }
        }

        collectionHolder.data('index', index + 1);
        parsedSubForm.append(createDeleteBtn(collectionHolder));

        return parsedSubForm;
    }

    function initSubForm(collectionHolder)
    {
        var formElements = collectionHolder.find('> .form-group');

        collectionHolder.data('index', formElements.length);
        formElements.append(createDeleteBtn(collectionHolder));

        collectionHolder.after(createAddBtn(collectionHolder));
    }

    $("form [data-prototype]:not(.form-collection)").each(function () {
        var collectionHolder = $(this);
        if (0 < collectionHolder.data('prototype').length) {
            initSubForm($(this));
        }
    });
});
