/**
 * Single radio field. Similar to checkbox, but automatically handles making sure only one radio
 * is checked at a time within a group of radios with the same name.
 *
 * # Labeling
 *
 * In addition to the {@link Ext.form.Labelable standard field labeling options}, radio buttons
 * may be given an optional {@link #boxLabel} which will be displayed immediately to the right
 * of the input. Also see {@link Ext.form.RadioGroup} for a convenient method of grouping related
 * radio buttons.
 *
 * # Values
 *
 * The main value of a Radio field is a boolean, indicating whether or not the radio is checked.
 *
 * The following values will check the radio:
 *
 * - `true`
 * - `'true'`
 * - `'1'`
 * - `'on'`
 *
 * Any other value will uncheck it.
 *
 * In addition to the main boolean value, you may also specify a separate {@link #inputValue}.
 * This will be sent as the parameter value when the form is
 * {@link Ext.form.Basic#submit submitted}. You will want to set this value if you have multiple
 * radio buttons with the same {@link #name}, as is almost always the case.
 *
 * # Example usage
 *
 *     @example
 *     Ext.create('Ext.form.Panel', {
 *         title      : 'Order Form',
 *         width      : 300,
 *         bodyPadding: 10,
 *         renderTo   : Ext.getBody(),
 *         items: [
 *             {
 *                 xtype      : 'fieldcontainer',
 *                 fieldLabel : 'Size',
 *                 defaultType: 'radiofield',
 *                 defaults: {
 *                     flex: 1
 *                 },
 *                 layout: 'hbox',
 *                 items: [
 *                     {
 *                         boxLabel  : 'M',
 *                         name      : 'size',
 *                         inputValue: 'm',
 *                         id        : 'radio1'
 *                     }, {
 *                         boxLabel  : 'L',
 *                         name      : 'size',
 *                         inputValue: 'l',
 *                         id        : 'radio2'
 *                     }, {
 *                         boxLabel  : 'XL',
 *                         name      : 'size',
 *                         inputValue: 'xl',
 *                         id        : 'radio3'
 *                     }
 *                 ]
 *             },
 *             {
 *                 xtype      : 'fieldcontainer',
 *                 fieldLabel : 'Color',
 *                 defaultType: 'radiofield',
 *                 defaults: {
 *                     flex: 1
 *                 },
 *                 layout: 'hbox',
 *                 items: [
 *                     {
 *                         boxLabel  : 'Blue',
 *                         name      : 'color',
 *                         inputValue: 'blue',
 *                         id        : 'radio4'
 *                     }, {
 *                         boxLabel  : 'Grey',
 *                         name      : 'color',
 *                         inputValue: 'grey',
 *                         id        : 'radio5'
 *                     }, {
 *                         boxLabel  : 'Black',
 *                         name      : 'color',
 *                         inputValue: 'black',
 *                         id        : 'radio6'
 *                     }
 *                 ]
 *             }
 *         ],
 *         bbar: [
 *             {
 *                 text: 'Smaller Size',
 *                 handler: function() {
 *                     var radio1 = Ext.getCmp('radio1'),
 *                         radio2 = Ext.getCmp('radio2'),
 *                         radio3 = Ext.getCmp('radio3');
 *
 *                     //if L is selected, change to M
 *                     if (radio2.getValue()) {
 *                         radio1.setValue(true);
 *                         return;
 *                     }
 *
 *                     //if XL is selected, change to L
 *                     if (radio3.getValue()) {
 *                         radio2.setValue(true);
 *                         return;
 *                     }
 *
 *                     //if nothing is set, set size to S
 *                     radio1.setValue(true);
 *                 }
 *             },
 *             {
 *                 text: 'Larger Size',
 *                 handler: function() {
 *                     var radio1 = Ext.getCmp('radio1'),
 *                         radio2 = Ext.getCmp('radio2'),
 *                         radio3 = Ext.getCmp('radio3');
 *
 *                     //if M is selected, change to L
 *                     if (radio1.getValue()) {
 *                         radio2.setValue(true);
 *                         return;
 *                     }
 *
 *                     //if L is selected, change to XL
 *                     if (radio2.getValue()) {
 *                         radio3.setValue(true);
 *                         return;
 *                     }
 *
 *                     //if nothing is set, set size to XL
 *                     radio3.setValue(true);
 *                 }
 *             },
 *             '-',
 *             {
 *                 text: 'Select color',
 *                 menu: {
 *                     indent: false,
 *                     items: [
 *                         {
 *                             text: 'Blue',
 *                             handler: function() {
 *                                 var radio = Ext.getCmp('radio4');
 *                                 radio.setValue(true);
 *                             }
 *                         },
 *                         {
 *                             text: 'Grey',
 *                             handler: function() {
 *                                 var radio = Ext.getCmp('radio5');
 *                                 radio.setValue(true);
 *                             }
 *                         },
 *                         {
 *                             text: 'Black',
 *                             handler: function() {
 *                                 var radio = Ext.getCmp('radio6');
 *                                 radio.setValue(true);
 *                             }
 *                         }
 *                     ]
 *                 }
 *             }
 *         ]
 *     });
 */
Ext.define('Ext.form.field.Radio', {
    extend: 'Ext.form.field.Checkbox',
    alias: ['widget.radiofield', 'widget.radio'],
    alternateClassName: 'Ext.form.Radio',
    
    requires: ['Ext.form.RadioManager'],
 
    /**
     * @property {Boolean} isRadio
     * The value `true` to identify an object as an instance of this or derived class.
     * @readonly
     */
    isRadio: true,
 
    /**
     * @cfg {String} uncheckedValue
     * @private
     */
 
    inputType: 'radio',
    
    formId: null,
 
    /**
     * @cfg {Boolean/String/Number} [modelValue=inputValue]
     * The value to use for {@link #getModelData} when checked. Uses the {@link #inputValue}
     * by default.
     *
     * @since 6.2.1
     */
    modelValue: undefined,
 
    /**
     * @cfg {Boolean/String/Number} modelValueUnchecked
     * The value to use for {@link #getModelData} when unchecked.
     *
     * @since 6.2.1
     */
    modelValueUnchecked: null,
 
    initComponent: function() {
        var me = this;
 
        if (me.modelValue === undefined) {
            me.modelValue = me.inputValue;
        }
        
        me.callParent();
    },
 
    /**
     * If this radio is part of a group, it will return the selected value
     * @return {String} 
     */
    getGroupValue: function() {
        var selected = this.getManager().getChecked(this.name, this.getFormId());
        
        return selected ? selected.inputValue : null;
    },
 
    onRemoved: function() {
        this.callParent(arguments);
        this.formId = null;
    },
 
    /**
     * Sets either the checked/unchecked status of this Radio, or, if a string value is passed,
     * checks a sibling Radio of the same name whose value is the value specified.
     * @param {String/Boolean} value Checked value, or the value of the sibling radio button
     * to check.
     * @return {Ext.form.field.Radio} this
     */
    setValue: function(value) {
        var me = this,
            active;
 
        if (Ext.isBoolean(value)) {
            me.callParent(arguments);
        }
        else {
            active = me.getManager().getWithValue(me.name, value, me.getFormId()).getAt(0);
            
            if (active) {
                active.setValue(true);
            }
        }
 
        return me;
    },
 
    /**
     * Returns the submit value for the checkbox which can be used when submitting forms.
     * @return {Boolean/Object} True if checked, null if not.
     */
    getSubmitValue: function() {
        return this.checked ? this.inputValue : null;
    },
 
    onChange: function(newVal, oldVal) {
        var me = this,
            ownerCt = me.ownerCt,
            r, rLen, radio, radios;
 
        me.callParent(arguments);
        
        // Standard compliant browsers only fire change event on the radio button
        // that became checked so we need to update other buttons in the group.
        // See also IE8 override.
        if (!me.$groupChange) {
            if (newVal) {
                radios = me.getManager().getByName(me.name, me.getFormId()).items;
                rLen = radios.length;
    
                for (= 0; r < rLen; r++) {
                    radio = radios[r];
    
                    if (radio !== me) {
                        radio.updateValueFromDom();
                    }
                }
            }
    
            if (ownerCt && ownerCt.isRadioGroup && ownerCt.simpleValue) {
                ownerCt.checkChange();
            }
        }
    },
 
    getManager: function() {
        return Ext.form.RadioManager;
    }
});