////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package mx.controls
{

import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.InteractiveObject;
import flash.events.Event;
import flash.events.EventDispatcher;

import mx.core.FlexGlobals;
import mx.core.IFlexDisplayObject;
import mx.core.IMXMLObject;
import mx.core.IRawChildrenContainer;
import mx.core.UIComponent;
import mx.core.mx_internal;
import mx.events.FlexEvent;
import mx.events.ItemClickEvent;

use namespace mx_internal;

//--------------------------------------
//  Events
//--------------------------------------

/**
 *  Dispatched when the value of the selected RadioButton control in
 *  this group changes.
 *
 *  @eventType flash.events.Event.CHANGE
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="change", type="flash.events.Event")]

/**
 *  Dispatched when a user selects a RadioButton control in the group.
 *  You can also set a handler for individual RadioButton controls.
 *
 *  @eventType mx.events.ItemClickEvent.ITEM_CLICK
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="itemClick", type="mx.events.ItemClickEvent")]

//--------------------------------------
//  Other metadata
//--------------------------------------

[DefaultBindingProperty(source="selection", destination="selection")]

[DefaultTriggerEvent("change")]

[IconFile("RadioButtonGroup.png")]

[Alternative(replacement="spark.components.RadioButtonGroup", since="4.0")]

/**
 *  The RadioButtonGroup control defines a group of RadioButton controls
 *  that act as a single mutually exclusive control; therefore,
 *  a user can select only one RadioButton control at a time. While grouping
 *  RadioButton instances
 *  in a RadioButtonGroup is optional, a group lets you do things 
 *  like set a single event handler on a group of buttons, rather than
 *  on each individual button.
 *  
 *  <p>The <code>id</code> property is required when you use the
 *  <code>&lt;mx:RadioButtonGroup&gt;</code> tag to define the name
 *  of the group.</p> 
 *
 *  <p>Notice that the RadioButtonGroup control is a subclass of EventDispatcher, not UIComponent,
 *  and implements the IMXMLObject interface.
 *  All other Flex visual components are subclasses of UIComponent, which implements
 *  the IUIComponent interface.
 *  The RadioButtonGroup control has support built into the Flex compiler
 *  that allows you to use the RadioButtonGroup control as a child of a Flex container,
 *  even though it does not implement IUIComponent.
 *  All other container children must implement the IUIComponent interface.</p>
 *
 *  <p>Therefore, if you try to define a visual component as a subclass of
 *  EventDispatcher that implements the IMXMLObject interface,
 *  you will not be able to use it as the child of a container.</p>
 *
 *  @mxml
 *
 *  <p>The <code>&lt;mx:RadioButtonGroup&gt;</code> tag inherits all of the
 *  tag attributes of its superclass, and adds the following tag attributes:</p>
 *
 *  <pre>
 *  &lt;mx:RadioButtonGroup
 *    <strong>Properties</strong>
 *    enabled="true|false"
 *    id="<i>No default</i>"
 *    labelPlacement="right|left|top|bottom"
 *
 *    <strong>Events</strong>
 *    change="<i>No default</i>"
 *    itemClick="<i>No default</i>"
 *  /&gt;
 *  </pre>
 *
 *  @includeExample examples/RadioButtonGroupExample.mxml
 *
 *  @see mx.controls.RadioButton
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class RadioButtonGroup extends EventDispatcher implements IMXMLObject
{
    include "../core/Version.as";

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     *  Constructor.
     *
     *  @param document In simple cases where a class extends EventDispatcher,
     *  the <code>document</code> parameter should not be used.
     *
     *  @see flash.events.EventDispatcher
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function RadioButtonGroup(document:IFlexDisplayObject = null)
    {
        super();
    }

    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  The document containing a reference to this RadioButtonGroup.
     */
    private var document:IFlexDisplayObject;

    /**
     *  @private
     *  An Array of the RadioButtons that belong to this group.
     */
    private var radioButtons:Array /* of RadioButton */ = [];

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  enabled
    //----------------------------------

    [Bindable("enabledChanged")]
    [Inspectable(category="General", defaultValue="true")]

    /**
     *  Determines whether selection is allowed.
     *
     *  @default true
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get enabled():Boolean
    {
        var s:Number = 0;

        var n:int = numRadioButtons;
        for (var i:int = 0; i < n; i++)
        {
            s = s + getRadioButtonAt(i).enabled;
        }

        if (s == 0)
            return false;

        if (s == n)
            return true;

        return false;
    }

    /**
     *  @private
     */
    public function set enabled(value:Boolean):void
    {
        var n:int = numRadioButtons;
        for (var i:int = 0; i < n; i++)
        {
            getRadioButtonAt(i).enabled = value;
        }

        dispatchEvent(new Event("enabledChanged"));
    }

    //----------------------------------
    //  labelPlacement
    //----------------------------------

    /**
     *  @private
     *  Storage for the labelPlacement property.
     */
    private var _labelPlacement:String = "right";

    [Bindable("labelPlacementChanged")]
    [Inspectable(category="General", enumeration="left,right,top,bottom", defaultValue="right")]

    /**
     *  Position of the RadioButton label relative to the RadioButton icon
     *  for each control in the group.
     *  You can override this setting for the individual controls.
     *
     *  <p>Valid values in MXML are <code>"right"</code>, <code>"left"</code>,
     *  <code>"bottom"</code>, and <code>"top"</code>. </p>
     *
     *  <p>In ActionScript, you use the following constants to set this property:
     *  <code>ButtonLabelPlacement.RIGHT</code>, <code>ButtonLabelPlacement.LEFT</code>,
     *  <code>ButtonLabelPlacement.BOTTOM</code>, and <code>ButtonLabelPlacement.TOP</code>.</p>
     *
     *  @default "right"
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get labelPlacement():String
    {
        return _labelPlacement;
    }

    /**
     *  @private
     */
    public function set labelPlacement(value:String):void
    {
        _labelPlacement = value;

        var n:int = numRadioButtons;
        for (var i:int = 0; i < n; i++)
        {
            getRadioButtonAt(i).labelPlacement = value;
        }
    }

    //----------------------------------
    //  numRadioButtons
    //----------------------------------

    [Bindable("numRadioButtonsChanged")]

    /**
     *  The number of RadioButtons that belong to this RadioButtonGroup.
     *
     *  @default "undefined"
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get numRadioButtons():int
    {
        return radioButtons.length;
    }

    //----------------------------------
    //  selectedValue
    //----------------------------------

    /**
     *  @private
     *  Storage for the selectedValue property.
     */
    private var _selectedValue:Object;

    [Bindable("change")]
    [Bindable("valueCommit")]
    [Inspectable(category="General")]

    /**
     *  The value of the <code>value</code> property of the selected
     *  RadioButton control in the group, if this has been set
     *  to be something other than <code>null</code> (the default value).
     *  Otherwise, <code>selectedValue</code> is the value of the
     *  <code>label</code> property of the selected RadioButton.
     *  If no RadioButton is selected, this property is <code>null</code>.
     *
     *  <p>If you set <code>selectedValue</code>, Flex selects the
     *  RadioButton control whose <code>value</code> or
     *  <code>label</code> property matches this value.</p>
     *
     *  @default null
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get selectedValue():Object
    {
        if (selection)
        {
            return selection.value != null ?
                   selection.value :
                   selection.label;
        }

        return null;
    }

    /**
     *  @private.
     */
    public function set selectedValue(value:Object):void
    {
        _selectedValue = value;

        // Clear the exisiting selecton if there is one.
        if (value == null)
        {
            setSelection(null, false);
            return;
        }
        
        // Find the radio button value specified.
        var n:int = numRadioButtons;
        for (var i:int = 0; i < n; i++)
        {
            var radioButton:RadioButton = getRadioButtonAt(i);
            if (radioButton.value == value ||
                radioButton.label == value)
            {
                changeSelection(i, false);
                break;
            }
        }

        dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT));
    }

    //----------------------------------
    //  selection
    //----------------------------------

    /**
     *  @private
     *  Reference to the selected radio button.
     */
    private var _selection:RadioButton;

    [Bindable("change")]
    [Bindable("valueCommit")]
    [Inspectable(category="General")]

    /**
     *  Contains a reference to the currently selected
     *  RadioButton control in the group.
     *  You can access the property in ActionScript only;
     *  it is not settable in MXML.
     *  Setting this property to <code>null</code> deselects the currently selected RadioButton control.
     *
     *  @default null
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get selection():RadioButton
    {
        return _selection;
    }

    /**
     *  @private
     */
    public function set selection(value:RadioButton):void
    {
        // Going through the selection setter should never fire a change event.
        setSelection(value, false);
    }

    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

    /**
     *  Implementation of the <code>IMXMLObject.initialized()</code> method
     *  to support deferred instantiation.
     *
     *  @param document The MXML document that created this object.
     *
     *  @param id The identifier used by document to refer to this object.
     *  If the object is a deep property on document, <code>id</code> is null.
     *
     *  @see mx.core.IMXMLObject
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function initialized(document:Object, id:String):void
    {
        this.document = document ?
                        IFlexDisplayObject(document) :
                        IFlexDisplayObject(FlexGlobals.topLevelApplication);
    }

    /**
     *  Returns the RadioButton control at the specified index.
     *
     *  @param index The index of the RadioButton control in the
     *  RadioButtonGroup control, where the index of the first control is 0.
     *
     *  @return The specified RadioButton control.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getRadioButtonAt(index:int):RadioButton
    {
        return RadioButton(radioButtons[index]);
    }

    /**
     *  @private
     *  Add a radio button to the group.
     */
    mx_internal function addInstance(instance:RadioButton):void
    {
        instance.addEventListener(Event.REMOVED, radioButton_removedHandler);
        radioButtons.push(instance);

        // Apply group indices in "tab order" or "breadth-first" order.
        radioButtons.sort(readOrderCompare);
        for (var i:int = 0; i < radioButtons.length; i++)
            radioButtons[i].indexNumber = i;

        if (_selectedValue != null)
            selectedValue = _selectedValue;

		dispatchEvent(new Event("numRadioButtonsChanged"));
    }

    /**
     *  @private
     *  Remove a radio button from the group.
     */
    mx_internal function removeInstance(instance:RadioButton):void
    {
        if (instance)
        {

            var foundInstance:Boolean = false;
            for (var i:int = 0; i < numRadioButtons; i++)
            {
                var rb:RadioButton = getRadioButtonAt(i);

                if (foundInstance)
                {
                    // Decrement the indexNumber for each button after the removed button.
                    rb.indexNumber--;
                }
                else if (rb == instance)
                {
                	rb.group = null;

                    if (instance == _selection)
                    {
                        _selection = null;
                    }
                    // Remove the radio button from the internal array
                    radioButtons.splice(i,1);
                    foundInstance = true;
                    // redo the same index because we removed the previous item at this index
                    i--;
                }
            }

            if (foundInstance)
				dispatchEvent(new Event("numRadioButtonsChanged"));
        }
    }

    /**
     *  @private
     *  Return the value or the label value
     *  of the selected radio button.
     */
    private function getValue():String
    {
        if (selection)
        {
            return selection.value &&
                   selection.value is String &&
                   String(selection.value).length != 0 ?
                   String(selection.value) :
                   selection.label;
        }
        else
        {
            return null;
        }
    }

    /**
     *  @private
     */
    mx_internal function setSelection(value:RadioButton, fireChange:Boolean = true):void
    {
        if (value == null)
        {
            if (selection != null)
            {
                _selection.selected = false;
                _selection = null;
                if (fireChange)
                    dispatchEvent(new Event(Event.CHANGE));
            }
        }
        else
        {
            var n:int = numRadioButtons;
            for (var i:int = 0; i < n; i++)
            {
                if (value == getRadioButtonAt(i))
                {
                    changeSelection(i, fireChange);
                    break;
                }
            }
        }

        dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT));
    }

    /**
     *  @private
     */
    private function changeSelection(index:int, fireChange:Boolean = true):void
    {
        if (getRadioButtonAt(index))
        {
            // Unselect the currently selected radio
            if (selection)
                selection.selected = false;

            // Change the focus to the new radio.
            // Set the state of the new radio to true.
            // Fire a click event for the new radio.
            // Fire a click event for the radio group.
            _selection = getRadioButtonAt(index);
            _selection.selected = true;
            if (fireChange)
                dispatchEvent(new Event(Event.CHANGE));
        }
    }

    /**
     *  @private
	 *  Comparison function used to sort items as they are added to the radioButtons array.
	 *  Compares by tabIndex or if neither item defines a tabIndex, by "breadthOrder."
	 * 
	 *  Returns -1 if a is before b in sort order, 0 if a and b have same
     *  sort order and 1 if a after b in sort order.
     */
    private function readOrderCompare(a:DisplayObject, b:DisplayObject):Number
    {
        var aParent:DisplayObject = (a is UIComponent) ? UIComponent(a).$parent : a.parent;
        var bParent:DisplayObject = (b is UIComponent) ? UIComponent(b).$parent : b.parent;

        if (!aParent || !bParent)
            return 0;
		
		// first check to see if we can compare by tabIndex
		var aTabIndex:int = (a is InteractiveObject) ? InteractiveObject(a).tabIndex : -1;
		var bTabIndex:int = (b is InteractiveObject) ? InteractiveObject(b).tabIndex : -1;
		
		// if one of the items being compared has a defined tabIndex, compare by tabIndex
		if(aTabIndex > -1 || bTabIndex > -1)
		{
			if (aTabIndex > bTabIndex)
				return (bTabIndex == -1) ? -1 : 1; // items with assigned tabIndex come before those without
			if (aTabIndex < bTabIndex)
				return (aTabIndex == -1) ? 1 : -1; // items without assigned tabIndex come after those without
			if (a == b)
				return 0;
		}
		
		// if neither item has a defined tabIndex we compare by "breadthOrder"
		var aNestLevel:int = (a is UIComponent) ? UIComponent(a).nestLevel : -1;
        var bNestLevel:int = (b is UIComponent) ? UIComponent(b).nestLevel : -1;

        var aIndex:int = DisplayObjectContainer(aParent).getChildIndex(a);

        var bIndex:int = DisplayObjectContainer(bParent).getChildIndex(b);

        if (aNestLevel > bNestLevel || (a.parent == b.parent && aIndex > bIndex))
            return 1;
        else if (aNestLevel < bNestLevel ||  (a.parent == b.parent && bIndex > aIndex))
            return -1;
        else if (a == b)
            return 0;
        else // Nest levels are identical, compare ancestors.
            return readOrderCompare(aParent, bParent);
    }

    //--------------------------------------------------------------------------
    //
    //  Event Handlers
    //
    //--------------------------------------------------------------------------
     /**
     *  @private
     */
    private function radioButton_removedHandler(event:Event):void
    {
        var rb:RadioButton = event.target as RadioButton;
        if (rb)
        {
        	rb.removeEventListener(Event.REMOVED, radioButton_removedHandler);
            removeInstance(RadioButton(event.target));
        }
    }
}

}
