////////////////////////////////////////////////////////////////////////////////
//
//  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.InteractiveObject;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import mx.collections.ArrayCollection;
import mx.collections.IList;
import mx.containers.Box;
import mx.containers.BoxDirection;
import mx.containers.ViewStack;
import mx.core.ClassFactory;
import mx.core.INavigatorContent;
import mx.core.IFactory;
import mx.core.IFlexDisplayObject;
import mx.core.ScrollPolicy;
import mx.core.UIComponent;
import mx.core.mx_internal;
import mx.events.ChildExistenceChangedEvent;
import mx.events.CollectionEvent;
import mx.events.FlexEvent;
import mx.events.IndexChangedEvent;
import mx.events.ItemClickEvent;
import mx.managers.ISystemManager;
import mx.managers.SystemManager;
import mx.styles.StyleProtoChain;

use namespace mx_internal;

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

/**
 *  Dispatched when a navigation item is selected.
 *
 *  @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")]

//--------------------------------------
//  Excluded APIs
//--------------------------------------

[Exclude(name="defaultButton", kind="property")]
[Exclude(name="horizontalLineScrollSize", kind="property")]
[Exclude(name="horizontalPageScrollSize", kind="property")]
[Exclude(name="horizontalScrollBar", kind="property")]
[Exclude(name="horizontalScrollPolicy", kind="property")]
[Exclude(name="horizontalScrollPosition", kind="property")]
[Exclude(name="icon", kind="property")]
[Exclude(name="label", kind="property")]
[Exclude(name="maxHorizontalScrollPosition", kind="property")]
[Exclude(name="maxVerticalScrollPosition", kind="property")]
[Exclude(name="verticalLineScrollSize", kind="property")]
[Exclude(name="verticalPageScrollSize", kind="property")]
[Exclude(name="verticalScrollBar", kind="property")]
[Exclude(name="verticalScrollPolicy", kind="property")]
[Exclude(name="verticalScrollPosition", kind="property")]

[Exclude(name="scroll", kind="event")]
[Exclude(name="click", kind="event")]

[Exclude(name="horizontalScrollBarStyleName", kind="style")]
[Exclude(name="verticalScrollBarStyleName", kind="style")]

[ResourceBundle("controls")]

/**
 *  The NavBar control is the superclass for navigator controls, such as the
 *  LinkBar and TabBar controls, and cannot be instantiated directly.
 *
 *  @mxml
 *
 *  <p>The <code><mx:NavBar></code> tag inherits all of the tag attributes
 *  of its superclass, with the exception of scrolling-related
 *  attributes, and adds the following tag attributes:</p>
 *
 *  <pre>
 *  &lt;mx:<i>tagname</i>
 *    <strong>Properties</strong>
 *    dataProvider="<i>No default</i>"
 *    enabledField="enabled"
 *    iconField="icon"
 *    labeField="label"
 *    selectedIndex="-1"
 *    toolTipField="toolTip"
 *     
 *    <strong>Events</strong>
 *    itemClick="<i>No default</i>"
 *    &gt;
 *     ...
 *       <i>child tags</i>
 *     ...
 *    &lt;/mx:<i>tagname</i>&gt;
 *  </pre>
 *
 *  @see mx.collections.IList
 *  @see mx.containers.ViewStack
 *  @see mx.controls.LinkBar
 *  @see mx.controls.TabBar
 *  @see mx.controls.ButtonBar
 *  
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class NavBar extends Box
{
    include "../core/Version.as";

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

    /**
     *  Constructor.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function NavBar()
    {
        super();

        direction = BoxDirection.HORIZONTAL;
		showInAutomationHierarchy = true;
    }

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

    /**
     *  @private
     *  The target ViewStack.
     *  If this is null, the dataProvider is an Array.
     */
    mx_internal var targetStack:ViewStack;

    /**
     *  @private
     *  This variable is set when the NavBar is still initializing and the
     *  dataProvider is set to a ViewStack (or a String that might identify
     *  a ViewStack in the parent document).
     */
    private var pendingTargetStack:Object;

    /**
     *  @private
     *  The factory that generates the instances of the navigation items.
     *  It generates instances of ButtonBarButton for ButtonBar and
     *  ToggleButtonBar, of LinkButton for LinkBar, and of Tab for TabBar.
     *  This var is expected to be set before the navigation items are created;
     *  setting it does not re-create existing navigation items based on the
     *  new factory.
     */
    mx_internal var navItemFactory:IFactory = new ClassFactory(Button);

 	/**
     *  @private
     *  allows us to null out child containers' toolTips without descending
     *  into recursive madness.
     */
	private var lastToolTip:String = null;

    /**
     *  @private
     */
    private var measurementHasBeenCalled:Boolean = false;

    //--------------------------------------------------------------------------
    //
    //  Overridden properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  baselinePosition
    //----------------------------------

    /**
     *  @private
     *  The baselinePosition of a NavBar is calculated
	 *  for the label of the first nav item.
 	 *  If there are no nav items, the NavBar doesn't appear
	 *  and the baselinePosition is irrelevant.
     */
    override public function get baselinePosition():Number
    {
		if (!validateBaselinePosition())
			return NaN;

		if (numChildren == 0)
			return super.baselinePosition;

		var child:Button = Button(getChildAt(0));
		
		validateNow();

		return child.y + child.baselinePosition;
    }

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

    [Inspectable(category="General", enumeration="true,false", defaultValue="true")]

    /**
     *  @private
     */
    override public function set enabled(value:Boolean):void
    {
        if (value != enabled)
        {
            super.enabled = value;

            var n:int = numChildren;
            for (var i:int = 0; i < n; i++)
            {
                if (targetStack)
                {
                    Button(getChildAt(i)).enabled = value &&
                            UIComponent(targetStack.getChildAt(i)).enabled;
                }
                else
                {
                    Button(getChildAt(i)).enabled = value;
                }
            }
        }
    }

    //----------------------------------
    //  horizontalScrollPolicy
    //----------------------------------

    [Inspectable(environment="none")]

    /**
     *  @private
     *  The NavBar control's <code>horizontalScrollPolicy</code> is always
     *  <code>ScrollPolicy.OFF</code>.
     *  It cannot be set to any other value.
     */
    override public function get horizontalScrollPolicy():String
    {
        return ScrollPolicy.OFF;
    }

    /**
     *  @private
     */
    override public function set horizontalScrollPolicy(value:String):void
    {
        // A NavBar control never scrolls.
        // Its horizontalScrollPolicy</code> property is initialized to
        // ScrollPolicy.OFF and can't be changed.
    }

    //----------------------------------
    //  verticalScrollPolicy
    //----------------------------------

    [Inspectable(environment="none")]

    /**
     *  @private
     *  The NavBar control's <code>verticalScrollPolicy</code> is always
     *  <code>ScrollPolicy.OFF</code>.
     *  It cannot be set to any other value.
     */
    override public function get verticalScrollPolicy():String
    {
        return ScrollPolicy.OFF;
    }

    /**
     *  @private
     */
    override public function set verticalScrollPolicy(value:String):void
    {
        // A NavBar control never scrolls.
        // Its <code>verticalScrollPolicy</code> property is initialized
        // to <code>ScrollPolicy.OFF</code> and can't be changed.
    }

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

    //----------------------------------
    //  dataProvider
    //----------------------------------

    /**
     *  @private
     *  Storage for the dataProvider property.
     */
    private var _dataProvider:IList;

    /**
     *  @private
     */
    private var dataProviderChanged:Boolean = false;

    [Bindable("collectionChange")]
    [Inspectable(category="Data")]

    /**
     *  Data used to populate the navigator control.
     *  The type of data can either be a ViewStack container or an Array.
     *
     *  <p>When you use a ViewStack container, the <code>label</code>
     *  and <code>icon</code> properties of the ViewStack container's children
     *  are used to populate the navigation items,
     *  as in the following example:</p>
     * 
     *  <pre>
     *  &lt;mx:LinkBar dataProvider="{vs}"/&gt;
     *  &lt;mx:ViewStack id="vs"&gt;
     *    &lt;mx:VBox label="Accounts" icon="account_icon"/&gt;
     *    &lt;mx:VBox label="Leads" icon="leads_icon"/&gt;
     *  &lt;/mx:ViewStack&gt; </pre>
     *  
     *  <p>The LinkBar control contains two links: "Accounts" and "Leads,"
     *  each with its own icon as specified on the VBox tags.
     *  When you click a link, the ViewStack container navigates
     *  to the corresponding view.</p>
     *
     *  <p>When you use an Array, the <code>labelField</code> property
     *  determines the name of the <code>dataProvider</code> field
     *  to use as the label for each navigation item; the <code>iconField</code>
     *  property determines the name of the <code>dataProvider</code> field
     *  to use as the icon for each navigation item. 
     *  If you use an Array of Strings, the <code>labelField</code>
     *  property is ignored.</p>
     *
     *  @default "undefined"
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get dataProvider():Object
    {
        return targetStack ? targetStack : _dataProvider;
    }

    /**
     *  @private
     */
    public function set dataProvider(value:Object /* can be either String, ViewStack, Array or IList */):void
    {
        var message:String;
		
		if (value &&
            !(value is String) &&
            !(value is ViewStack) &&
            !(value is Array) &&
            !(value is IList))
        {
			message = resourceManager.getString(
				"controls", "errWrongContainer", [ id ]);
            throw new Error(message);
        }
		
        if (_dataProvider)
        {
            _dataProvider.removeEventListener(CollectionEvent.COLLECTION_CHANGE,
                                              collectionChangeHandler);
        }

        // If value is a string, try to resolve here.
        // If value is a ViewStack name, document[value] may not be defined yet.
        // In this case, fall through to the code below
        // which will setup a pending target view stack.
        if ((value is String) && (document && document[value]))
            value = document[value];

        if ((value is String) || (value is ViewStack))
        {
            setTargetViewStack(value);
            return;
        }
        else if ((value is IList && IList(value).length > 0 &&
                 IList(value).getItemAt(0) is DisplayObject) ||
                 (value is Array && (value as Array).length > 0 &&
                 value[0] is DisplayObject))
        {
            var name:String = id ?
                              className + " '" + id + "'" :
                              "a " + className;
            message = resourceManager.getString(
				"controls", "errWrongType", [ name ]);
			throw new Error(message);
        }

        // Clear any existing target stack.
        setTargetViewStack(null);
        removeAllChildren();

        if (value is IList)
            _dataProvider = IList(value);
        else if (value is Array)
            _dataProvider = new ArrayCollection(value as Array);
        else
            _dataProvider = null;

        dataProviderChanged = true;
        invalidateProperties();

        if (_dataProvider)
        {
            // use weak reference
            _dataProvider.addEventListener(CollectionEvent.COLLECTION_CHANGE,
                                           collectionChangeHandler, false, 0, true);
        }

        // Styles might not have been set yet, so short circuit and let
        // createChildren() handle the rest.
        if (inheritingStyles == StyleProtoChain.STYLE_UNINITIALIZED)
            return;

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


    //----------------------------------
    //  enabledField
    //----------------------------------

    /**
     *  @private
     *  Storage for the enabled property.
     */
    private var _enabledField:String = "enabled";

    [Bindable("enabledFieldChanged")]
    [Inspectable(category="Data")]

    /**
     *  Name of the the field in the <code>dataProvider</code> object
     *  to use as the enabled label.
     *  
     *  @default "enabled"
     *  
     *  @langversion 3.0
     *  @playerversion Flash 11.1
     *  @playerversion AIR 3.4
     *  @productversion Flex 4.10
     */
    public function get enabledField():String
    {
        return _enabledField;
    }

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

        // If we have a data provider, update here to
        // reflect new enabled field.
        if (_dataProvider)
            dataProvider = _dataProvider;

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


    //----------------------------------
    //  iconField
    //----------------------------------

    /**
     *  @private
     *  Storage for the iconField property.
     */
    private var _iconField:String = "icon";

    [Bindable("iconFieldChanged")]
    [Inspectable(category="Data")]

    /**
     *  Name of the field in the <code>dataProvider</code> object
     *  to display as the icon for each navigation item. 
     *
     *  @default "icon"
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get iconField():String
    {
        return _iconField;
    }

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

        // If we have a data provider, update here to
        // reflect new icon field.
        if (_dataProvider)
            dataProvider = _dataProvider;

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

    //----------------------------------
    //  labelField
    //----------------------------------

    /**
     *  @private
     *  Storage for the <code>labelField</code> property.
     */
    private var _labelField:String = "label";

    [Bindable("labelFieldChanged")]
    [Inspectable(category="Data")]

    /**
     *  Name of the field in the <code>dataProvider</code> object
     *  to display as the label for each navigation item. 
     *
     *  @default "label"
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get labelField():String
    {
        return _labelField;
    }

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

        // If we have a data provider, update here to
        // reflect new label field.
        if (_dataProvider)
            dataProvider = _dataProvider;

        dispatchEvent(new Event("labelFieldChanged"));
    }
    
 	//----------------------------------
    //  labelFunction
    //----------------------------------

    /**
     *  @private
     *  Storage for labelFunction property.
     */
    private var _labelFunction:Function;

    [Bindable("labelFunctionChanged")]
    [Inspectable(category="Data")]

    /**
     *  A user-supplied function to run on each item to determine its label.  
     *  By default, the component looks for a property named <code>label</code> 
     *  on each data provider item and displays it.
     *  However, some data sets do not have a <code>label</code> property
     *  nor do they have another property that can be used for displaying.
     *  An example is a data set that has lastName and firstName fields
     *  but you want to display full names.
     *
     *  <p>You can supply a <code>labelFunction</code> that finds the 
     *  appropriate fields and returns a displayable string. The 
     *  <code>labelFunction</code> is also good for handling formatting and 
     *  localization. </p>
     *
     *  <p>For most components, the label function takes a single argument
     *  which is the item in the data provider and returns a String.</p>
     *  <pre>
     *  myLabelFunction(item:Object):String</pre>
     *
     *
     *  @default null
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get labelFunction():Function
    {
        return _labelFunction;
    }

    /**
     *  @private
     */
    public function set labelFunction(value:Function):void
    {
        _labelFunction = value;

        // If we have a data provider, update here to
        // reflect new label function.
        if (_dataProvider)
            dataProvider = _dataProvider;

        dispatchEvent(new Event("labelFunctionChanged"));
    }
    
    //----------------------------------
    //  selectedIndex
    //----------------------------------

    /**
     *  @private
     *  Storage for the selectedIndex property.
     */
    private var _selectedIndex:int = -1;

    [Bindable("itemClick")]
    [Bindable("valueCommit")]
    [Inspectable(category="General", defaultValue="-1")]

    /**
     *  Index of the active navigation item,
     *  where the first item is at an index of 0.
     *
     *  @default -1
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get selectedIndex():int
    {
        return _selectedIndex;
    }

    /**
     *  @private
     */
    public function set selectedIndex(value:int):void
    {
        _selectedIndex = value;

        if (targetStack)
            targetStack.selectedIndex = value;

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

    //----------------------------------
    //  toolTipField
    //----------------------------------

    /**
     *  @private
     *  Storage for the toolTipField property.
     */
    private var _toolTipField:String = "toolTip";

    [Bindable("toolTipFieldChanged")]
    [Inspectable(category="Data")]

    /**
     *  Name of the the field in the <code>dataProvider</code> object
     *  to display as the tooltip label.
     *  
     *  @default "toolTip"
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get toolTipField():String
    {
        return _toolTipField;
    }

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

        // If we have a data provider, update here to
        // reflect new toolTip field.
        if (_dataProvider)
            dataProvider = _dataProvider;

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

    //--------------------------------------------------------------------------
    //
    //  Overridden methods: UIComponent
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    override protected function createChildren():void
    {
        super.createChildren();

        if (dataProviderChanged)
        {
            createNavChildren();
            dataProviderChanged = false;
        }
    }

    /**
     *  @private
     */
    override protected function commitProperties():void
    {
        super.commitProperties();

        if (!measurementHasBeenCalled)
        {
            checkPendingTargetStack();
            measurementHasBeenCalled = true;
        }

        if (dataProviderChanged)
        {
            dataProviderChanged = false;
            createNavChildren();
        }

        if (blocker)
            blocker.visible = false;
    }

    /**
     *  @private
     *  Always do a recursive notification since our content children may have us as
     *  the styleName.
     */
    override public function notifyStyleChangeInChildren(
                                styleProp:String, recursive:Boolean):void
    {
        super.notifyStyleChangeInChildren(styleProp, true);
    }

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

  	//--------------------------------------------------------------------------
    //
    //  Item fields
    //
    //--------------------------------------------------------------------------

   /**
     *  Returns the string the renderer would display for the given data object
     *  based on the labelField and labelFunction properties.
     *  If the method cannot convert the parameter to a string, it returns a
     *  single space.
     *
     *  @param data Object to be rendered.
     *
     *  @return The string to be displayed based on the data.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function itemToLabel(data:Object):String
    {
        if (data == null)
            return "";

        if (labelFunction != null)
            return labelFunction(data);

        if (data is XML)
        {
            try
            {
                if (data[labelField].length() != 0)
                    data = data[labelField];
                //by popular demand, this is a default XML labelField
                //else if (data.@label.length() != 0)
                //  data = data.@label;
            }
            catch(e:Error)
            {
            }
        }
        else if (data is Object)
        {
            try
            {
                if (data[labelField] != null)
                    data = data[labelField];
            }
            catch(e:Error)
            {
            }
        }

        if (data is String)
            return String(data);
		
		if (data is Number)
			return data.toString();
			
        return "";
    }

    /**
     *  Creates the individual navigator items.  
     * 
     *  By default, this method performs no action. 
     *  You can override this method in a 
     *  subclass to create a navigator item based on the type of 
     *  navigator items in your subclass.
     *
     *  @param label The label for the created navigator item. 
     *
     *  @param icon The icon for the created navigator item. 
     *  Typically, this is an icon that you have embedded in the application.
     *
     *  @return The created navigator item.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function createNavItem(label:String,
                                     icon:Class = null):IFlexDisplayObject
    {
        // Override to create a nav item.
        return null;
    }

    /**
     *  Highlights the selected navigator item. 
     * 
     *  By default, this method performs no action. 
     *  You can override this method in a subclass to 
     *  highlight the selected navigator item.
     *
     *  @param index The index of the selected item in the NavBar control.
     *  The first item is at an index of 0.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function hiliteSelectedNavItem(index:int):void
    {
        // Override to hilite selected item.
    }

    /**
     *  Resets the navigator bar to its default state.
     * 
     *  By default, this method performs no action. 
     *  You can override this method in a subclass to 
     *  reset the navigator bar to a default state.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function resetNavItems():void
    {
        // Override to reset nav items.
    }

    /**
     *  Sets the label property of a navigator item in the 
     *  NavBar control. 
     * 
     *  You can override this method in a subclass to 
     *  set the label of a navigator item based on the type of 
     *  navigator items in your subclass.
     *
     *  @param index The index of the navigator item in the NavBar control.
     *  The first navigator item is at an index of 0.
     *
     *  @param label The new label text for the navigator item. 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function updateNavItemLabel(index:int, label:String):void
    {
        // Override if your nav item doesn't derive from Button.
        var item:Button = Button(getChildAt(index));

        item.label = label;
    }

    /**
     *  Resets the icon of a navigator item in the 
     *  NavBar control. 
     * 
     *  You can override this method in a subclass to 
     *  set the icon of a navigator item based on the type of 
     *  navigator items in your subclass.
     *
     *  @param index The index of the navigator item in the NavBar control.
     *  The first navigator item is at an index of 0.
     *
     *  @param icon The new icon for the navigator item. 
     *  Typically, this is an icon that you have embedded in the application.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function updateNavItemIcon(index:int, icon:Class):void
    {
        // Override if your nav item doesn't derive from Button.
        var item:Button = Button(getChildAt(index));

        item.setStyle("icon", icon);
    }

    /**
     *  @private
     */
    private function createNavChildren():void
    {
        if (!_dataProvider)
            return;

        var n:int = _dataProvider.length;
        for (var i:int = 0; i < n; i++)
        {
            var item:Object = _dataProvider.getItemAt(i);
            var navItem:Button;
            if (item is String && labelFunction == null)
            {
                navItem = Button(createNavItem(String(item)));

                navItem.enabled = enabled;
            }
            else
            {
                var label:String = itemToLabel(item);
                // if labelField doesn't exist in item, label will be null;

                if (iconField != "")
                {
                    var iconValue:Object = null;

                    try
                    {
                        iconValue = item[iconField];
                    }
                    catch(e:Error)
                    {
                    }

                    // Workaround for bug 123651. Currently
                    // the MXML compiler passes the class name
                    // as a string instead of a Class reference.
                    var icon:Class =
                        iconValue is String ?
                        Class(systemManager.getDefinitionByName(
                                                String(iconValue))) :
                        Class(iconValue);

                    navItem = Button(createNavItem(label, icon));
                }
                else
                {
                    navItem = Button(createNavItem(label, null));
                }

                //Check for toolTip field and assign it to the individual button if it exists.
                if (_toolTipField != "" && item.hasOwnProperty(_toolTipField) == true)
                {
                    navItem.toolTip = String(item[_toolTipField]);
                }

                //Check for enabled field and assign it to the individual button if it exists.
                if (_enabledField != "" && item.hasOwnProperty(_enabledField) == true)
                {
                    navItem.enabled = Boolean(item[_enabledField]);
                }
                else
                {
                    navItem.enabled = enabled;
                }
            }

        }
        resetNavItems();
    }



    /**
     *  @private
     */
    private function setTargetViewStack(
                        newStack:Object /* can be String or ViewStack */):void
    {
        // If this property is set at creation time, the target view stack
        // may not exist yet. In this case, we just save off the requested
        // target stack and set it later.
        if (!measurementHasBeenCalled && newStack)
        {
            pendingTargetStack = newStack;
            invalidateProperties();
        }
        else
        {
            _setTargetViewStack(newStack);
        }
    }

    /**
     *  @private
     */
    private function _setTargetViewStack(
                        newStack:Object /* can be String or ViewStack */):void
    {
        var newTargetStack:ViewStack;

        if (newStack is ViewStack)
        {
            newTargetStack = ViewStack(newStack);
        }
        else if (newStack)
        {
            // newStack is not a ViewStack.
            // First, look for it on the current document
            newTargetStack = parentDocument[newStack];
        }
        else
        {
            newTargetStack = null;
        }

        // Remove any existing event listeners
        if (targetStack)
        {
            targetStack.removeEventListener(
                ChildExistenceChangedEvent.CHILD_ADD,
                childAddHandler);

            targetStack.removeEventListener(
                ChildExistenceChangedEvent.CHILD_REMOVE,
                childRemoveHandler);

            targetStack.removeEventListener(Event.CHANGE, changeHandler);
            targetStack.removeEventListener(FlexEvent.VALUE_COMMIT, changeHandler);

            targetStack.removeEventListener(
                IndexChangedEvent.CHILD_INDEX_CHANGE, childIndexChangeHandler);

            var numViews:int = targetStack.numChildren;
            var child:INavigatorContent;

            for (var i:int = 0; i < numViews; i++)
	        {
                child = INavigatorContent(targetStack.getChildAt(i));

                child.removeEventListener("labelChanged", labelChangedHandler);
                child.removeEventListener("iconChanged", iconChangedHandler);
                child.removeEventListener("enabledChanged", enabledChangedHandler);
                child.removeEventListener("toolTipChanged", toolTipChangedHandler);
            }
        }

        // Clear out the current links
        removeAllChildren();
        _selectedIndex = -1;

        targetStack = newTargetStack;

        if (!targetStack)
            return;

        targetStack.addEventListener(ChildExistenceChangedEvent.CHILD_ADD,
                                     childAddHandler);

        targetStack.addEventListener(ChildExistenceChangedEvent.CHILD_REMOVE,
                                     childRemoveHandler);

        targetStack.addEventListener(Event.CHANGE, changeHandler);
        targetStack.addEventListener(FlexEvent.VALUE_COMMIT, changeHandler);

        targetStack.addEventListener(IndexChangedEvent.CHILD_INDEX_CHANGE,
                                     childIndexChangeHandler);

        numViews = targetStack.numChildren;

        for (i = 0; i < numViews; i++)
        {
            child = INavigatorContent(targetStack.getChildAt(i));
            var item:Button = Button(createNavItem(itemToLabel(child), child.icon));

                 

            // Make the nav item inherit the tooltip from the child
            if (child.toolTip)
            {
                item.toolTip = child.toolTip;
                child.toolTip = null;
            }
            
            child.addEventListener("labelChanged", labelChangedHandler);
            child.addEventListener("iconChanged", iconChangedHandler);
            child.addEventListener("enabledChanged", enabledChangedHandler);
        	child.addEventListener("toolTipChanged", toolTipChangedHandler);      

            item.enabled = enabled && child.enabled;
        }

        var index:int = targetStack.selectedIndex;
        if (index == -1 && targetStack.numChildren > 0)
            index = 0;

        if (index != -1)
            hiliteSelectedNavItem(index);

        resetNavItems();
        invalidateDisplayList();
    }

    /**
     *  @private
     */
    private function checkPendingTargetStack():void
    {
        // Check for pending target view stacks.
        if (pendingTargetStack)
        {
            _setTargetViewStack(pendingTargetStack);
            pendingTargetStack = null;
        }
    }

    //--------------------------------------------------------------------------
    //
    //  Event handlers
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    private function collectionChangeHandler(event:Event):void
    {
        // Brute force -- rebuild everything...
        dataProvider = dataProvider;
    }

    /**
     *  @private
     */
    private function childAddHandler(event:ChildExistenceChangedEvent):void
    {
        // Prevent infinite recursion; the call to createNavItem() below
        // can cause this handler to get invoked due to event bubbling,
        // such as when a TabBar is inside a TabNavigator.
        if (event.target == this)
            return;

        // Bail if this isn't a child of the target stack.
        if (event.relatedObject.parent != targetStack)
            return;

        var newChild:INavigatorContent = INavigatorContent(event.relatedObject);
        var item:Button = Button(createNavItem(itemToLabel(newChild), newChild.icon));
        var index:int = newChild.parent.getChildIndex(DisplayObject(newChild));
        setChildIndex(item, index);

        if (newChild.toolTip)
        {
            item.toolTip = newChild.toolTip;
            newChild.toolTip = null;
        }

        newChild.addEventListener("labelChanged", labelChangedHandler);
        newChild.addEventListener("iconChanged", iconChangedHandler);
        newChild.addEventListener("enabledChanged", enabledChangedHandler);
        newChild.addEventListener("toolTipChanged", toolTipChangedHandler);
	
        item.enabled = enabled && newChild.enabled;
        callLater(resetNavItems);
    }

    /**
     *  @private
     */
    private function childRemoveHandler(event:ChildExistenceChangedEvent):void
    {
        // Prevent infinite recursion; the call to removeChildAt() below
        // can cause this handler to get invoked due to event bubbling,
        // such as when a TabBar is inside a TabNavigator.
        if (event.target == this)
            return;
        
        // Remove listeners for this child
        event.relatedObject.removeEventListener("labelChanged", labelChangedHandler);
        event.relatedObject.removeEventListener("iconChanged", iconChangedHandler);
        event.relatedObject.removeEventListener("enabledChanged", enabledChangedHandler);
        event.relatedObject.removeEventListener("toolTipChanged", toolTipChangedHandler); 

        var viewStack:ViewStack = ViewStack(event.target);
        removeChildAt(viewStack.getChildIndex(event.relatedObject));

        callLater(resetNavItems);
    }

    /**
     *  @private
     */
    private function changeHandler(event:Event):void
    {
        // Change events from text fields propagate, so we need to make sure
        // this event is coming from our dataProvider
        if (event.target == dataProvider)
            hiliteSelectedNavItem(Object(event.target).selectedIndex);
    }

    /**
     *  @private
     */
    private function childIndexChangeHandler(event:IndexChangedEvent):void
    {
        // Prevent infinite recursion; the call to setChildIndex() below
        // can cause this handler to get invoked due to event bubbling,
        // such as when a TabBar is inside a TabNavigator.
        if (event.target == this)
            return;

        setChildIndex(getChildAt(event.oldIndex), event.newIndex);
        resetNavItems();
    }

    /**
     *  @private
     */
    private function labelChangedHandler(event:Event):void
    {
        // Event.target is a child of the target view stack. Need to
        // convert to index
        var itemIndex:int =
            targetStack.getChildIndex(DisplayObject(event.target));

        updateNavItemLabel(itemIndex, INavigatorContent(event.target).label);
    }

    /**
     *  @private
     */
    private function iconChangedHandler(event:Event):void
    {
        // Event.target is a child of the target view stack. Need to
        // convert to index
        var itemIndex:int =
            targetStack.getChildIndex(DisplayObject(event.target));

        updateNavItemIcon(itemIndex, INavigatorContent(event.target).icon);
    }
    
    /**
     * @private
     */
    private function toolTipChangedHandler(event:Event):void
    {
    	// Event.target is a child of the target view stack. Need to
        // convert to index
        var itemIndex:int =
            targetStack.getChildIndex(DisplayObject(event.target));
        var item:UIComponent = UIComponent(getChildAt(itemIndex));
		
		if (UIComponent(event.target).toolTip)
		{
			item.toolTip = UIComponent(event.target).toolTip;
			lastToolTip = UIComponent(event.target).toolTip;
			UIComponent(event.target).toolTip = null;
		}
		else if (!lastToolTip)
		{
       		item.toolTip = UIComponent(event.target).toolTip;
       		lastToolTip = "placeholder";
        	UIComponent(event.target).toolTip = null;
  		}
  		else
  		 	lastToolTip = null;
    } 

    /**
     *  @private
     */
    private function enabledChangedHandler(event:Event):void
    {
        // Event.target is a child of the target view stack. Need to
        // convert to index
        var itemIndex:int =
            targetStack.getChildIndex(DisplayObject(event.target));

        Button(getChildAt(itemIndex)).enabled = enabled && event.target.enabled;
    }

    /**
     *  Handles the <code>MouseEvent.CLICK</code> event 
     *  for the items in the NavBar control. This handler
     *  dispatches the <code>itemClick</code> event for the NavBar control.
     *
     *  @param event The event object.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function clickHandler(event:MouseEvent):void
    {
        var index:int = getChildIndex(DisplayObject(event.currentTarget));
        if (targetStack)
            targetStack.selectedIndex = index;

        _selectedIndex = index;

        var newEvent:ItemClickEvent =
            new ItemClickEvent(ItemClickEvent.ITEM_CLICK);
        newEvent.label = Button(event.currentTarget).label;
        newEvent.index = index;
        newEvent.relatedObject = InteractiveObject(event.currentTarget);
        newEvent.item = _dataProvider ?
                        _dataProvider.getItemAt(index) :
                        null;
        dispatchEvent(newEvent);
    
        event.stopImmediatePropagation();
    }

}

}
