// Converts html5 template into ko script template.
// @note: Does not work, currently is unused.
ko.bindingHandlers.html5template = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        // Get value of template binding for the same element.
        var v = allBindings.get('template');
        var template = document.getElementById(v.name);
        if ('content' in document.createElement('template')) {
            var clone = document.importNode(template.content, true);
            var script = document.createElement('script');
            script.setAttribute('type', 'text/html');
            while (clone.hasChildNodes()) {
                script.appendChild(clone.removeChild(clone.firstChild));
            }
            template.parentNode.replaceChild(script, template);
            script.id = v.name;
        }
    },
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    },
};

ko.bindingHandlers.anonymous_template = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        var $textarea = $(element)
        .parents(valueAccessor()['base-selector'])
        .find('.ko-template')
        .eq(valueAccessor()['template-index']);
        $(element).append($textarea.val());
    }
};

App.ko.formset = function($formsTotalCount, serversideFormsCount, maxFormsCount) {
    var self = this;
    var formArray = [];
    /*
    // Fill out all optional forms.
    clientsideFormsCount = maxFormsCount - serversideFormsCount;
    for (var i = 0; i < clientsideFormsCount; i++) {
        formArray[i] = i;
    }
    */
    this.forms = ko.observableArray(formArray);
    this.$formsTotalCount = $formsTotalCount;
    this.serversideFormsCount = serversideFormsCount;
    this.maxFormsCount = maxFormsCount;
    this.hasMoreForms = ko.pureComputed(function () {
        return typeof this.maxFormsCount === 'undefined' ||
            this.getTotalFormsCount() < this.maxFormsCount;
    }, this);
    this.addForm = function(data, event) {
        var formsCount = this.getTotalFormsCount();
        if (this.hasMoreForms()) {
            // Add new knockout template form.
            // Value does not matter because ko template uses foreach $index().
            this.forms.push($.randomHash());
            // Update DOM node for forms total count, otherwise Django will not create extra model forms.
            this.$formsTotalCount.val(this.getTotalFormsCount());
        }
    };
    this.afterFormRendered = function(elements, data) {
        var $elements = $(elements);
        App.initClient($elements);
        self.deleteFormHandler($elements);
    }
};

(function(ko_formset) {
    ko_formset.getTotalFormsCount = function() {
        return this.serversideFormsCount + this.forms().length;
    };
    ko_formset.deleteFormHandler = function($elements) {
        var self = this;
        var formModelName = $elements.find('.panel-title:first').html();
        // Attach event handler to newly added form delete input.
        $elements.findSelf('input[name$="-DELETE"]')
        .on('change', function(ev) {
            if (!this.checked) {
                return;
            }
            var $input = $(this);
            // Get form index in formset client-side generated form list.
            var match = $input.prop('name').match(/-(\d+)-DELETE/);
            if (match === null) {
                throw "Unable to match form index: " + $formsDeleteFields.prop('name');
            }
            var koFormIndex = parseInt(match.pop()) - self.serversideFormsCount;
            $elements.addClass('alert alert-danger');
            new App.Dialog({
                'title': App.trans('Delete "%s"', formModelName),
                'message': App.trans('Are you sure you want to delete "%s" ?', formModelName),
                'callback': function(result) {
                    if (result) {
                        self.forms.splice(koFormIndex, 1);
                    } else {
                        $input.prop('checked', false);
                        $elements.removeClass('alert alert-danger');
                    }
                }
            }).confirm();
        });
    };
})(App.ko.formset.prototype);

App.documentReadyHooks.push(function() {
    $.each($('.formset'), function(k, v) {
        var $formset = $(v);
        var $formsTotalCount;
        var serversideFormsCount;
        var maxFormsCount;
        $.each($formset.find('.management-form :input'), function(k, v) {
            var $input = $(v);
            if ($input.prop('id').match(/TOTAL_FORMS$/)) {
                $formsTotalCount = $input;
                serversideFormsCount = parseInt($input.val());
            }
            if ($input.prop('id').match(/MAX_NUM_FORMS$/)) {
                maxFormsCount = parseInt($input.val());
            }
        });
        if (typeof serversideFormsCount === 'undefined' ||
                typeof maxFormsCount === 'undefined') {
            return;
        }
        var ko_formset = new App.ko.formset(
            $formsTotalCount,
            serversideFormsCount,
            maxFormsCount
        );
        ko.applyBindings(ko_formset, v);
    });
});

App.initClientHooks.push(function($selector) {
    // Do not display delete input for required forms.
    var $requiredFormsDeleteFields = $selector.findSelf('.formset-form-wrap.form-required input[name$="-DELETE"]');
    $requiredFormsDeleteFields.parents('.field').empty().html(App.trans('Required'));
    // Display different label for optional previously saved forms loaded at server-side.
    var $optionalFormsDeleteFields = $selector.findSelf('.formset-form-wrap.form-optional input[name$="-DELETE"]');
    $optionalFormsDeleteFields.next('span').html(App.trans('Delete when saved'))
});
