text: (function($) {
  
      var Alpaca = $.alpaca;
  
      Alpaca.Fields.FileField = Alpaca.Fields.TextField.extend(
      /**
       * @lends Alpaca.Fields.FileField.prototype
       */
      {
          /**
           * @constructs
           * @augments Alpaca.Fields.TextField
           *
           * @class File control with nice custom styles.
           *
           * @param {Object} container Field container.
           * @param {Any} data Field data.
           * @param {Object} options Field options.
           * @param {Object} schema Field schema.
           * @param {Object|String} view Field view.
           * @param {Alpaca.Connector} connector Field connector.
           * @param {Function} errorCallback Error callback.
           */
          constructor: function(container, data, options, schema, view, connector, errorCallback) {
              this.base(container, data, options, schema, view, connector, errorCallback);
          },
  
          /**
           * @see Alpaca.Fields.TextField#setup
           */
          setup: function() {
              this.base();            
              this.controlFieldTemplateDescriptor = this.view.getTemplateDescriptor("controlFieldFile");
          },
                  
          /**
           * @see Alpaca.Fields.TextField#setValue
           */
          setValue: function(value) {
              // be sure to call into base method
              // We won't be able to actually set the value for file input field so we use the mask input
              var tmp = this.field;
              this.field = $('.alpaca-filefield-control',this.fieldContainer);
              this.base(value);
  
              // switch it back to actual file input
              this.field = tmp;
          },
  
          onChange: function(e)
          {
              this.base(e);
  
              if (this.options.selectionHandler)
              {
                  this.processSelectionHandler(e.target.files);
              }
          },
  
          processSelectionHandler: function(files)
          {
              if (files && files.length > 0)
              {
                  // if the browser supports HTML5 FileReader, we can pull in the stream for preview
                  if (typeof(FileReader) !== "undefined")
                  {
                      // clear out previous loaded data
                      var loadedData = [];
                      var loadCount = 0;
  
                      var fileReader = new FileReader();
                      fileReader.onload = (function() {
                          var field = this;
                          return function(event)
                          {
                              var dataUri = event.target.result;
  
                              loadedData.push(dataUri);
                              loadCount++;
  
                              if (loadCount === files.length)
                              {
                                  field.options.selectionHandler.call(field, files, loadedData);
                              }
                          }
                      }).call(this);
  
                      for (var i = 0; i < files.length; i++)
                      {
                          fileReader.readAsDataURL(files[i]);
                      }
                  }
              }
          },
  
          
          /**
           * @see Alpaca.Fields.TextField#postRender
           */
          postRender: function() {
              this.base();
              // apply additional css
  			if (this.fieldContainer) {
  				this.fieldContainer.addClass("alpaca-controlfield-file");
              }
  
              // listen for change events on the field
          },//__BUILDER_HELPERS
  
          /**
           * @private
           * @see Alpaca.ControlField#getSchemaOfOptions
           */
          getSchemaOfOptions: function() {
              return Alpaca.merge(this.base(), {
                  "properties": {
                      "selectionHandler": {
                          "title": "Selection Handler",
                          "description": "Function that should be called when files are selected.  Requires HTML5.",
                          "type": "boolean",
                          "default": false
                      }
                  }
              });
          },
  
          /**
           * @private
           * @see Alpaca.ControlField#getOptionsForOptions
           */
          getOptionsForOptions: function() {
              return Alpaca.merge(this.base(), {
                  "fields": {
                      "selectionHandler": {
                          "type": "checkbox"
                      }
                  }
              });
          },
  
  		/**
           * @see Alpaca.Fields.TextField#getTitle
  		 */
  		getTitle: function() {
  			return "File Field";
  		},
  		
  		/**
           * @see Alpaca.Fields.TextField#getDescription
  		 */
  		getDescription: function() {
  			return "Field for uploading files.";
  		},
  
  		/**
           * @see Alpaca.Fields.TextField#getFieldType
           */
          getFieldType: function() {
              return "file";
          }//__END_OF_BUILDER_HELPERS
      });
      
      Alpaca.registerTemplate("controlFieldFile", '<input type="file" id="${id}" {{if options.size}}size="${options.size}"{{/if}} {{if options.readonly}}readonly="readonly"{{/if}} {{if name}}name="${name}"{{/if}} {{each(i,v) options.data}}data-${i}="${v}"{{/each}}/>');
      Alpaca.registerFieldClass("file", Alpaca.Fields.FileField);
  })(jQuery);
  