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

This class creates a multiline text field, which can be used as a direct replacement for traditional
textarea fields. In addition, it supports automatically {@link #grow growing} the height of the textarea to
fit its content.

All of the configuration options from {@link Ext.form.field.Text} can be used on TextArea.
{@img Ext.form.TextArea/Ext.form.TextArea.png Ext.form.TextArea component}
Example usage:

    Ext.create('Ext.form.FormPanel', {
        title      : 'Sample TextArea',
        width      : 400,
        bodyPadding: 10,
        renderTo   : Ext.getBody(),
        items: [{
            xtype     : 'textareafield',
            grow      : true,
            name      : 'message',
            fieldLabel: 'Message',
            anchor    : '100%'
        }]
    });

Some other useful configuration options when using {@link #grow} are {@link #growMin} and {@link #growMax}. These
allow you to set the minimum and maximum grow heights for the textarea.

 * @docauthor Robert Dougan <rob@sencha.com>
 */

Ext.define('Ext.form.field.TextArea', {
    extend
:'Ext.form.field.Text',
    alias
: ['widget.textareafield', 'widget.textarea'],
    alternateClassName
: 'Ext.form.TextArea',
    requires
: ['Ext.XTemplate', 'Ext.layout.component.field.TextArea'],

    fieldSubTpl
: [
       
'<textarea id="{id}" ',
           
'<tpl if="name">name="{name}" </tpl>',
           
'<tpl if="rows">rows="{rows}" </tpl>',
           
'<tpl if="cols">cols="{cols}" </tpl>',
           
'<tpl if="tabIdx">tabIndex="{tabIdx}" </tpl>',
           
'class="{fieldCls} {typeCls}" ',
           
'autocomplete="off">',
       
'</textarea>',
       
{
            compiled
: true,
            disableFormats
: true
       
}
   
],

    /**
     * @cfg {Number} growMin The minimum height to allow when <tt>{@link Ext.form.field.Text#grow grow}=true</tt>
     * (defaults to <tt>60</tt>)
     */

    growMin
: 60,

    /**
     * @cfg {Number} growMax The maximum height to allow when <tt>{@link Ext.form.field.Text#grow grow}=true</tt>
     * (defaults to <tt>1000</tt>)
     */

    growMax
: 1000,

    /**
     * @cfg {String} growAppend
     * A string that will be appended to the field's current value for the purposes of calculating the target
     * field size. Only used when the {@link #grow} config is <tt>true</tt>. Defaults to a newline for TextArea
     * to ensure there is always a space below the current line.
     */

    growAppend
: '\n-',

    /**
     * @cfg {Number} cols An initial value for the 'cols' attribute on the textarea element. This is only
     * used if the component has no configured {@link #width} and is not given a width by its container's
     * layout. Defaults to <tt>20</tt>.
     */

    cols
: 20,

    /**
     * @cfg {Number} cols An initial value for the 'cols' attribute on the textarea element. This is only
     * used if the component has no configured {@link #width} and is not given a width by its container's
     * layout. Defaults to <tt>4</tt>.
     */

    rows
: 4,

    /**
     * @cfg {Boolean} enterIsSpecial
     * True if you want the enter key to be classed as a <tt>special</tt> key. Special keys are generally navigation
     * keys (arrows, space, enter). Setting the config property to <tt>true</tt> would mean that you could not insert
     * returns into the textarea.
     * (defaults to <tt>false</tt>)
     */

    enterIsSpecial
: false,

    /**
     * @cfg {Boolean} preventScrollbars <tt>true</tt> to prevent scrollbars from appearing regardless of how much text is
     * in the field. This option is only relevant when {@link #grow} is <tt>true</tt>. Equivalent to setting overflow: hidden, defaults to
     * <tt>false</tt>.
     */

    preventScrollbars
: false,

   
// private
    componentLayout
: 'textareafield',

   
// private
    onRender
: function(ct, position) {
       
var me = this;
       
Ext.applyIf(me.subTplData, {
            cols
: me.cols,
            rows
: me.rows
       
});

        me
.callParent(arguments);
   
},

   
// private
    afterRender
: function(){
       
var me = this;

        me
.callParent(arguments);

       
if (me.grow) {
           
if (me.preventScrollbars) {
                me
.inputEl.setStyle('overflow', 'hidden');
           
}
            me
.inputEl.setHeight(me.growMin);
       
}
   
},

   
// private
    fireKey
: function(e) {
       
if (e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() !== e.ENTER || e.hasModifier()))) {
           
this.fireEvent('specialkey', this, e);
       
}
   
},

    /**
     * Automatically grows the field to accomodate the height of the text up to the maximum field height allowed.
     * This only takes effect if <tt>{@link #grow} = true</tt>, and fires the {@link #autosize} event if
     * the height changes.
     */

    autoSize
: function() {
       
var me = this,
            height
;

       
if (me.grow && me.rendered) {
            me
.doComponentLayout();
            height
= me.inputEl.getHeight();
           
if (height !== me.lastInputHeight) {
                me
.fireEvent('autosize', height);
                me
.lastInputHeight = height;
           
}
       
}
   
},

   
// private
    initAria
: function() {
       
this.callParent(arguments);
       
this.getActionEl().dom.setAttribute('aria-multiline', true);
   
},

    /**
     * @protected override
     * To get the natural width of the textarea element, we do a simple calculation based on the
     * 'cols' config. We use hard-coded numbers to approximate what browsers do natively,
     * to avoid having to read any styles which would hurt performance.
     */

    getBodyNaturalWidth
: function() {
       
return Math.round(this.cols * 6.5) + 20;
   
}

});