////////////////////////////////////////////////////////////////////////////////
//
//  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.events.Event;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.text.TextLineMetrics;
import flash.ui.Keyboard;

import mx.collections.ArrayCollection;
import mx.collections.CursorBookmark;
import mx.controls.dataGridClasses.DataGridListData;
import mx.controls.listClasses.BaseListData;
import mx.controls.listClasses.IDropInListItemRenderer;
import mx.controls.listClasses.IListItemRenderer;
import mx.controls.listClasses.ListBase;
import mx.controls.listClasses.ListData;
import mx.core.ClassFactory;
import mx.core.EdgeMetrics;
import mx.core.IDataRenderer;
import mx.core.IFactory;
import mx.core.LayoutDirection;
import mx.core.ScrollPolicy;
import mx.core.UIComponent;
import mx.core.UIComponentGlobals;
import mx.core.mx_internal;
import mx.effects.Tween;
import mx.events.CollectionEvent;
import mx.events.CollectionEventKind;
import mx.events.DropdownEvent;
import mx.events.FlexEvent;
import mx.events.FlexMouseEvent;
import mx.events.InterManagerRequest;
import mx.events.ListEvent;
import mx.events.SandboxMouseEvent;
import mx.events.ScrollEvent;
import mx.events.ScrollEventDetail;
import mx.managers.ISystemManager;
import mx.managers.PopUpManager;
import mx.styles.CSSStyleDeclaration;
import mx.utils.MatrixUtil;

use namespace mx_internal;

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

/**
 *  Dispatched when the ComboBox contents changes as a result of user
 *  interaction, when the <code>selectedIndex</code> or
 *  <code>selectedItem</code> property changes, and, if the ComboBox control
 *  is editable, each time a keystroke is entered in the box.
 *
 *  @eventType mx.events.ListEvent.CHANGE
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="change", type="mx.events.ListEvent")]

/**
 *  Dispatched when the drop-down list is dismissed for any reason such when 
 *  the user:
 *  <ul>
 *      <li>selects an item in the drop-down list</li>
 *      <li>clicks outside of the drop-down list</li>
 *      <li>clicks the drop-down button while the drop-down list is 
 *  displayed</li>
 *      <li>presses the ESC key while the drop-down list is displayed</li>
 *  </ul>
 *
 *  @eventType mx.events.DropdownEvent.CLOSE
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="close", type="mx.events.DropdownEvent")]

/**
 *  Dispatched when the <code>data</code> property changes.
 *
 *  <p>When you use a component as an item renderer,
 *  the <code>data</code> property contains an item from the
 *  dataProvider.
 *  You can listen for this event and update the component
 *  when the <code>data</code> property changes.</p>
 * 
 *  @eventType mx.events.FlexEvent.DATA_CHANGE
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="dataChange", type="mx.events.FlexEvent")]

/**
 *  Dispatched if the <code>editable</code> property
 *  is set to <code>true</code> and the user presses the Enter key
 *  while typing in the editable text field.
 *
 *  @eventType mx.events.FlexEvent.ENTER
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="enter", type="mx.events.FlexEvent")]

/**
 *  Dispatched when user rolls the mouse out of a drop-down list item.
 *  The event object's <code>target</code> property contains a reference
 *  to the ComboBox and not the drop-down list.
 *
 *  @eventType mx.events.ListEvent.ITEM_ROLL_OUT
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="itemRollOut", type="mx.events.ListEvent")]

/**
 *  Dispatched when the user rolls the mouse over a drop-down list item.
 *  The event object's <code>target</code> property contains a reference
 *  to the ComboBox and not the drop-down list.
 *
 *  @eventType mx.events.ListEvent.ITEM_ROLL_OVER
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="itemRollOver", type="mx.events.ListEvent")]

/**
 *  Dispatched when the user clicks the drop-down button
 *  to display the drop-down list.  It is also dispatched if the user
 *  uses the keyboard and types Ctrl-Down to open the drop-down.
 *
 *  @eventType mx.events.DropdownEvent.OPEN
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="open", type="mx.events.DropdownEvent")]

/**
 *  Dispatched when the user scrolls the ComboBox control's drop-down list.
 *
 *  @eventType mx.events.ScrollEvent.SCROLL
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="scroll", type="mx.events.ScrollEvent")]

//--------------------------------------
//  Styles
//--------------------------------------

include "../styles/metadata/FocusStyles.as"
include "../styles/metadata/IconColorStyles.as"
include "../styles/metadata/LeadingStyle.as"
include "../styles/metadata/PaddingStyles.as"
include "../styles/metadata/SkinStyles.as"
include "../styles/metadata/TextStyles.as"

/**
 *  The set of BackgroundColors for drop-down list rows in an alternating
 *  pattern.
 *  Value can be an Array of two of more colors.
 *  If <code>undefined</code> then the rows will use the drop-down list's 
 *  backgroundColor style.
 *
 *  @default undefined
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="alternatingItemColors", type="Array", arrayType="uint", format="Color", inherit="yes")]

/**
 *  Width of the arrow button in pixels.
 *  
 *  The default value for the Halo theme is 22.
 *  The default value for the Spark theme is 18.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="arrowButtonWidth", type="Number", format="Length", inherit="no")]

/**
 *  The thickness of the border of the drop-down list, in pixels. 
 *  This value is overridden if you define 
 *  <code>borderThickness</code> when setting the 
 *  <code>dropdownStyleName</code> CSSStyleDeclaration. 
 *
 *  @default 1
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="borderThickness", type="Number", format="Length", inherit="no")]

/**
 *  The length of the transition when the drop-down list closes, in milliseconds.
 *  The default transition has the drop-down slide up into the ComboBox.
 *
 *  The default value for the Halo theme is 250.
 *  The default value for the Spark theme is 50.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="closeDuration", type="Number", format="Time", inherit="no")]

/**
 *  An easing function to control the close transition.  Easing functions can
 *  be used to control the acceleration and deceleration of the transition.
 *
 *  @default undefined
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="closeEasingFunction", type="Function", inherit="no")]

/**
 *  The color of the border of the ComboBox.  If <code>undefined</code>
 *  the drop-down list will use its normal borderColor style.  This style
 *  is used by the validators to show the ComboBox in an error state.
 * 
 *  @default undefined
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="dropdownBorderColor", type="uint", format="Color", inherit="yes", theme="halo")]

/**
 *  The name of a CSSStyleDeclaration to be used by the drop-down list.  This
 *  allows you to control the appearance of the drop-down list or its item
 *  renderers.
 * 
 *  [deprecated]
 *
 *  @default "comboDropDown"
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="dropDownStyleName", type="String", inherit="no", deprecatedReplacement="dropdownStyleName")]

/**
 *  The name of a CSSStyleDeclaration to be used by the drop-down list.  This
 *  allows you to control the appearance of the drop-down list or its item
 *  renderers.
 *
 *  @default "comboDropdown"
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="dropdownStyleName", type="String", inherit="no")]

/**
 *  Length of the transition when the drop-down list opens, in milliseconds.
 *  The default transition has the drop-down slide down from the ComboBox.
 *
 *  The default value for the Halo theme is 250.
 *  The default value for the Spark theme is 0.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="openDuration", type="Number", format="Time", inherit="no")]

/**
 *  An easing function to control the open transition.  Easing functions can
 *  be used to control the acceleration and deceleration of the transition.
 *
 *  @default undefined
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="openEasingFunction", type="Function", inherit="no")]

/**
 *  Number of pixels between the control's bottom border
 *  and the bottom of its content area.
 *  When the <code>editable</code> property is <code>true</code>, 
 *  <code>paddingTop</code> and <code>paddingBottom</code> affect the size 
 *  of the ComboBox control, but do not affect the position of the editable text field.
 *  
 *  The default value for the Halo theme is 0.
 *  The default value for the Spark theme is -2.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="paddingBottom", type="Number", format="Length", inherit="no")]

/**
 *  Number of pixels between the control's top border
 *  and the top of its content area.
 *  When the <code>editable</code> property is <code>true</code>, 
 *  <code>paddingTop</code> and <code>paddingBottom</code> affect the size 
 *  of the ComboBox control, but do not affect the position of the editable text field.
 *  
 *  The default value for the Halo theme is 0.
 *  The default value for the Spark theme is -1.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="paddingTop", type="Number", format="Length", inherit="no")]

/**
 *  The rollOverColor of the drop-down list.
 *  
 *  The default value for the Halo theme is <code>0xB2E1FF</code>.
 *  The default value for the Spark theme is <code>0xCEDBEF</code>.
 * 
 *  @see mx.controls.List
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="rollOverColor", type="uint", format="Color", inherit="yes")]

/**
 *  The selectionColor of the drop-down list.
 *  
 *  The default value for the Halo theme is <code>0x7FCEFF</code>.
 *  The default value for the Spark theme is <code>0xA8C6EE</code>.
 * 
 *  @see mx.controls.List
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="selectionColor", type="uint", format="Color", inherit="yes")]

/**
 *  The selectionDuration of the drop-down list.
 * 
 *  @default 250
 * 
 *  @see mx.controls.List
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="selectionDuration", type="uint", format="Time", inherit="no")]

/**
 *  The selectionEasingFunction of the drop-down list.
 * 
 *  @default undefined
 * 
 *  @see mx.controls.List
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="selectionEasingFunction", type="Function", inherit="no")]

/**
 *  The textRollOverColor of the drop-down list.
 * 
 *  The default value for the Halo theme is <code>0x2B333C</code>.
 *  The default value for the Spark theme is <code>0x000000</code>.
 *  
 *  @see mx.controls.List
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="textRollOverColor", type="uint", format="Color", inherit="yes")]

/**
 *  The textSelectedColor of the drop-down list.
 * 
 *  The default value for the Halo theme is <code>0x2B333C</code>.
 *  The default value for the Spark theme is <code>0x000000</code>.
 * 
 *  @see mx.controls.List
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="textSelectedColor", type="uint", format="Color", inherit="yes")]

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

[AccessibilityClass(implementation="mx.accessibility.ComboBoxAccImpl")]

[DataBindingInfo("acceptedTypes", "{ dataProvider: { label: &quot;String&quot; } }")]

[DefaultBindingProperty(source="selectedItem", destination="dataProvider")]

[DefaultProperty("dataProvider")]

[DefaultTriggerEvent("change")]

[IconFile("ComboBox.png")]

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

/**
 *  The ComboBox control contains a drop-down list
 *  from which the user can select a single value.
 *  Its functionality is very similar to that of the
 *  SELECT form element in HTML.
 *  The ComboBox can be editable, in which case
 *  the user can type entries into the TextInput portion
 *  of the ComboBox that are not in the list.
 *
 *  <p>The ComboBox control has the following default sizing 
 *     characteristics:</p>
 *     <table class="innertable">
 *        <tr>
 *           <th>Characteristic</th>
 *           <th>Description</th>
 *        </tr>
 *        <tr>
 *           <td>Default size</td>
 *           <td>Wide enough to accommodate the longest entry in the 
 *               drop-down list in the display area of the main
 *               control, plus the drop-down button. When the 
 *               drop-down list is not visible, the default height 
 *               is based on the label text size. 
 *
 *               <p>The default drop-down list height is five rows, or 
 *               the number of entries in the drop-down list, whichever 
 *               is smaller. The default height of each entry in the 
 *               drop-down list is 22 pixels.</p></td>
 *        </tr>
 *        <tr>
 *           <td>Minimum size</td>
 *           <td>0 pixels.</td>
 *        </tr>
 *        <tr>
 *           <td>Maximum size</td>
 *           <td>5000 by 5000.</td>
 *        </tr>
 *        <tr>
 *           <td>dropdownWidth</td>
 *           <td>The width of the ComboBox control.</td>
 *        </tr>
 *        <tr>
 *           <td>rowCount</td>
 *           <td>5 rows.</td>
 *        </tr>
 *     </table>
 *
 *  @mxml
 *
 *  <p>The <code>&lt;mx:ComboBox&gt;</code> tag inherits all the tag attributes
 *  of its superclass, and adds the following tag attributes:</p>
 *
 *  <pre>
 *  &lt;mx:ComboBox
 *    <b>Properties</b>
 *    dataProvider="null"
 *    dropdownFactory="<i>ClassFactory that creates an mx.controls.List</i>"
 *    dropdownWidth="<i>100 or width of the longest text in the dataProvider</i>"
 *    itemRenderer="null"
 *    labelField="label"
 *    labelFunction="null"
 *    prompt="null"
 *    rowCount="5"
 *    selectedIndex="-1"
 *    selectedItem="null"
 *    
 *    <b>Styles</b>
 *    alternatingItemColors="undefined"
 *    arrowButtonWidth="22"
 *    borderColor="0xB7BABC"
 *    borderThickness="1"
 *    closeDuration="250"
 *    closeEasingFunction="undefined"
 *    color="0x0B333C"
 *    cornerRadius="0"
 *    disabledColor="0xAAB3B3"
 *    disabledIconColor="0x919999"
 *    dropdownBorderColor="undefined"
 *    dropdownStyleName="comboDropdown"
 *    fillAlphas="[0.6,0.4]"
 *    fillColors="[0xFFFFFF, 0xCCCCCC]"
 *    focusAlpha="0.4"
 *    focusRoundedCorners="tl tr bl br"
 *    fontAntiAliasType="advanced|normal"
 *    fontFamily="Verdana"
 *    fontGridFitType="pixel|none|subpixel"
 *    fontSharpness="0"
 *    fontSize="10"
 *    fontStyle="normal|italic"
 *    fontThickness="0"
 *    fontWeight="normal|bold"
 *    highlightAlphas="[0.3,0.0]"
 *    iconColor="0x111111"
 *    leading="0"
 *    openDuration="250"
 *    openEasingFunction="undefined"
 *    paddingTop="0"
 *    paddingBottom="0"
 *    paddingLeft="5"
 *    paddingRight="5"
 *    rollOverColor="<i>Depends on theme color"</i>
 *    selectionColor="<i>Depends on theme color"</i>
 *    selectionDuration="250"
 *    selectionEasingFunction="undefined"
 *    textAlign="left|center|right"
 *    textDecoration="none|underline"
 *    textIndent="0"
 *    textRollOverColor="0x2B333C"
 *    textSelectedColor="0x2B333C"
 *    
 *    <b>Events</b>
 *    change="<i>No default</i>"
 *    close="<i>No default</i>"
 *    dataChange="<i>No default</i>"
 *    enter="<i>No default</i>"
 *    itemRollOut="<i>No default</i>"
 *    itemRollOver="<i>No default</i>"
 *    open="<i>No default</i>"
 *    scroll="<i>No default</i>"
 *  /&gt;
 *  </pre>
 *
 *  @includeExample examples/SimpleComboBox.mxml
 *
 *  @see mx.controls.List
 *  @see mx.effects.Tween
 *  @see mx.managers.PopUpManager
 *
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class ComboBox extends ComboBase
                      implements IDataRenderer, IDropInListItemRenderer,
                      IListItemRenderer
{
    include "../core/Version.as";

    //--------------------------------------------------------------------------
    //
    //  Class mixins
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  Placeholder for mixin by ComboBoxAccImpl.
     */
    mx_internal static var createAccessibilityImplementation:Function;

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

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

        // It it better to start out with an empty data provider rather than
        // an undefined one. Otherwise, code in getDropdown() sets it to []
        // later, but via setDataProvider(). This API has side effects like
        // setting selectionChanged, which causes the text in an editable
        // ComboBox to be lost.
        dataProvider = new ArrayCollection();

        useFullDropdownSkin = true;
        wrapDownArrowButton = false;
        addEventListener("unload", unloadHandler);
        addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
    }

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

    /**
     *  @private
     *  A reference to the internal List that pops up to display a row
     *  for each dataProvider item.
     */
    private var _dropdown:ListBase;

    /**
     *  @private
     *  A int to track the oldIndex, used when the dropdown is dismissed using the ESC key.
     */
    private var _oldIndex:int;

    /**
     *  @private
     *  The tween used for showing and hiding the drop-down list.
     */
    private var tween:Tween = null;
    
    /**
     *  @private
     *  A flag to track whether the dropDown tweened up or down. 
     */
    private var tweenUp:Boolean = false;
    

    /**
     *  @private
     */
    private var preferredDropdownWidth:Number;

    /**
     *  @private
     */
    private var dropdownBorderStyle:String = "solid";

    /**
     *  @private
     *  Is the dropdown list currently shown?
     */
    private var _showingDropdown:Boolean = false;

    /**
     *  @private
     */
    private var _selectedIndexOnDropdown:int = -1;

    /**
     *  @private
     */
    private var bRemoveDropdown:Boolean = true;

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

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

    /**
     *  @private
     *  Flag that will block default data/listData behavior
     */
    private var selectedItemSet:Boolean;

    /**
     *  @private
     *  Event that is causing the dropDown to open or close.
     */
    private var triggerEvent:Event;

    /**
     *  @private
     *  Whether the text property was explicitly set or not
     */
    private var explicitText:Boolean;

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

    //----------------------------------
    //  data
    //----------------------------------

    /**
     *  @private
     *  Storage for the data property.
     */
    private var _data:Object;

    [Bindable("dataChange")]
    [Inspectable(environment="none")]

    /**
     *  The <code>data</code> property lets you pass a value
     *  to the component when you use it in an item renderer or item editor.
     *  You typically use data binding to bind a field of the <code>data</code>
     *  property to a property of this component.
     *
     *  <p>The ComboBox control uses the <code>listData</code> property and the
     *  <code>data</code> property as follows. If the ComboBox is in a 
     *  DataGrid control, it expects the <code>dataField</code> property of the 
     *  column to map to a property in the data and sets 
     *  <code>selectedItem</code> to that property. If the ComboBox control is 
     *  in a List control, it expects the <code>labelField</code> of the list 
     *  to map to a property in the data and sets <code>selectedItem</code> to 
     *  that property. 
     *  Otherwise, it sets <code>selectedItem</code> to the data itself.</p>
     *
     *  <p>You do not set this property in MXML.</p>
     *
     *  @see mx.core.IDataRenderer
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get data():Object
    {
        return _data;
    }

    /**
     *  @private
     */
    public function set data(value:Object):void
    {
        var newSelectedItem:*;

        _data = value;

        if (_listData && _listData is DataGridListData)
            newSelectedItem = _data[DataGridListData(_listData).dataField];
        else if (_listData is ListData && ListData(_listData).labelField in _data)
            newSelectedItem = _data[ListData(_listData).labelField];
        else
            newSelectedItem = _data;

        if (newSelectedItem !== undefined && !selectedItemSet)
        {
            selectedItem = newSelectedItem;
            selectedItemSet = false;
        }

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

    //----------------------------------
    //  listData
    //----------------------------------

    /**
     *  @private
     *  Storage for the listData property.
     */
    private var _listData:BaseListData;

    [Bindable("dataChange")]
    [Inspectable(environment="none")]

    /**
     *  When a component is used as a drop-in item renderer or drop-in item 
     *  editor, Flex initializes the <code>listData</code> property of the 
     *  component with the appropriate data from the List control. The 
     *  component can then use the <code>listData</code> property and the 
     *  <code>data</code> property to display the appropriate information 
     *  as a drop-in item renderer or drop-in item editor.
     *
     *  <p>You do not set this property in MXML or ActionScript; Flex sets it 
     *  when the component
     *  is used as a drop-in item renderer or drop-in item editor.</p>
     *
     *  @see mx.controls.listClasses.IDropInListItemRenderer
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get listData():BaseListData
    {
        return _listData;
    }

    /**
     *  @private
     */
    public function set listData(value:BaseListData):void
    {
        _listData = value;
    }

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

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

    [Bindable("collectionChange")]
    [Inspectable(category="Data", arrayType="Object")]

    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    override public function set dataProvider(value:Object):void
    {
        selectionChanged = true;

        super.dataProvider = value;
        
        destroyDropdown();

        invalidateProperties();
        invalidateSize();
    }

    //----------------------------------
    //  itemRenderer
    //----------------------------------

    /**
     *  @private
     *  Storage for itemRenderer property.
     */
    private var _itemRenderer:IFactory;

    [Inspectable(category="Data")]

    /**
     *  IFactory that generates the instances that displays the data for the
     *  drop-down list of the control.  You can use this property to specify 
     *  a custom item renderer for the drop-down list.
     *
     *  <p>The control uses a List control internally to create the drop-down
     *  list.
     *  The default item renderer for the List control is the ListItemRenderer
     *  class, which draws the text associated with each item in the list, 
     *  and an optional icon. </p>
     *
     *  @see mx.controls.List
     *  @see mx.controls.listClasses.ListItemRenderer
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get itemRenderer():IFactory
    {
        return _itemRenderer;
    }

    /**
     *  @private
     */
    public function set itemRenderer(value:IFactory):void
    {
        _itemRenderer = value;

        if (_dropdown)
            _dropdown.itemRenderer = value;

        invalidateSize();
        invalidateDisplayList();

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

    //----------------------------------
    //  selectedIndex
    //----------------------------------

    [Bindable("change")]
    [Bindable("collectionChange")]
    [Bindable("valueCommit")]
    [Inspectable(category="General", defaultValue="0")]

    /**
     *  Index of the selected item in the drop-down list.
     *  Setting this property sets the current index and displays
     *  the associated label in the TextInput portion.
     *  <p>The default value is -1, but it set to 0
     *  when a <code>dataProvider</code> is assigned, unless there is a prompt.
     *  If the control is editable, and the user types in the TextInput portion,
     *  the value of the <code>selectedIndex</code> property becomes 
     *  -1. If the value of the <code>selectedIndex</code> 
     *  property is out of range, the <code>selectedIndex</code> property is set to the last
     *  item in the <code>dataProvider</code>.</p>
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    override public function set selectedIndex(value:int):void
    {
        super.selectedIndex = value;

        if (value >= 0)
            selectionChanged = true;
            
        implicitSelectedIndex = false;
        invalidateDisplayList();

        // value committed event needs the text to be set
        if (textInput && !textChanged && value >= 0)
            textInput.text = selectedLabel;
        else if (textInput && prompt)
            textInput.text = prompt;

        // [Matt] setting the text of the textInput should take care of this now
        // Send a valueCommit event, which is used by the data model
        //dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT));
    }

    //----------------------------------
    //  selectedItem
    //----------------------------------

    [Bindable("change")]
    [Bindable("collectionChange")]
    [Bindable("valueCommit")]

    /**
     *  Contains a reference to the selected item in the
     *  <code>dataProvider</code>.
     *  If the data is an object or class instance, modifying
     *  properties in the object or instance modifies the <code>dataProvider</code>
     *  and thus its views.  Setting the selectedItem itself causes the
     *  ComboBox to select that item (display it in the TextInput portion and set
     *  the selectedIndex) if it exists in the dataProvider.
     *  <p>If the ComboBox control is editable, the <code>selectedItem</code>
     *  property is <code>null</code> if the user types any text
     *  into the TextInput.
     *  It has a value only if the user selects an item from the drop-down
     *  list, or if it is set programmatically.</p>
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    override public function set selectedItem(value:Object):void
    {
        selectedItemSet = true;
        
        // We do not want to apply an implicit default index in this case.
        implicitSelectedIndex = false;
        
        super.selectedItem = value;
    }

    //----------------------------------
    //  showInAutomationHierarchy
    //----------------------------------

    /**
     *  @private
     */
    override public function set showInAutomationHierarchy(value:Boolean):void
    {
        //do not allow value changes
    }

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

    //----------------------------------
    //  dropdown
    //----------------------------------

    /**
     *  A reference to the List control that acts as the drop-down in the ComboBox.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get dropdown():ListBase
    {
        return getDropdown();
    }

    //----------------------------------
    //  dropdownFactory
    //----------------------------------

    /**
     *  @private
     *  Storage for the dropdownFactory property.
     */
    private var _dropdownFactory:IFactory = new ClassFactory(List);

    [Bindable("dropdownFactoryChanged")]

    /**
     *  The IFactory that creates a ListBase-derived instance to use
     *  as the drop-down.
     *  The default value is an IFactory for List
     *
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get dropdownFactory():IFactory
    {
        return _dropdownFactory;
    }

    /**
     *  @private
     */
    public function set dropdownFactory(value:IFactory):void
    {
        _dropdownFactory = value;

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

    //----------------------------------
    //  dropDownStyleFilters
    //----------------------------------

    /**
     *  The set of styles to pass from the ComboBox to the dropDown.
     *  Styles in the dropDownStyleName style will override these styles.
     *  @see mx.styles.StyleProxy
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function get dropDownStyleFilters():Object
    {
        return null;
    }

    //----------------------------------
    //  dropdownWidth
    //----------------------------------

    /**
     *  @private
     *  Storage for the dropdownWidth property.
     */
    private var _dropdownWidth:Number = 100;

    [Bindable("dropdownWidthChanged")]
    [Inspectable(category="Size", defaultValue="100")]

    /**
     *  Width of the drop-down list, in pixels.
     *  <p>The default value is 100 or the width of the longest text
     *  in the <code>dataProvider</code>, whichever is greater.</p>
     *
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get dropdownWidth():Number
    {
        return _dropdownWidth;
    }

    /**
     *  @private
     */
    public function set dropdownWidth(value:Number):void
    {
        _dropdownWidth = value;

        preferredDropdownWidth = value;

        if (_dropdown)
            _dropdown.setActualSize(value, _dropdown.height);

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

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

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

    /**
     *  @private
     */
    private var labelFieldChanged:Boolean;

    [Bindable("labelFieldChanged")]
    [Inspectable(category="Data", defaultValue="label")]

    /**
     *  Name of the field in the items in the <code>dataProvider</code>
     *  Array to display as the label in the TextInput portion and drop-down list.
     *  By default, the control uses a property named <code>label</code>
     *  on each Array object and displays it.
     *  <p>However, if the <code>dataProvider</code> items do not contain
     *  a <code>label</code> property, you can set the <code>labelField</code>
     *  property to use a different property.</p>
     *
     *  
     *  @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;
        labelFieldChanged = true;

        invalidateDisplayList();

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

    //----------------------------------
    //  labelFunction
    //----------------------------------

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

    /**
     *  @private
     */
    private var labelFunctionChanged:Boolean;

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

    /**
     *  User-supplied function to run on each item to determine its label.
     *  By default the control uses a property named <code>label</code>
     *  on each <code>dataProvider</code> item to determine its label.
     *  However, some data sets do not have a <code>label</code> property,
     *  or do not have another property that can be used for displaying
     *  as a label.
     *  <p>An example is a data set that has <code>lastName</code> and
     *  <code>firstName</code> fields but you want to display full names.
     *  You use <code>labelFunction</code> to specify a callback function
     *  that uses the appropriate fields and return a displayable String.</p>
     *
     *  <p>The labelFunction takes a single argument which is the item
     *  in the dataProvider and returns a String:</p>
     *  <pre>
     *  myLabelFunction(item:Object):String
     *  </pre>
     *
     *  
     *  @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;
        labelFunctionChanged = true;

        invalidateDisplayList();

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

    //----------------------------------
    //  prompt
    //----------------------------------

    private var promptChanged:Boolean = false;

    /**
     *  @private
     *  Storage for the prompt property.
     */
    private var _prompt:String;

    [Inspectable(category="General")]

    /**
     *  The prompt for the ComboBox control. A prompt is
     *  a String that is displayed in the TextInput portion of the
     *  ComboBox when <code>selectedIndex</code> = -1.  It is usually
     *  a String like "Select one...".  If there is no
     *  prompt, the ComboBox control sets <code>selectedIndex</code> to 0
     *  and displays the first item in the <code>dataProvider</code>.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get prompt():String
    {
        return _prompt;
    }

    /**
     *  @private
     */
    public function set prompt(value:String):void
    {
        _prompt = value;
        promptChanged = true;
        invalidateProperties();
    }

    //----------------------------------
    //  rowCount
    //----------------------------------

    /**
     *  @private
     *  Storage for the rowCount property.
     */
    private var _rowCount:int = 5;

    [Bindable("resize")]
    [Inspectable(category="General", defaultValue="5")]

    /**
     *  Maximum number of rows visible in the ComboBox control list.
     *  If there are fewer items in the
     *  dataProvider, the ComboBox shows only as many items as
     *  there are in the dataProvider.
     *  
     *  @default 5
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get rowCount():int
    {
        return Math.max(1, Math.min(collection.length, _rowCount));
    }

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

        if (_dropdown)
            _dropdown.rowCount = value;
    }

    //----------------------------------
    //  selectedLabel
    //----------------------------------

    /**
     *  The String displayed in the TextInput portion of the ComboBox. It
     *  is calculated from the data by using the <code>labelField</code> 
     *  or <code>labelFunction</code>.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get selectedLabel():String
    {
        return itemToLabel(selectedItem);
    }

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

    /**
     *  @private
     */
    override protected function initializeAccessibility():void
    {
        if (ComboBox.createAccessibilityImplementation != null)
            ComboBox.createAccessibilityImplementation(this);
    }

    /**
     *  @private
     */
    override public function styleChanged(styleProp:String):void
    {
        destroyDropdown();

        super.styleChanged(styleProp);
    }

    /**
     *  Makes sure the control is at least 40 pixels wide,
     *  and tall enough to fit one line of text
     *  in the TextInput portion of the control but at least
     *  22 pixels high.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    override protected function measure():void
    {
        super.measure();

        // Make sure we're not too small
        measuredMinWidth = Math.max(measuredWidth, DEFAULT_MEASURED_MIN_WIDTH);

        // Make sure we're tall enough to hold our text.
        // Text field height is text height + 4 pixels top/bottom
        var textHeight:Number = measureText("M").height + 6;
        var bm:EdgeMetrics = borderMetrics;
        measuredMinHeight = measuredHeight =
            Math.max(textHeight + bm.top + bm.bottom, DEFAULT_MEASURED_MIN_HEIGHT);
        measuredMinHeight = measuredHeight += getStyle("paddingTop") + getStyle("paddingBottom");
    }

    /**
     *  @private
     *  Make sure the drop-down width is the same as the rest of the ComboBox
     */
    override protected function updateDisplayList(unscaledWidth:Number,
                                                  unscaledHeight:Number):void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);

        // we toss the dropdown when resized
        // except if we're opening the dropdown
        // then we assume the updateDisplayList() call is spurious
        // and will not affect the dropdown size
        if (_dropdown && !inTween)
        {
            // We will not destroy our dropdown if user is actively
            // interacting with it, this has been legacy behavior since
            // Flex 3.0.
            if (!_showingDropdown)
                destroyDropdown();
        }
        else if (_showingDropdown)
        {
            bRemoveDropdown = false;
        }

        var ddw:Number = preferredDropdownWidth;
        if (isNaN(ddw))
            ddw = _dropdownWidth = unscaledWidth;

        if (labelFieldChanged)
        {
            if (_dropdown)
                _dropdown.labelField = _labelField;

            selectionChanged = true;
            if (!explicitText) 
                textInput.text = selectedLabel;
            labelFieldChanged = false;
        }

        if (labelFunctionChanged)
        {
            selectionChanged = true;
            if (!explicitText)
                textInput.text = selectedLabel;
            labelFunctionChanged = false;
        }

        if (selectionChanged)
        {
            if (!textChanged)
            {
                if (selectedIndex == -1 && prompt)
                    textInput.text = prompt;
                else if (!explicitText)
                    textInput.text = selectedLabel;
            }

            textInput.invalidateDisplayList();
            textInput.validateNow();

            if (editable)
            {
                textInput.selectRange(0, textInput.text.length);
                textInput.horizontalScrollPosition = 0;
            }

            if (_dropdown)
                _dropdown.selectedIndex = selectedIndex;

            selectionChanged = false;
        }

        // We might need to decrease the number of rows.
        if (_dropdown && _dropdown.rowCount != rowCount)
            _dropdown.rowCount = rowCount;
    }

    /**
     *  @private
     */
    override protected function commitProperties():void
    {
        explicitText = textChanged;

        super.commitProperties();

        if (collectionChanged)
        {
            if (selectedIndex == -1 && implicitSelectedIndex && _prompt == null)
                selectedIndex = 0;
            selectedIndexChanged = true;
            collectionChanged = false;
        }
        if (promptChanged && prompt != null && selectedIndex == -1)
        {
            promptChanged = false;
            textInput.text = prompt;
        }
    }

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

    /**
     *  Returns a string representing the <code>item</code> parameter.
     *  
     *  <p>This method checks in the following order to find a value to return:</p>
     *  
     *  <ol>
     *    <li>If you have specified a <code>labelFunction</code> property,
     *  returns the result of passing the item to the function.</li>
     *    <li>If the item is a String, Number, Boolean, or Function, returns
     *  the item.</li>
     *    <li>If the item has a property with the name specified by the control's
     *  <code>labelField</code> property, returns the contents of the property.</li>
     *    <li>If the item has a label property, returns its value.</li>
     *  </ol>
     * 
     *  @param item The object that contains the value to convert to a label. 
     *  If the item is null, this method returns the empty string.
     *
     *  @return A string representing the <code>item</code> parameter.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function itemToLabel(item:Object, ...rest):String
    {
        // rest args are needed in case dropdown is some other thing like DataGrid
        // that has multiple arguments to labelFunction

        // we need to check for null explicitly otherwise
        // a numeric zero will not get properly converted to a string.
        // (do not use !item)
        if (item == null)
            return "";

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

        if (typeof(item) == "object")
        {
            try
            {
                if (item[labelField] != null)
                    item = item[labelField];
            }
            catch(e:Error)
            {
            }
        }
        else if (typeof(item) == "xml")
        {
            try
            {
                if (item[labelField].length() != 0)
                    item = item[labelField];
            }
            catch(e:Error)
            {
            }
        }

        if (typeof(item) == "string")
            return String(item);

        try
        {
            return item.toString();
        }
        catch(e:Error)
        {
        }

        return " ";
    }

    /**
     *  Displays the drop-down list.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function open():void
    {
        displayDropdown(true);
    }

    /**
     *  Hides the drop-down list.
     *
     *  @param trigger The event to dispatch when the 
     *  drop-down list closes.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function close(trigger:Event = null):void
    {
        if (_showingDropdown)
        {
            if (_dropdown && selectedIndex != _dropdown.selectedIndex)
                selectedIndex = _dropdown.selectedIndex;

            displayDropdown(false, trigger);

            dispatchChangeEvent(new Event("dummy"),
                    _selectedIndexOnDropdown,
                    selectedIndex);
        }
    }

    /**
     *  @private
     */
    mx_internal function hasDropdown():Boolean
    {
        return _dropdown != null;
    }

    /**
     *  @private
     */
    private function getDropdown():ListBase
    {
        if (!initialized)
            return null;

        if (!hasDropdown())
        {
            var dropDownStyleName:String = getStyle("dropDownStyleName");
            if (dropDownStyleName == null ) 
                dropDownStyleName = getStyle("dropdownStyleName");
            

            _dropdown = dropdownFactory.newInstance();
            _dropdown.visible = false;
            _dropdown.focusEnabled = false;
            _dropdown.owner = this;

            if (itemRenderer)
                _dropdown.itemRenderer = itemRenderer;

            if (dropDownStyleName)
                _dropdown.styleName = dropDownStyleName;

            PopUpManager.addPopUp(_dropdown, this);

            // Don't display a tween when the selection changes.
            // The dropdown menu is about to appear anyway,
            // and other processing can make the tween look choppy.
            _dropdown.setStyle("selectionDuration", 0);

            // Set up a data provider in case one doesn't yet exist,
            // so we can share it with the dropdown listbox.
            if (!dataProvider)
                dataProvider = new ArrayCollection();

            _dropdown.dataProvider = dataProvider;
            _dropdown.rowCount = rowCount;
            _dropdown.width = _dropdownWidth;
            _dropdown.selectedIndex = selectedIndex;
            _oldIndex = selectedIndex;
            _dropdown.verticalScrollPolicy = ScrollPolicy.AUTO;
            _dropdown.labelField = _labelField;
            _dropdown.labelFunction = itemToLabel;
            _dropdown.allowDragSelection = true;

            _dropdown.addEventListener("change", dropdown_changeHandler);
            _dropdown.addEventListener(ScrollEvent.SCROLL, dropdown_scrollHandler);
            _dropdown.addEventListener(ListEvent.ITEM_ROLL_OVER, dropdown_itemRollOverHandler);
            _dropdown.addEventListener(ListEvent.ITEM_ROLL_OUT, dropdown_itemRollOutHandler);
            
            // the drop down should close if the user clicks on any item.
            // add a handler to detect a click in the list
            _dropdown.addEventListener(ListEvent.ITEM_CLICK, dropdown_itemClickHandler);

            UIComponentGlobals.layoutManager.validateClient(_dropdown, true);
            _dropdown.setActualSize(_dropdownWidth, _dropdown.getExplicitOrMeasuredHeight());
            _dropdown.validateDisplayList();

            _dropdown.cacheAsBitmap = true;

            // weak reference to stage
            systemManager.addEventListener(Event.RESIZE, stage_resizeHandler, false, 0, true);
        }
        
        
        var m:Matrix = MatrixUtil.getConcatenatedMatrix(this, systemManager.getSandboxRoot());
        _dropdown.scaleX = m.a; //scale x
        _dropdown.scaleY = m.d; //scale y
        
        return _dropdown;
    }

    /**
     *  @private
     */
    private function displayDropdown(show:Boolean, trigger:Event = null, playEffect:Boolean = true):void
    {
        if (!initialized || show == _showingDropdown)
            return;

        if (inTween && tween)
            tween.endTween();

        // Subclasses may extend to do pre-processing
        // before the dropdown is displayed
        // or override to implement special display behavior

        // Show or hide the dropdown
        var initY:Number;
        var endY:Number;
        var duration:Number;
        var easingFunction:Function;

        var point:Point = new Point(0, unscaledHeight);
        point = localToGlobal(point);
        
        var sm:ISystemManager = systemManager.topLevelSystemManager;
        var screen:Rectangle = sm.getVisibleApplicationRect(null, true);

        //opening the dropdown 
        if (show)
        {
            // Store the selectedIndex temporarily so we can tell
            // if the value changed when the dropdown is closed
            _selectedIndexOnDropdown = selectedIndex;

            getDropdown();

            _dropdown.addEventListener(FlexMouseEvent.MOUSE_DOWN_OUTSIDE, dropdown_mouseOutsideHandler);
            _dropdown.addEventListener(FlexMouseEvent.MOUSE_WHEEL_OUTSIDE, dropdown_mouseOutsideHandler);
            _dropdown.addEventListener(SandboxMouseEvent.MOUSE_DOWN_SOMEWHERE, dropdown_mouseOutsideHandler);
            _dropdown.addEventListener(SandboxMouseEvent.MOUSE_WHEEL_SOMEWHERE, dropdown_mouseOutsideHandler);
            
            if (_dropdown.parent == null)  // was popped up then closed
                PopUpManager.addPopUp(_dropdown, this);
            else
                PopUpManager.bringToFront(_dropdown);

            // if we donot have enough space in the bottom display the dropdown
            // at the top. But if the space there is also less than required
            // display it below.
            if (point.y + _dropdown.height > screen.bottom &&
                point.y > screen.top + _dropdown.height)
            {
                // Dropdown will go below the bottom of the stage
                // and be clipped. Instead, have it grow up.
                point.y -= (unscaledHeight + _dropdown.height);
                initY = -_dropdown.height;
                tweenUp = true;
            }
            else
            {
                initY = _dropdown.height;
                tweenUp = false;
            }
        
            point = _dropdown.parent.globalToLocal(point);
            
            // If the combobox's layout is mirrored then the the dropdown's 
            // will be too.  That also means that (stage coordinate) point.x is 
            // currently the right edge of the dropdown.  Fix that:
            if (layoutDirection == LayoutDirection.RTL)
                point.x -= _dropdown.width;

            var sel:int = _dropdown.selectedIndex;
            if (sel == -1)
                sel = 0;
            var pos:Number = _dropdown.verticalScrollPosition;

            // try to set the verticalScrollPosition one above the selected index so
            // it looks better when the dropdown is displayed
            pos = sel - 1;
            pos = Math.min(Math.max(pos, 0), _dropdown.maxVerticalScrollPosition);
            _dropdown.verticalScrollPosition = pos;

            if (_dropdown.x != point.x || _dropdown.y != point.y)
                _dropdown.move(point.x, point.y);

            _dropdown.scrollRect = new Rectangle(0, initY,
                    _dropdown.width, _dropdown.height);

            if (!_dropdown.visible)
                _dropdown.visible = true;

            // Make sure we don't remove the dropdown at the end of the tween
            bRemoveDropdown = false;
            
            // Set up the tween and relevant variables. 
            _showingDropdown = show;
            duration = getStyle("openDuration");
            endY = 0;
            easingFunction = getStyle("openEasingFunction") as Function;
        }
        
        // closing the dropdown 
        else if (_dropdown)
        {
            // Set up the tween and relevant variables. 
            endY = (point.y + _dropdown.height > screen.bottom || tweenUp
                               ? -_dropdown.height
                               : _dropdown.height);
            _showingDropdown = show;
            initY = 0;
            duration = getStyle("closeDuration");
            easingFunction = getStyle("closeEasingFunction") as Function;
            
            _dropdown.resetDragScrolling();
        }
        
        inTween = true;
        // only force validation if we're about to show
        // or closing with effect.  Otherwise, if the iterator
        // is out of sync in the dropdown, we'll get an RTE
        // when closing
        if (playEffect || show) 
            UIComponentGlobals.layoutManager.validateNow();
        
        // Block all layout, responses from web service, and other background
        // processing until the tween finishes executing.
        UIComponent.suspendBackgroundProcessing();
        
        // Disable the dropdown during the tween.
        if (_dropdown)
            _dropdown.enabled = false;
        
        duration = Math.max(1, duration);
        if (!playEffect) 
            duration = 1;
        tween = new Tween(this, initY, endY, duration);
        
        if (easingFunction != null && tween)
            tween.easingFunction = easingFunction;
            
        triggerEvent = trigger;
    }

    /**
     *  @private
     */
    private function dispatchChangeEvent(oldEvent:Event, prevValue:int,
                                         newValue:int):void
    {
        if (prevValue != newValue)
        {
            var newEvent:Event = oldEvent is ListEvent ?
                                 oldEvent :
                                 new ListEvent("change");

            dispatchEvent(newEvent);
        }
    }

    /**
     *  @private
     */
    private function destroyDropdown():void
    {
        if (inTween && tween)
            tween.endTween();
        
        displayDropdown(false, null, false);
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden event handlers
    //
    //--------------------------------------------------------------------------
    private var implicitSelectedIndex:Boolean = false;
    /**
     *  @private
     */
    override protected function collectionChangeHandler(event:Event):void
    {
        // Save a copy of the selectedIndex
        var curSelectedIndex:int = selectedIndex;

        super.collectionChangeHandler(event);

        if (event is CollectionEvent)
        {
            // trace("ListBase collectionEvent");
            var ce:CollectionEvent = CollectionEvent(event);

            if (collection.length == 0)
            {
                // Special case: Empty dataProvider.
                if (!selectedIndexChanged && !selectedItemChanged)
                {
                    if (super.selectedIndex != -1)
                        super.selectedIndex = -1;
                    implicitSelectedIndex = true;
                    invalidateDisplayList();
                }
                // if the combobox is non-editable remove the text
                // we don't want to remove the text if it is editable as user might
                // have typed something.
                if (textInput && !editable)
                    textInput.text = "";
            }

            else if (ce.kind == CollectionEventKind.ADD)
            {
                if (collection.length == ce.items.length)
                {
                    // Special case: Adding the first item(s). Select item 0
                    // if there is no prompt
                    if (selectedIndex == -1 && _prompt == null)
                        selectedIndex = 0;
                }
                else
                {
                    // we dont want to destroy the dropdown just
                    // because data got added.  Especially true
                    // for paged data.
                    return;
                }
            }

            else if (ce.kind == CollectionEventKind.UPDATE)
            {
                if (ce.location == selectedIndex ||
                    ce.items[0].source == selectedItem)
                    // unsorted lists don't have a valid location
                    // Force an update of the text input
                    selectionChanged = true;
            }

            else if (ce.kind == CollectionEventKind.REPLACE)
            {
                // bail on a replace, no need to change anything,
                // especially for paged data
                return;
            }

            else if (ce.kind == CollectionEventKind.RESET)
            {
                collectionChanged = true;
                if (!selectedIndexChanged && !selectedItemChanged)
                    selectedIndex = prompt ? -1 : 0;
                invalidateProperties();
            }

            invalidateDisplayList();

            destroyDropdown();
        }
    }

    /**
     *  @private
     */
    override protected function textInput_changeHandler(event:Event):void
    {
        super.textInput_changeHandler(event);

        // Force a change event to be dispatched
        dispatchChangeEvent(event, -1, -2);
    }

    /**
     *  @private
     */
    override protected function downArrowButton_buttonDownHandler(
                                    event:FlexEvent):void
    {
        // The down arrow should always toggle the visibility of the dropdown.
        if (_showingDropdown)
        {
            close(event);
        }
        else
        {
            displayDropdown(true, event);
        }
    }

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

    /**
     *  @private
     */
    private function dropdown_mouseOutsideHandler(event:Event):void
    {
        // trace("dropdown_mouseOutsideHandler: " + event);
        
        if (event is MouseEvent)
        {
            var mouseEvent:MouseEvent = MouseEvent(event);
            if (mouseEvent.target != _dropdown)
                // the dropdown's items can dispatch a mouseDownOutside
                // event which then bubbles up to us
                return;
    
            if (!hitTestPoint(mouseEvent.stageX, mouseEvent.stageY, true))
            {
                close(event);
            }
        }
        else if (event is SandboxMouseEvent) 
        {
            close(event);
        }
    }

    /**
     *  @private
     */
    private function dropdown_itemClickHandler(event:ListEvent):void
    {
        if (_showingDropdown)
        {
            close();
        }
    }

    /**
     *  @private
     */
    override protected function focusOutHandler(event:FocusEvent):void
    {
        // Note: event.relatedObject is the object getting focus.
        // It can be null in some cases, such as when you open
        // the dropdown and then click outside the application.

        // If the dropdown is open...
        if (_showingDropdown && _dropdown &&
            this.contains(DisplayObject(event.target)))
        {
            // If focus is moving outside the dropdown...
            if (!event.relatedObject ||
                !_dropdown.contains(event.relatedObject))
            {
                // Close the dropdown.
                close();
            }
        }

        super.focusOutHandler(event);
    }

    private function stage_resizeHandler(event:Event):void
    {
        destroyDropdown();
    }

    /**
     *  @private
     */
    private function dropdown_scrollHandler(event:Event):void
    {
        // TextField.scroll bubbles so you might see it here
        if (event is ScrollEvent)
        {
            var se:ScrollEvent = ScrollEvent(event);
            if (se.detail == ScrollEventDetail.THUMB_TRACK ||
                    se.detail == ScrollEventDetail.THUMB_POSITION ||
                    se.detail == ScrollEventDetail.LINE_UP ||
                    se.detail == ScrollEventDetail.LINE_DOWN)
                dispatchEvent(se);
        }
    }

    /**
     *  @private
     */
    private function dropdown_itemRollOverHandler(event:Event):void
    {
        dispatchEvent(event);
    }

    /**
     *  @private
     */
    private function dropdown_itemRollOutHandler(event:Event):void
    {
        dispatchEvent(event);
    }

    /**
     *  @private
     */
    private function dropdown_changeHandler(event:Event):void
    {
        var prevValue:int = selectedIndex;

        // This assignment will also assign the label to the text field.
        // See setSelectedIndex().
        if (_dropdown)
            selectedIndex = _dropdown.selectedIndex;

        // If this was generated by the dropdown as a result of a keystroke, it is
        // likely a Page-Up or Page-Down, or Arrow-Up or Arrow-Down.
        // If the selection changes due to a keystroke,
        // we leave the dropdown displayed.
        // If it changes as a result of a mouse selection,
        // we close the dropdown.
        if (!_showingDropdown)
            dispatchChangeEvent(event, prevValue, selectedIndex);
        else if (!bInKeyDown)
        {
            // this will also send a change event if needed
            close();
        }
    }

    /**
     *  @private
     */
    override protected function keyDownHandler(event:KeyboardEvent):void
    {
        // If the combo box is disabled, don't do anything
        if (!enabled)
            return;
            
        // If a the editable field currently has focus, it is handling
        // all arrow keys. We shouldn't also scroll this selection.
        if (event.target == textInput)
            return;

        if (event.ctrlKey && event.keyCode == Keyboard.DOWN)
        {
            displayDropdown(true, event);
            event.stopPropagation();
        }
        else if (event.ctrlKey && event.keyCode == Keyboard.UP)
        {
            close(event);
            event.stopPropagation();
        }
        else if (event.keyCode == Keyboard.ESCAPE)
        {
            if (_showingDropdown)
            {
                if (_oldIndex != _dropdown.selectedIndex)
                    selectedIndex = _oldIndex;

                displayDropdown(false);
                event.stopPropagation();
            }
        }

        else if (event.keyCode == Keyboard.ENTER)
        {
            if (_showingDropdown)
            {
                close();
                event.stopPropagation();
            }
        }
        else
        {
            if (!editable ||
                event.keyCode == Keyboard.UP ||
                event.keyCode == Keyboard.DOWN ||
                event.keyCode == Keyboard.PAGE_UP ||
                event.keyCode == Keyboard.PAGE_DOWN)
            {
                var oldIndex:int = selectedIndex;

                // Make sure we know we are handling a keyDown,
                // so if the dropdown sends out a "change" event
                // (like when an up-arrow or down-arrow changes
                // the selection) we know not to close the dropdown.
                bInKeyDown = _showingDropdown;
                // Redispatch the event to the dropdown
                // and let its keyDownHandler() handle it.

                dropdown.dispatchEvent(event.clone());
                event.stopPropagation();
                bInKeyDown = false;

            }
        }
    }

    /**
     *  @private
     *  This acts as the destructor.
     */
    private function unloadHandler(event:Event):void
    {
        if (inTween)
        {
            UIComponent.resumeBackgroundProcessing();
            inTween = false;
        }

        if (_dropdown)
            _dropdown.parent.removeChild(_dropdown);
    }
    
    /**
     *  @private
     */
    private function removedFromStageHandler(event:Event):void
    {
        // Ensure we've unregistered ourselves from PopupManager, else
        // we'll be leaked.
        destroyDropdown();
    }

    //--------------------------------------------------------------------------
    //
    // Tween handlers
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    mx_internal function onTweenUpdate(value:Number):void
    {
        if (_dropdown)
        {
            _dropdown.scrollRect = new Rectangle(0, value,
                _dropdown.width, _dropdown.height);
        }
    }

    /**
     *  @private
     */
    mx_internal function onTweenEnd(value:Number):void
    {
        if (_dropdown)
        {
            // Clear the scrollRect here. This way if drop shadows are
            // assigned to the dropdown they show up correctly
            _dropdown.scrollRect = null;

            inTween = false;
            _dropdown.enabled = true;
            _dropdown.visible = _showingDropdown;
            
            if (bRemoveDropdown)
            {
                _dropdown.removeEventListener(FlexMouseEvent.MOUSE_DOWN_OUTSIDE, dropdown_mouseOutsideHandler);
                _dropdown.removeEventListener(FlexMouseEvent.MOUSE_WHEEL_OUTSIDE, dropdown_mouseOutsideHandler);
                _dropdown.removeEventListener(SandboxMouseEvent.MOUSE_DOWN_SOMEWHERE, dropdown_mouseOutsideHandler);
                _dropdown.removeEventListener(SandboxMouseEvent.MOUSE_WHEEL_SOMEWHERE, dropdown_mouseOutsideHandler);
                
                PopUpManager.removePopUp(_dropdown);
                _dropdown = null;
            }
        }
        
        bRemoveDropdown = true;
        
        UIComponent.resumeBackgroundProcessing();
        var cbdEvent:DropdownEvent =
            new DropdownEvent(_showingDropdown ? DropdownEvent.OPEN : DropdownEvent.CLOSE);
        cbdEvent.triggerEvent = triggerEvent;
        dispatchEvent(cbdEvent);
    }

    /**
     *  Determines default values of the height and width to use for each 
     *  entry in the drop-down list, based on the maximum size of the label 
     *  text in the first <code>numItems</code> items in the data provider. 
     *
     *  @param count The number of items to check to determine the value.
     *  
     *  @return An Object containing two properties: width and height.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    override protected function calculatePreferredSizeFromData(count:int):Object
    {
        var maxW:Number = 0;
        var maxH:Number = 0;

        var bookmark:CursorBookmark = iterator ? iterator.bookmark : null;
        
        iterator.seek(CursorBookmark.FIRST, 0);
        
        var more:Boolean = iterator != null;
        
        var lineMetrics:TextLineMetrics;

        for (var i:int = 0; i < count; i++)
        {
            var data:Object;
            if (more)
                data = iterator ? iterator.current : null;
            else
                data = null;

            var txt:String = itemToLabel(data);

            lineMetrics = measureText(txt);

            maxW = Math.max(maxW, lineMetrics.width);
            maxH = Math.max(maxH, lineMetrics.height);
            
            if (iterator)
                iterator.moveNext();
        }

        if (prompt)
        {
            lineMetrics = measureText(prompt);

            maxW = Math.max(maxW, lineMetrics.width);
            maxH = Math.max(maxH, lineMetrics.height);
        }

        maxW += getStyle("paddingLeft") + getStyle("paddingRight");

        if (iterator)
            iterator.seek(bookmark, 0);

        return { width: maxW, height: maxH };
    }

    /**
     *  @private
     */
    mx_internal function get isShowingDropdown():Boolean
    {
        return _showingDropdown;
    }


}

}
