/**
 * @class Ext.form.field.File
 * @extends Ext.form.field.Text

A file upload field which has custom styling and allows control over the button text and other
features of {@link Ext.form.field.Text text fields} like {@link Ext.form.field.Text#emptyText empty text}.
It uses a hidden file input element behind the scenes to allow user selection of a file and to
perform the actual upload during {@link Ext.form.Basic#submit form submit}.

Because there is no secure cross-browser way to programmatically set the value of a file input,
the standard Field `setValue` method is not implemented. The `{@link #getValue}` method will return
a value that is browser-dependent; some have just the file name, some have a full path, some use
a fake path.
{@img Ext.form.File/Ext.form.File.png Ext.form.File component}
#Example Usage:#

    Ext.create('Ext.form.Panel', {
        title: 'Upload a Photo',
        width: 400,
        bodyPadding: 10,
        frame: true,
        renderTo: Ext.getBody(),    
        items: [{
            xtype: 'filefield',
            name: 'photo',
            fieldLabel: 'Photo',
            labelWidth: 50,
            msgTarget: 'side',
            allowBlank: false,
            anchor: '100%',
            buttonText: 'Select Photo...'
        }],
   
        buttons: [{
            text: 'Upload',
            handler: function() {
                var form = this.up('form').getForm();
                if(form.isValid()){
                    form.submit({
                        url: 'photo-upload.php',
                        waitMsg: 'Uploading your photo...',
                        success: function(fp, o) {
                            Ext.Msg.alert('Success', 'Your photo "' + o.result.file + '" has been uploaded.');
                        }
                    });
                }
            }
        }]
    });

 * @constructor
 * Create a new File field
 * @param {Object} config Configuration options
 * @xtype filefield
 * @markdown
 * @docauthor Jason Johnston <jason@sencha.com>
 */

Ext.define("Ext.form.field.File", {
    extend
: 'Ext.form.field.Text',
   
alias: ['widget.filefield', 'widget.fileuploadfield'],
    alternateClassName
: ['Ext.form.FileUploadField', 'Ext.ux.form.FileUploadField', 'Ext.form.File'],
    uses
: ['Ext.button.Button', 'Ext.layout.component.field.File'],

    /**
     * @cfg {String} buttonText The button text to display on the upload button (defaults to
     * 'Browse...').  Note that if you supply a value for {@link #buttonConfig}, the buttonConfig.text
     * value will be used instead if available.
     */

    buttonText
: 'Browse...',

    /**
     * @cfg {Boolean} buttonOnly True to display the file upload field as a button with no visible
     * text field (defaults to false).  If true, all inherited Text members will still be available.
     */

    buttonOnly
: false,

    /**
     * @cfg {Number} buttonMargin The number of pixels of space reserved between the button and the text field
     * (defaults to 3).  Note that this only applies if {@link #buttonOnly} = false.
     */

    buttonMargin
: 3,

    /**
     * @cfg {Object} buttonConfig A standard {@link Ext.button.Button} config object.
     */


    /**
     * @event change
     * Fires when the underlying file input field's value has changed from the user
     * selecting a new file from the system file selection dialog.
     * @param {Ext.ux.form.FileUploadField} this
     * @param {String} value The file value returned by the underlying file input field
     */


    /**
     * @property fileInputEl
     * @type {Ext.core.Element}
     * A reference to the invisible file input element created for this upload field. Only
     * populated after this component is rendered.
     */


    /**
     * @property button
     * @type {Ext.button.Button}
     * A reference to the trigger Button component created for this upload field. Only
     * populated after this component is rendered.
     */


    /**
     * @cfg {String} fieldBodyCls
     * An extra CSS class to be applied to the body content element in addition to {@link #fieldBodyCls}.
     * Defaults to 'x-form-file-wrap' for file upload field.
     */

    fieldBodyCls
: Ext.baseCSSPrefix + 'form-file-wrap',


   
// private
    readOnly
: true,
    componentLayout
: 'filefield',

   
// private
    onRender
: function() {
       
var me = this,
            inputEl
;

        me
.callParent(arguments);

        me
.createButton();
        me
.createFileInput();
       
       
// we don't create the file/button til after onRender, the initial disable() is
       
// called in the onRender of the component.
       
if (me.disabled) {
            me
.disableItems();
       
}

        inputEl
= me.inputEl;
        inputEl
.dom.removeAttribute('name'); //name goes on the fileInput, not the text input
       
if (me.buttonOnly) {
            inputEl
.setDisplayed(false);
       
}
   
},

    /**
     * @private
     * Creates the custom trigger Button component. The fileInput will be inserted into this.
     */

    createButton
: function() {
       
var me = this;
        me
.button = Ext.widget('button', Ext.apply({
            renderTo
: me.bodyEl,
            text
: me.buttonText,
            cls
: Ext.baseCSSPrefix + 'form-file-btn',
            preventDefault
: false,
            ownerCt
: me,
            style
: me.buttonOnly ? '' : 'margin-left:' + me.buttonMargin + 'px'
       
}, me.buttonConfig));
   
},

    /**
     * @private
     * Creates the file input element. It is inserted into the trigger button component, made
     * invisible, and floated on top of the button's other content so that it will receive the
     * button's clicks.
     */

    createFileInput
: function() {
       
var me = this;
        me
.fileInputEl = me.button.el.createChild({
            name
: me.getName(),
            cls
: Ext.baseCSSPrefix + 'form-file-input',
            tag
: 'input',
            type
: 'file',
            size
: 1
       
}).on('change', me.onFileChange, me);
   
},

    /**
     * @private Event handler fired when the user selects a file.
     */

    onFileChange
: function() {
       
this.lastValue = null; // force change event to get fired even if the user selects a file with the same name
       
Ext.form.field.File.superclass.setValue.call(this, this.fileInputEl.dom.value);
   
},

    /**
     * Overridden to do nothing
     * @hide
     */

    setValue
: Ext.emptyFn,

    reset
: function(){
       
this.fileInputEl.remove();
       
this.createFileInput();
       
this.callParent();
   
},

    onDisable
: function(){
       
this.callParent();
       
this.disableItems();
   
},
   
    disableItems
: function(){
       
var file = this.fileInputEl,
            button
= this.button;
             
       
if (file) {
            file
.dom.disabled = true;
       
}
       
if (button) {
            button
.disable();
       
}    
   
},

    onEnable
: function(){
       
var me = this;
        me
.callParent();
        me
.fileInputEl.dom.disabled = false;
        me
.button.enable();
   
},

    isFileUpload
: function() {
       
return true;
   
},

    extractFileInput
: function() {
       
var fileInput = this.fileInputEl.dom;
       
this.reset();
       
return fileInput;
   
},

    onDestroy
: function(){
       
Ext.destroyMembers(this, 'fileInputEl', 'button');
       
this.callParent();
   
}


});