/**
 * A view for uploading a file.
 *
 * Currently only single-file upload is supported (to support multiple-file uploads, the HTML
 * input must be changed to specify "multiple" and the notification messaging needs to be changed
 * to support the display of multiple status messages).
 *
 * There is no associated model, but the view supports the following options:
 *
 * @param title, the title to display.
 * @param inputLabel, a label that will be added for the file input field. Note that this label is only shown to
 *     screen readers.
 * @param inputTip, a tooltip linked to the file input field. Can be used to state what sort of file can be uploaded.
 * @param extensions, the allowed file extensions of the uploaded file, as a comma-separated string (ex, ".csv,.txt").
 *     Some browsers will enforce that only files with these extensions can be uploaded, but others
 *     (for instance, Firefox), will not. By default, no extensions are specified and any file can be uploaded.
 * @param submitButtonText, text to display on the submit button to upload the file. The default value for this is
 *     "Upload File".
 * @param url, the url for posting the uploaded file.
 * @param successNotification, optional callback that can return a success NotificationModel for display
 *     after a file was successfully uploaded. This method will be passed the uploaded file, event, and data.
 * @param errorNotification, optional callback that can return a success NotificationModel for display
 *     after a file failed to upload. This method will be passed the attempted file, event, and data.
 */
(function(Backbone, $, _, gettext, interpolate_text, NotificationModel, NotificationView) {
    // Requires JQuery-File-Upload.
    var FileUploaderView = Backbone.View.extend({

        initialize: function(options) {
            this.template = _.template($('#file-upload-tpl').text());
            this.options = options;
        },

        render: function() {
            var options = this.options,
                get_option_with_default = function(option, default_value) {
                    var optionVal = options[option];
                    return optionVal ? optionVal : default_value;
                },
                submitButton, resultNotification;

            this.$el.html(this.template({
                title: get_option_with_default('title', ''),
                inputLabel: get_option_with_default('inputLabel', ''),
                inputTip: get_option_with_default('inputTip', ''),
                extensions: get_option_with_default('extensions', ''),
                submitButtonText: get_option_with_default('submitButtonText', gettext('Upload File')),
                url: get_option_with_default('url', '')
            }));

            submitButton = this.$el.find('.submit-file-button');
            resultNotification = this.$el.find('.result'),

            this.$el.find('#file-upload-form').fileupload({
                dataType: 'json',
                type: 'POST',
                done: this.successHandler.bind(this),
                fail: this.errorHandler.bind(this),
                autoUpload: false,
                replaceFileInput: false,
                add: function(e, data) {
                    var file = data.files[0];
                    submitButton.removeClass('is-disabled').attr('aria-disabled', false);
                    submitButton.unbind('click');
                    submitButton.click(function(event) {
                        event.preventDefault();
                        data.submit();
                    });
                    resultNotification.html('');
                }
            });

            return this;
        },

        successHandler: function(event, data) {
            var file = data.files[0].name;
            var notificationModel;
            if (this.options.successNotification) {
                notificationModel = this.options.successNotification(file, event, data);
            }
            else {
                notificationModel = new NotificationModel({
                    type: 'confirmation',
                    title: interpolate_text(gettext("Your upload of '{file}' succeeded."), {file: file})
                });
            }
            var notification = new NotificationView({
                el: this.$('.result'),
                model: notificationModel
            });
            notification.render();
        },

        errorHandler: function(event, data) {
            var file = data.files[0].name, message = null, jqXHR = data.response().jqXHR;
            var notificationModel;
            if (this.options.errorNotification) {
                notificationModel = this.options.errorNotification(file, event, data);
            }
            else {
                if (jqXHR.responseText) {
                    try {
                        message = JSON.parse(jqXHR.responseText).error;
                    }
                    catch (err) {
                    }
                }
                if (!message) {
                    message = interpolate_text(gettext("Your upload of '{file}' failed."), {file: file});
                }
                notificationModel = new NotificationModel({
                    type: 'error',
                    title: message
                });
            }
            var notification = new NotificationView({
                el: this.$('.result'),
                model: notificationModel
            });
            notification.render();
        }
    });

    this.FileUploaderView = FileUploaderView;
}).call(this, Backbone, $, _, gettext, interpolate_text, NotificationModel, NotificationView);