text: (function(define) {
      'use strict';
      define([
          'gettext', 'jquery', 'underscore', 'backbone',
          'edx-ui-toolkit/js/utils/html-utils', 'js/views/fields',
          'text!templates/fields/field_image.underscore',
          'backbone-super', 'jquery.fileupload'
      ], function(gettext, $, _, Backbone, HtmlUtils, FieldViews, FieldImageTemplate) {
          var ImageFieldView = FieldViews.FieldView.extend({
  
              fieldType: 'image',
  
              fieldTemplate: FieldImageTemplate,
              uploadButtonSelector: '.upload-button-input',
  
              titleAdd: gettext('Upload an image'),
              titleEdit: gettext('Change image'),
              titleRemove: gettext('Remove'),
  
              titleUploading: gettext('Uploading'),
              titleRemoving: gettext('Removing'),
  
              titleImageAlt: '',
              screenReaderTitle: gettext('Image'),
  
              iconUpload: '<span class="icon fa fa-camera" aria-hidden="true"></span>',
              iconRemove: '<span class="icon fa fa-remove" aria-hidden="true"></span>',
              iconProgress: '<span class="icon fa fa-spinner fa-pulse fa-spin" aria-hidden="true"></span>',
  
              errorMessage: gettext('An error has occurred. Refresh the page, and then try again.'),
  
              events: {
                  'click .u-field-upload-button': 'clickedUploadButton',
                  'click .u-field-remove-button': 'clickedRemoveButton',
                  'click .upload-submit': 'clickedUploadButton',
                  'focus .upload-button-input': 'showHoverState',
                  'blur .upload-button-input': 'hideHoverState'
              },
  
              initialize: function(options) {
                  this.options = _.extend({}, options);
                  this._super(options);
                  _.bindAll(this, 'render', 'imageChangeSucceeded', 'imageChangeFailed', 'fileSelected',
                            'watchForPageUnload', 'onBeforeUnload');
              },
  
              render: function() {
                  var attributes = {
                      id: this.options.valueAttribute,
                      inputName: (this.options.inputName || 'file'),
                      imageUrl: _.result(this, 'imageUrl'),
                      imageAltText: _.result(this, 'imageAltText'),
                      uploadButtonIcon: _.result(this, 'iconUpload'),
                      uploadButtonTitle: _.result(this, 'uploadButtonTitle'),
                      removeButtonIcon: _.result(this, 'iconRemove'),
                      removeButtonTitle: _.result(this, 'removeButtonTitle'),
                      screenReaderTitle: _.result(this, 'screenReaderTitle')
                  };
                  this.$el.html(HtmlUtils.HTML(this.template(attributes)).toString());
                  this.delegateEvents();
                  this.updateButtonsVisibility();
                  this.watchForPageUnload();
                  return this;
              },
  
              showHoverState: function() {
                  this.$('.u-field-upload-button').addClass('button-visible');
              },
  
              hideHoverState: function() {
                  this.$('.u-field-upload-button').removeClass('button-visible');
              },
  
              showErrorMessage: function(message) {
                  return message;
              },
  
              imageUrl: function() {
                  return '';
              },
  
              uploadButtonTitle: function() {
                  if (this.isShowingPlaceholder()) {
                      return _.result(this, 'titleAdd');
                  } else {
                      return _.result(this, 'titleEdit');
                  }
              },
  
              removeButtonTitle: function() {
                  return this.titleRemove;
              },
  
              isEditingAllowed: function() {
                  return true;
              },
  
              isShowingPlaceholder: function() {
                  return false;
              },
  
              setUploadButtonVisibility: function(state) {
                  this.$('.u-field-upload-button').css('display', state);
              },
  
              setRemoveButtonVisibility: function(state) {
                  this.$('.u-field-remove-button').css('display', state);
              },
  
              updateButtonsVisibility: function() {
                  if (!this.isEditingAllowed() || !this.options.editable) {
                      this.setUploadButtonVisibility('none');
                  }
  
                  if (this.isShowingPlaceholder() || !this.options.editable) {
                      this.setRemoveButtonVisibility('none');
                  }
              },
  
              clickedUploadButton: function() {
                  $(this.uploadButtonSelector).fileupload({
                      url: this.options.imageUploadUrl,
                      type: 'POST',
                      add: this.fileSelected,
                      done: this.imageChangeSucceeded,
                      fail: this.imageChangeFailed
                  });
              },
  
              clickedRemoveButton: function() {
                  var view = this;
                  this.setCurrentStatus('removing');
                  this.setUploadButtonVisibility('none');
                  this.showRemovalInProgressMessage();
                  $.ajax({
                      type: 'POST',
                      url: this.options.imageRemoveUrl
                  }).done(function() {
                      view.imageChangeSucceeded();
                  }).fail(function(jqXHR) {
                      view.showImageChangeFailedMessage(jqXHR.status, jqXHR.responseText);
                  });
              },
  
              imageChangeSucceeded: function() {
                  this.$('.u-field-upload-button').removeClass('in-progress');
                  this.render();
              },
  
              imageChangeFailed: function(e, data) {
              },
  
              showImageChangeFailedMessage: function(status, responseText) {
              },
  
              fileSelected: function(e, data) {
                  if (_.isUndefined(data.files[0].size) || this.validateImageSize(data.files[0].size)) {
                      this.setCurrentStatus('uploading');
                      this.setRemoveButtonVisibility('none');
                      this.showUploadInProgressMessage();
                      data.submit();
                  }
              },
  
              validateImageSize: function(imageBytes) {
                  var humanReadableSize;
                  if (imageBytes < this.options.imageMinBytes) {
                      humanReadableSize = this.bytesToHumanReadable(this.options.imageMinBytes);
                      this.showErrorMessage(
                          interpolate_text(
                              gettext('The file must be at least {size} in size.'), {size: humanReadableSize}
                          )
                      );
                      return false;
                  } else if (imageBytes > this.options.imageMaxBytes) {
                      humanReadableSize = this.bytesToHumanReadable(this.options.imageMaxBytes);
                      this.showErrorMessage(
                          interpolate_text(
                              gettext('The file must be smaller than {size} in size.'), {size: humanReadableSize}
                          )
                      );
                      return false;
                  }
                  return true;
              },
  
              showUploadInProgressMessage: function() {
                  this.$('.u-field-upload-button').addClass('in-progress');
                  HtmlUtils.setHtml(this.$('.upload-button-icon'), HtmlUtils.HTML(this.iconProgress));
                  HtmlUtils.setHtml(this.$('.upload-button-title'), HtmlUtils.HTML(this.titleUploading));
              },
  
              showRemovalInProgressMessage: function() {
                  this.$('.u-field-remove-button').css('opacity', 1);
                  HtmlUtils.setHtml(this.$('.remove-button-icon'), HtmlUtils.HTML(this.iconProgress));
                  HtmlUtils.setHtml(this.$('.remove-button-title'), HtmlUtils.HTML(this.titleRemoving));
              },
  
              setCurrentStatus: function(status) {
                  this.$('.image-wrapper').attr('data-status', status);
              },
  
              getCurrentStatus: function() {
                  return this.$('.image-wrapper').attr('data-status');
              },
  
              watchForPageUnload: function() {
                  $(window).on('beforeunload', this.onBeforeUnload);
              },
  
              onBeforeUnload: function() {
                  var status = this.getCurrentStatus();
                  if (status === 'uploading') {
                      return gettext('Upload is in progress. To avoid errors, stay on this page until the process is complete.');
                  } else if (status === 'removing') {
                      return gettext('Removal is in progress. To avoid errors, stay on this page until the process is complete.');
                  }
              },
  
              bytesToHumanReadable: function(size) {
                  var units = [gettext('bytes'), gettext('KB'), gettext('MB')];
                  var i = 0;
                  while (size >= 1024) {
                      size /= 1024;
                      ++i;
                  }
                  return size.toFixed(1) * 1 + ' ' + units[i];
              }
          });
  
          return ImageFieldView;
      });
  }).call(this, define || RequireJS.define);
  