////////////////////////////////////////////////////////////////////////////////
//
//  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.Graphics;
import flash.events.Event;
import flash.geom.Rectangle;
import flash.text.StyleSheet;
import flash.text.TextFormat;
import flash.text.TextLineMetrics;
import mx.controls.listClasses.BaseListData;
import mx.controls.listClasses.IDropInListItemRenderer;
import mx.controls.listClasses.IListItemRenderer;
import mx.core.IDataRenderer;
import mx.core.IFlexModuleFactory;
import mx.core.IFontContextComponent;
import mx.core.IUITextField;
import mx.core.UIComponent;
import mx.core.UITextField;
import mx.core.mx_internal;
import mx.events.FlexEvent;

use namespace mx_internal;

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

/**
 *  Dispatched when the <code>data</code> property changes.
 *
 *  <p>When you use a component as an item renderer,
 *  the <code>data</code> property contains the data to display.
 *  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 when a user clicks a hyperlink in an 
 *  HTML-enabled text field, where the URL begins with <code>"event:"</code>. 
 *  The remainder of the URL after 
 *  <code>"event:"</code> is placed in the text property of the <code>link</code> event object.
 *
 *  <p>When you handle the <code>link</code> event, the hyperlink is not automatically executed; 
 *  you need to execute the hyperlink from within your event handler. 
 *  You typically use the <code>navigateToURL()</code> method to execute the hyperlink.
 *  This allows you to modify the hyperlink, or even prohibit it from occurring, 
 *  in your application. </p>
 *
 *  <p>The Label control must have the <code>selectable</code> property set 
 *  to <code>true</code> to generate the <code>link</code> event.</p>
 *
 *  @eventType flash.events.TextEvent.LINK
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="link", type="flash.events.TextEvent")]

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

include "../styles/metadata/TextStyles.as"

/**
 *  Number of pixels between the left of the Label and 
 *  the left of the text. 
 *  
 *  @default 0
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="paddingLeft", type="Number", format="Length", inherit="no")]

/**
 *  Number of pixels between the right of the Label and 
 *  the right of the text. 
 *  
 *  @default 0
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="paddingRight", type="Number", format="Length", inherit="no")]

/**
 *  Number of pixels between the bottom of the Label and 
 *  the bottom of the text. 
 *  
 *  The default value for the Halo theme is <code>2</code>.
 *  The default value for the Spark theme is <code>-1</code>.
 *  
 *  @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 top of the Label and 
 *  the top of the text. 
 *  
 *  The default value for the Halo theme is <code>2</code>.
 *  The default value for the Spark theme is <code>-1</code>.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="paddingTop", type="Number", format="Length", inherit="no")]

/**
 *  Color of the Label object's opaque background.
 *  The default value is <code>undefined</code>,
 *  which means that the background is transparent.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
//[Style(name="backgroundColor", type="uint", format="Color", inherit="no")]

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

[Exclude(name="focusEnabled", kind="property")]
[Exclude(name="focusPane", kind="property")]
[Exclude(name="mouseFocusEnabled", kind="property")]
[Exclude(name="tabEnabled", kind="property")]
[Exclude(name="chromeColor", kind="style")]
[Exclude(name="focusBlendMode", kind="style")]
[Exclude(name="focusSkin", kind="style")]
[Exclude(name="focusThickness", kind="style")]
[Exclude(name="themeColor", kind="style")]
[Exclude(name="setFocus", kind="method")]

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

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

[DefaultBindingProperty(destination="text")]

[IconFile("Label.png")]

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

/**
 *  The Label control displays a single line of noneditable text.
 *  Use the Text control to create blocks of multiline
 *  noneditable text.
 *
 *  <p>You can format Label text by using HTML tags,
 *  which are applied after the Label control's CSS styles are applied.
 *  You can also put padding around the four sides of the text.
 *  The text of a Label is nonselectable by default,
 *  but you can make it selectable.</p>
 *
 *  <p>If a Label is sized to be smaller than its text,
 *  you can control whether the text is simply clipped or whether
 *  it is truncated with a localizable string such as "...".
 *  (Note: Plain text can be truncated, but HTML text cannot.)
 *  If the entire text of the Label, either plain or HTML, 
 *  is not completely visible, and you haven't assigned a tooltip
 *  to the Label, an automatic "truncation tip" 
 *  displays the complete plain text when a user holds the mouse over the Label control.</p>
 *
 *  <p>Label controls do not have backgrounds or borders
 *  and cannot take focus.</p>
 *
 *  <p>The Label 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>Width and height large enough for the text</td>
 *        </tr>
 *        <tr>
 *           <td>Minimum size</td>
 *           <td>0 pixels</td>
 *        </tr>
 *        <tr>
 *           <td>Maximum size</td>
 *           <td>10000 by 10000 pixels</td>
 *        </tr>
 *     </table>
 *
 *  @mxml
 *
 *  <p>The <code>&lt;mx:Label&gt;</code> tag inherits all of the tag attributes
 *  of its superclass, and adds the following tag attributes:</p>
 *
 *  <pre>
 *  &lt;mx:Label
 *    <b>Properties</b>
 *    condenseWhite="true|false"
 *    data="null"
 *    htmlText=""
 *    listData="null"
 *    selectable="true|false"
 *    text=""
 *    truncateToFit="true|false"
 *    &nbsp;
 *    <b>Styles</b>
 *    color="0x0B333C"
 *    disabledColor="0xAAB3B3"
 *    fontAntiAliasType="advanced|normal"
 *    fontFamily="Verdana"
 *    fontGridFitType="pixel|none|subpixel"
 *    fontSharpness="0"
 *    fontSize="10"
 *    fontStyle="normal|italic"
 *    fontThickness="0"
 *    fontWeight="normal|bold"
 *    paddingLeft="0"
 *    paddingRight="0"
 *    paddingTop="0"
 *    paddingBottom="0"
 *    styleSheet="null"
 *    textAlign="left|right|center"
 *    textDecoration="none|underline"
 *    textIndent="0"
 *    &nbsp;
 *    <b>Events</b>
 *    dataChange="<i>No default</i>"
 *  /&gt;
 *  </pre>
 *
 *  @includeExample examples/LabelExample.mxml
 *
 *  @see mx.controls.Text
 *  @see mx.controls.TextInput
 *  @see mx.controls.TextArea
 *  @see mx.controls.RichTextEditor
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class Label extends UIComponent
                   implements IDataRenderer, IDropInListItemRenderer,
                   IListItemRenderer, IFontContextComponent
                   
{
    include "../core/Version.as";

    //--------------------------------------------------------------------------
    //
    //  Implementation notes
    //
    //--------------------------------------------------------------------------

    /*
        A Label has a single internal child, a UITextField which displays
        the Label's text or htmlText (whichever was last set).

        See the implementation notes for UITextField to understand
        more about how a Flash TextField works.

        The 'text' and 'htmlText' properties of Label work somewhat
        differently from those of a native TextField.

        Because Flex uses invalidation, setting either 'text' or 'htmlText'
        does very little work; the setter only sets a storage var and some
        flags and dispatches an event to trigger bindings to update.

        In fact, the setters are so fast that calling them in a loop
        does not create a performance problem.
        For example, if you have a Text component (which is a subclass of
        Label intended for displaying multiple lines of text) you can
        write code like myTextComponent.text += moreStuff[i] inside a
        loop. 

        However, the Flex invalidation approach means that the 'text' and
        'htmlText' properties are not coupled as immediately as with
        a TextField.

        If you set the 'text' of a Label, you can immediately get it back,
        but if you immediately get the 'htmlText' it will be null,
        indicating that it is invalid and will be calculated
        the next time the LayoutManager runs.
        Similarly, if you set the 'htmlText' of a Label, you can immediately
        get back exactly what you set, but the 'text' will be null,
        again an indication that it is invalid and will be calculated
        the next time the LayoutManager runs.

        Later, when the LayoutManager runs to re-validate the Label,
        either the 'text' or the 'htmlText' that you set -- whichever one
        was set last -- will be pushed down into the TextField.
        After that happens, the Label's 'text' and 'htmlText' properties
        will be the same as those of the TextFields; the 'text' and the
        'htmlText' will be in sync with each other, but they will no
        longer necessarily be what you set.

        If you need to force the LayoutManager to run immediately,
        you can call validateNow() on the Label.

        Here are some examples of how these interactions work:

        myLabel.htmlText = "This is <b>bold</b>."
        trace(myLabel.htmlText);
            This is <b>bold</b>.
        trace(myLabel.text);
            null
        myLabel.validateNow();
        trace(myLabel.htmlText);
            <TEXTFORMAT LEADING="2">
            <P ALIGN="LEFT">
            <FONT FACE="Verdana" SIZE="10" COLOR="#0B333C"
                  LETTERSPACING="0" KERNING="0">
            This is <B>bold</B>.
            </FONT>
            </P>
            </TEXTFORMAT>
        trace(myLabel.text);
            This is bold.
    */

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

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

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

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

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

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

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

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

    /**
     *  @private
     *  The baselinePosition of a Label is calculated for its textField.
     */
    override public function get baselinePosition():Number
    {
        if (!validateBaselinePosition())
            return NaN;
        
        return textField.y + textField.baselinePosition;
    }

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

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

    [Inspectable(category="General")]

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

        super.enabled = value;
        enabledChanged = true;

        invalidateProperties();
    }

    //----------------------------------
    //  textField
    //----------------------------------

    /**
     *  The internal UITextField that renders the text of this Label.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected var textField:IUITextField;

    //----------------------------------
    //  toolTip
    //----------------------------------

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

    /**
     *  @private
     */
    override public function set toolTip(value:String):void
    {
        super.toolTip = value;

        toolTipSet = value != null;
    }

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

    //----------------------------------
    //  condenseWhite
    //----------------------------------

    /**
     *  @private
     *  Storage for the condenseWhite property.
     */
    private var _condenseWhite:Boolean = false;

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

    [Bindable("condenseWhiteChanged")]
    [Inspectable(category="General", defaultValue="false")]
    
    /**
     *  Specifies whether extra white space (spaces, line breaks,
     *  and so on) should be removed in a Label control with HTML text.
     *
     *  <p>The <code>condenseWhite</code> property affects only text set with
     *  the <code>htmlText</code> property, not the <code>text</code> property.
     *  If you set text with the <code>text</code> property,
     *  <code>condenseWhite</code> is ignored.</p>
     *
     *  <p>If you set the <code>condenseWhite</code> property to <code>true</code>,
     *  you must use standard HTML commands, such as <code>&lt;br&gt;</code>
     *  and <code>&lt;p&gt;</code>, to place line breaks in the text field.</p>
     *
     *  @default false;
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get condenseWhite():Boolean
    {
        return _condenseWhite;
    }

    /**
     *  @private
     */
    public function set condenseWhite(value:Boolean):void
    {
        if (value == _condenseWhite)
            return;

        _condenseWhite = value;
        condenseWhiteChanged = true;
        
        // Changing the condenseWhite property needs to trigger
        // the same response as changing the htmlText property
        // if this Label is displaying HTML.
        if (isHTML)
            htmlTextChanged = true;

        invalidateProperties();
        invalidateSize();
        invalidateDisplayList();

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

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

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

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

    /**
     *  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>When you use the control as a drop-in item renderer or drop-in
     *  item editor, Flex automatically writes the current value of the item
     *  to the <code>text</code> property of this control.</p>
     *
     *  <p>You do not set this property in MXML.</p>
     *
     *  @default null
     *  @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 newText:*;

        _data = value;

        if (_listData)
        {
            newText = _listData.label;
        }
        else if (_data != null)
        {
            if (_data is String)
                newText = String(_data);
            else
                newText = _data.toString();
        }

        if (newText !== undefined && !textSet)
        {
            text = newText;
            textSet = false;
        }

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

    //----------------------------------
    //  fontContext
    //----------------------------------
    
    /**
     *  @inheritDoc 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get fontContext():IFlexModuleFactory
    {
        return moduleFactory;
    }

    /**
     *  @private
     */
    public function set fontContext(moduleFactory:IFlexModuleFactory):void
    {
        this.moduleFactory = moduleFactory;
    }
    
    //----------------------------------
    //  htmlText
    //----------------------------------

    /**
     *  @private
     *  Storage for the htmlText property.
     *  In addition to being set in the htmlText setter,
     *  it is automatically updated at two other times.
     *  1. When the 'text' or 'htmlText' is pushed down into
     *  the textField in commitProperties(), this causes
     *  the textField to update its own 'htmlText'.
     *  Therefore in commitProperties() we reset this storage var
     *  to be in sync with the textField.
     *  2. When the TextFormat of the textField changes
     *  because a CSS style has changed (see validateNow()
     *  in UITextField), the textField also updates its own 'htmlText'.
     *  Therefore in textField_textFieldStyleChangeHandler()
     */
    private var _htmlText:String = "";

    /**
     *  @private
     */
    mx_internal var htmlTextChanged:Boolean = false;
    
    /**
     *  @private
     *  The last value of htmlText that was set.
     *  We have to keep track of this because when you set the htmlText
     *  of a TextField and read it back, you don't get what you set.
     *  In general it will have additional HTML markup corresponding
     *  to the defaultTextFormat set from the CSS styles.
     *  If this var is null, it means that 'text' rather than 'htmlText'
     *  was last set.
     */
    private var explicitHTMLText:String = null; 

    [Bindable("htmlTextChanged")]
    [CollapseWhiteSpace]
    [Inspectable(category="General", defaultValue="")]

    /**
     *  Specifies the text displayed by the Label control, including HTML markup that
     *  expresses the styles of that text. 
     *  When you specify HTML text in this property, you can use the subset of HTML 
     *  tags that is supported by the Flash TextField control.
     * 
     *  <p>When you set this property, the HTML markup is applied
     *  after the CSS styles for the Label instance are applied.
     *  When you get this property, the HTML markup includes
     *  the CSS styles.</p>
     *  
     *  <p>For example, if you set this to be a string such as,
     *  <code>"This is an example of &lt;b&gt;bold&lt;/b&gt; markup"</code>,
     *  the text "This is an example of <b>bold</b> markup" appears
     *  in the Label with whatever CSS styles normally apply.
     *  Also, the word "bold" appears in boldface font because of the
     *  <code>&lt;b&gt;</code> markup.</p>
     *
     *  <p>HTML markup uses characters such as &lt; and &gt;,
     *  which have special meaning in XML (and therefore in MXML). So,  
     *  code such as the following does not compile:</p>
     *  
     *  <pre>
     *  &lt;mx:Label htmlText="This is an example of &lt;b&gt;bold&lt;/b&gt; markup"/&gt;
     *  </pre>
     *  
     *  <p>There are three ways around this problem.</p>
     *  
     *  <ul>
     *  
     *  <li>
     *  
     *  <p>Set the <code>htmlText</code> property in an ActionScript method called as 
     *  an <code>initialize</code> handler:</p>
     *  
     *  <pre>
     *  &lt;mx:Label id="myLabel" initialize="myLabel_initialize()"/&gt;
     *  </pre>
     *  
     *  <p>where the <code>myLabel_initialize</code> method is in a script CDATA section:</p>
     *  
     *  <pre>
     *  &lt;fx:Script&gt;
     *  &lt;![CDATA[
     *  private function myLabel_initialize():void {
     *      myLabel.htmlText = "This is an example of &lt;b&gt;bold&lt;/b&gt; markup";
     *  }
     *  ]]&gt;
     *  &lt;/fx:Script&gt;
     *  
     *  </pre>
     *  
     *  <p>This is the simplest approach because the HTML markup
     *  remains easily readable.
     *  Notice that you must assign an <code>id</code> to the label
     *  so you can refer to it in the <code>initialize</code>
     *  handler.</p>
     *  
     *  </li>
     *  
     *  <li>
     *  
     *  <p>Specify the <code>htmlText</code> property by using a child tag
     *  with a CDATA section. A CDATA section in XML contains character data
     *  where characters like &lt; and &gt; aren't given a special meaning.</p>
     *  
     *  <pre>
     *  &lt;mx:Label&gt;
     *      &lt;mx:htmlText&gt;&lt;![CDATA[This is an example of &lt;b&gt;bold&lt;/b&gt; markup]]&gt;&lt;/mx:htmlText&gt;
     *  &lt;mx:Label/&gt;
     *  </pre>
     *  
     *  <p>You must write the <code>htmlText</code> property as a child tag
     *  rather than as an attribute on the <code>&lt;mx:Label&gt;</code> tag
     *  because XML doesn't allow CDATA for the value of an attribute.
     *  Notice that the markup is readable, but the CDATA section makes 
     *  this approach more complicated.</p>
     *  
     *  </li>
     *  
     *  <li>
     *  
     *  <p>Use an <code>hmtlText</code> attribute where any occurences
     *  of the HTML markup characters &lt; and &gt; in the attribute value
     *  are written instead as the XML "entities" <code>&amp;lt;</code>
     *  and <code>&amp;gt;</code>:</p>
     *  
     *  <pre>
     *  &lt;mx:Label htmlText="This is an example of &amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt; markup"/&amp;gt;
     *  </pre>
     *  
     *  Adobe does not recommend this approach because the HTML markup becomes
     *  nearly impossible to read.
     *  
     *  </li>
     *  
     *  </ul>
     *  
     *  <p>If the <code>condenseWhite</code> property is <code>true</code> 
     *  when you set the <code>htmlText</code> property, multiple
     *  white-space characters are condensed, as in HTML-based browsers;
     *  for example, three consecutive spaces are displayed
     *  as a single space.
     *  The default value for <code>condenseWhite</code> is
     *  <code>false</code>, so you must set <code>condenseWhite</code>
     *  to <code>true</code> to collapse the white space.</p>
     *  
     *  <p>If you read back the <code>htmlText</code> property quickly
     *  after setting it, you get the same string that you set.
     *  However, after the LayoutManager runs, the value changes
     *  to include additional markup that includes the CSS styles.</p>
     *  
     *  <p>Setting the <code>htmlText</code> property affects the <code>text</code>
     *  property in several ways. 
     *  If you read the <code>text</code> property quickly after setting
     *  the <code>htmlText</code> property, you get <code>null</code>,
     *  which indicates that the <code>text</code> corresponding to the new
     *  <code>htmlText</code> has not yet been determined.
     *  However, after the LayoutManager runs, the <code>text</code> property 
     *  value changes to the <code>htmlText</code> string with all the 
     *  HTML markup removed; that is,
     *  the value is the characters that the Label actually displays.</p>
     *   
     *  <p>Conversely, if you set the <code>text</code> property,
     *  any previously set <code>htmlText</code> is irrelevant.
     *  If you read the <code>htmlText</code> property quickly after setting
     *  the <code>text</code> property, you get <code>null</code>,
     *  which indicates that the <code>htmlText</code> that corresponds to the new
     *  <code>text</code> has not yet been determined.
     *  However, after the LayoutManager runs, the <code>htmlText</code> property 
     *  value changes to the new text plus the HTML markup for the CSS styles.</p>
     *
     *  <p>To make the LayoutManager run immediately, you can call the
     *  <code>validateNow()</code> method on the Label.
     *  For example, you could set some <code>htmlText</code>,
     *  call the <code>validateNow()</code> method, and immediately
     *  obtain the corresponding <code>text</code> that doesn't have
     *  the HTML markup.</p>
     *  
     *  <p>If you set both <code>text</code> and <code>htmlText</code> properties 
     *  in ActionScript, whichever is set last takes effect.
     *  Do not set both in MXML, because MXML does not guarantee that
     *  the properties of an instance get set in any particular order.</p>
     *  
     *  <p>Setting either <code>text</code> or <code>htmlText</code> property
     *  inside a loop is a fast operation, because the underlying TextField
     *  that actually renders the text is not updated until
     *  the LayoutManager runs.</p>
     *
     *  <p>If you try to set this property to <code>null</code>,
     *  it is set, instead, to the empty string.
     *  If the property temporarily has the value <code>null</code>,
     *  it indicates that the <code>text</code> has been recently set
     *  and the corresponding <code>htmlText</code>
     *  has not yet been determined.</p>
     *  
     *  @default ""
     * 
     *  @see flash.text.TextField#htmlText
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get htmlText():String
    {
        return _htmlText;
    }

    /**
     *  @private
     */
    public function set htmlText(value:String):void
    {
        textSet = true;

        // The htmlText property can't be set to null,
        // only to the empty string, because if you set the htmlText
        // of a TextField to null it throws an RTE.
        // If the getter returns null, it means that 'text' was just set
        // and the value of 'htmlText' isn't yet known, because the 'text'
        // hasn't been committed into the textField and the 'htmlText'
        // hasn't yet been read back out of the textField.
        if (!value)
            value = "";

        if (isHTML && value == explicitHTMLText)
            return;

        _htmlText = value;
        htmlTextChanged = true;

        // The text property is unknown until commitProperties(),
        // when we push the htmlText into the TextField and it
        // calculates the text.
        // But you can call validateNow() to make this happen right away.
        _text = null;
        
        explicitHTMLText = value;

        invalidateProperties();
        invalidateSize();
        invalidateDisplayList();

        // Trigger bindings to htmlText.
        dispatchEvent(new Event("htmlTextChanged"));

        // commitProperties() will dispatch a "valueCommit" event
        // after the TextField determines the 'text' based on the
        // 'htmlText'; this event will trigger any bindings to 'text'.
    }

    //----------------------------------
    //  isHTML
    //----------------------------------

    /**
     *  @private
     */
    private function get isHTML():Boolean
    {
        return explicitHTMLText != null;
    }

    //----------------------------------
    //  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
     *  to initialize the <code>data</code> property of the 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>
     *
     *  @default null
     *  @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;
    }

    //----------------------------------
    //  selectable
    //----------------------------------

    /**
     *  @private
     *  Storage for selectable property.
     */
    private var _selectable:Boolean = false;

    /**
     *  @private
     *  Change flag for selectable property.
     */
    private var selectableChanged:Boolean;

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

    /**
     *  Specifies whether the text can be selected. 
     *  Making the text selectable lets you copy text from the control.
     *
     *  <p>When a <code>link</code> event is specified in the Label control, the <code>selectable</code> property must be set 
     *  to <code>true</code> to execute the <code>link</code> event.</p>
     *
     *  @default false;
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get selectable():Boolean
    {
        return _selectable;
    }

    /**
     *  @private
     */
    public function set selectable(value:Boolean):void
    {
        if (value == selectable)
            return;

        _selectable = value;
        selectableChanged = true;

        invalidateProperties();
    }

    //----------------------------------
    //  styleSheet
    //----------------------------------

    /**
     *  @private
     *  Change flag for the styleSheet property
     */
    private var styleSheetChanged:Boolean = false;

    /**
     *  @private
     *  Storage for the styleSheet property.
     */
    private var _styleSheet:StyleSheet;   

   /**
    *  A flash.text.StyleSheet object that can perform rendering
    *  on the Label control's text.
    *  Use this property for detailed control of HTML styles for the text.
    *  For more information, see the flash.text.StyleSheet
    *  class documentation.
    * 
    *  @see flash.text.StyleSheet
    *
    *  @default null
    *  
    *  @langversion 3.0
    *  @playerversion Flash 9
    *  @playerversion AIR 1.1
    *  @productversion Flex 3
    */
    public function get styleSheet():StyleSheet
    {
        return _styleSheet;
    }

    /**
     *  @private
     */
    public function set styleSheet(value:StyleSheet):void
    {
        _styleSheet = value;
        styleSheetChanged = true;
        htmlTextChanged = true;

        invalidateProperties();
    }

    //----------------------------------
    //  tabIndex
    //----------------------------------

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

    /**
     *  @private
     *  Although Label/Text do not receive stage focus 
     *  since they are not tabEnabled or 
     *  implement IFocusManagerComponent,
     *  for accessible applications, developers may set their
     *  tabIndex to specify reading order 
     *  of Screen Reader's virtual cursor.
     *  The default value is <code>-1</code>.
     *
     *  @tiptext tabIndex of the component
     *  @helpid 3198
     */
    override public function get tabIndex():int
    {
        return _tabIndex;
    }

    /**
     *  @private
     */
    override public function set tabIndex(value:int):void
    {
        _tabIndex = value;

        invalidateProperties();
    }

    //----------------------------------
    //  text
    //----------------------------------

    /**
     *  @private
     *  Storage for the text property.
     *  In addition to being set in the 'text' setter,
     *  it is automatically updated at another time:
     *  When the 'text' or 'htmlText' is pushed down into
     *  the textField in commitProperties(), this causes
     *  the textField to update its own 'text'.
     *  Therefore in commitProperties() we reset this storage var
     *  to be in sync with the textField.
     */
    private var _text:String = "";

    /**
     *  @private
     */
    mx_internal var textChanged:Boolean = false;

    [Bindable("valueCommit")]
    [CollapseWhiteSpace]
    [Inspectable(category="General", defaultValue="")]

    /**
     *  Specifies the plain text displayed by this control.
     *  Its appearance is determined by the CSS styles of this Label control.
     *
     *  <p>When you set this property, any characters that might
     *  look like HTML markup in the string have no special meaning
     *  and appear as entered.</p>
     *
     *  <p>To display text formatted by using HTML tags,
     *  use the <code>htmlText</code> property instead.
     *  If you set the <code>htmlText</code> property,
     *  the HTML replaces any text that you set using this property, and the
     *  <code>text</code> property returns a plain-text version of the
     *  HTML text, with all HTML tags stripped out.</p>
     *
     *  <p>To include the special characters left angle  bracket (&lt;),
     *  right angle bracket (&gt;), or ampersand (&amp;) in the text,
     *  wrap the text string in the CDATA tag.
     *  Alternatively, you can use HTML character entities for the
     *  special characters, for example, <code>&amp;lt;</code>.</p>
     *
     *  <p>If the text is wider than the Label control,
     *  the text is truncated and terminated by an ellipsis (...).
     *  The full text displays as a tooltip when
     *  you move the mouse over the Label control.
     *  If you also set a tooltip by using the <code>tooltip</code>
     *  property, the tooltip is displayed rather than the text.</p>
     *
     *  <p>If you try to set this property to <code>null</code>,
     *  it is set, instead, to the empty string.
     *  The <code>text</code> property can temporarily have the value <code>null</code>,
     *  which indicates that the <code>htmlText</code> has been recently set
     *  and the corresponding <code>text</code> value
     *  has not yet been determined.</p>
     *
     *  @default ""
     *  @tiptext Gets or sets the Label content
     *  @helpid 3907
    *  
    *  @langversion 3.0
    *  @playerversion Flash 9
    *  @playerversion AIR 1.1
    *  @productversion Flex 3
    */
    public function get text():String
    {
        return _text;
    }

    /**
     *  @private
     */
    public function set text(value:String):void
    {
        textSet = true;

        // The text property can't be set to null, only to the empty string.
        // If the getter returns null, it means that 'htmlText' was just set
        // and the value of 'text' isn't yet known, because the 'htmlText'
        // hasn't been committed into the textField and the 'text'
        // hasn't yet been read back out of the textField.
        if (!value)
            value = "";

        if (!isHTML && value == _text)
            return;
        
        _text = value;
        textChanged = true;

        // The htmlText property is unknown until commitProperties(),
        // when we push the text into the TextField and it
        // calculates the htmlText.
        // But you can call validateNow() to make this happen right away.
        _htmlText = null;
        
        explicitHTMLText = null;

        invalidateProperties();
        invalidateSize();
        invalidateDisplayList();

        // Trigger bindings to 'text'.
        dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT));

        // commitProperties() will dispatch an "htmlTextChanged" event
        // after the TextField determines the 'htmlText' based on the
        // 'text'; this event will trigger any bindings to 'htmlText'.
    }

    //----------------------------------
    //  textHeight
    //----------------------------------

    /**
     *  @private
     *  Storage for the textHeight property.
     */
    private var _textHeight:Number;

    /**
     *  The height of the text.
     *
     *  <p>The value of the <code>textHeight</code> property is correct only
     *  after the component has been validated.
     *  If you set <code>text</code> and then immediately ask for the
     *  <code>textHeight</code>, you might receive an incorrect value.
     *  You should wait for the component to validate
     *  or call the <code>validateNow()</code> method before you get the value.
     *  This behavior differs from that of the flash.text.TextField control,
     *  which updates the value immediately.</p>
     *
     *  @see flash.text.TextField
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get textHeight():Number
    {
        return _textHeight;
    }

    //----------------------------------
    //  textWidth
    //----------------------------------

    /**
     *  @private
     *  Storage for the textWidth property.
     */
    private var _textWidth:Number;

    /**
     *  The width of the text.
     *
     *  <p>The value of the <code>textWidth</code> property is correct only
     *  after the component has been validated.
     *  If you set <code>text</code> and then immediately ask for the
     *  <code>textWidth</code>, you might receive an incorrect value.
     *  You should wait for the component to validate
     *  or call the <code>validateNow()</code> method before you get the value.
     *  This behavior differs from that of the flash.text.TextField control,
     *  which updates the value immediately.</p>
     *
     *  @see flash.text.TextField
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get textWidth():Number
    {
        return _textWidth;
    }

    //----------------------------------
    //  truncateToFit
    //----------------------------------

    /**
     *  If this propery is <code>true</code>, and the Label control size is
     *  smaller than its text, the text of the 
     *  Label control is truncated using 
     *  a localizable string, such as <code>"..."</code>.
     *  If this property is <code>false</code>, text that does not fit is clipped.
     * 
     *  @default true
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public var truncateToFit:Boolean = true;
    
    //--------------------------------------------------------------------------
    //
    //  Overridden methods: UIComponent
    //
    //--------------------------------------------------------------------------


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

         if (!textField)
            createTextField(-1);
    }

    /**
     *  @private
     */
    override protected function commitProperties():void
    {
        super.commitProperties();
        
        // if the font changed and we already created the textfield, we will need to 
        // destory it so it can be re-created, possibly in a different swf context.
        
        if (hasFontContextChanged() && textField != null)
        {
            removeTextField();
            
            condenseWhiteChanged = true;
            enabledChanged = true;
            selectableChanged = true;
            textChanged = true;
        }

        if (!textField)
            createTextField(-1);
        
        if (condenseWhiteChanged)
        {
            textField.condenseWhite = _condenseWhite;
            
            condenseWhiteChanged = false;
        }

        textField.tabIndex = tabIndex;

        if (enabledChanged)
        {
            textField.enabled = enabled;
           
            enabledChanged = false;
        }

        if (selectableChanged)
        {
            textField.selectable = _selectable;
            
            selectableChanged = false;
        }

        if (styleSheetChanged)
        {
            textField.styleSheet = _styleSheet;

            styleSheetChanged = false;
        }

        if (textChanged || htmlTextChanged)
        {
            // If the 'text' and 'htmlText' properties have both changed,
            // the last one set wins.
            if (isHTML)
                textField.htmlText = explicitHTMLText;
            else
                textField.text = _text;
            
            textFieldChanged(false)
                        
            textChanged = false;
            htmlTextChanged = false;
        }
    }

    /**
     *  @private
     *  Measure min/max/preferred sizes.
     */
    override protected function measure():void
    {
        super.measure();

        var t:String = isHTML ? explicitHTMLText : text; 
        
        t = getMinimumText(t);

        // Determine how large the textField would need to be
        // to display the entire text.
        var textFieldBounds:Rectangle = measureTextFieldBounds(t);

        // Add in the padding.
        measuredMinWidth = measuredWidth = textFieldBounds.width +
            getStyle("paddingLeft") + getStyle("paddingRight");
        measuredMinHeight = measuredHeight = textFieldBounds.height +
            getStyle("paddingTop") + getStyle("paddingBottom");
    }

    /**
     *  @private
     */
    override protected function updateDisplayList(unscaledWidth:Number,
                                                  unscaledHeight:Number):void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);
                
        /*
        var g:Graphics = graphics;
        g.clear();
        var backgroundColor:* = getStyle("backgroundColor");
        if (StyleManager.isValidStyleValue(backgroundColor))
        {
            g.beginFill(getStyle("backgroundColor"));
            g.drawRect(0, 0, unscaledWidth, unscaledHeight);
            g.endFill();
        }
        */
                
        // The textField occupies the entire Label bounds minus the padding.

        var paddingLeft:Number = getStyle("paddingLeft");
        var paddingTop:Number = getStyle("paddingTop");
        var paddingRight:Number = getStyle("paddingRight");
        var paddingBottom:Number = getStyle("paddingBottom");

        
        textField.setActualSize(unscaledWidth - paddingLeft - paddingRight,
                                unscaledHeight - paddingTop - paddingBottom);

        textField.x = paddingLeft;
        textField.y = paddingTop;

        // Now handle truncation if the text doesn't fit.

        var t:String = isHTML ? explicitHTMLText : text; 

        // Determine how large the textField would need to be
        // to display the entire text.
        var textFieldBounds:Rectangle = measureTextFieldBounds(t);
        
        // Plain text gets truncated with a "...".
        // HTML text simply gets clipped, because it is difficult
        // to skip over the markup and truncate only the non-markup.
        // But both plain text and HTML text gets an automatic tooltip
        // if the full text isn't visible.
        if (truncateToFit)
        {
            var truncated:Boolean;
            if (isHTML)
            {
                truncated = textFieldBounds.width > textField.width;
            }
            else
            {
                // Reset the text in case it was previously
                // truncated with a "...".
                textField.text = _text;
                
                // Determine whether the full text needs to be truncated
                // based on the actual size of the TextField.
                // Note that the actual size doesn't change;
                // the text changes to fit within the actual size.
                truncated = textField.truncateToFit();
            }

            // If no explicit tooltip has been set,
            // implicitly set or clear a "truncation tip".
            if (!toolTipSet)
                super.toolTip = truncated ? text : null;
        }
        
    }

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

    /**
     *  @private
     *  Creates the text field child and adds it as a child of this component.
     * 
     *  @param childIndex The index of where to add the child.
     *  If -1, the text field is appended to the end of the list.
     */
    mx_internal function createTextField(childIndex:int):void
    {   
        if (!textField)
        {
            textField = IUITextField(createInFontContext(UITextField));
            textField.enabled = enabled;
            textField.ignorePadding = true;
            textField.selectable = selectable;
            textField.styleName = this;
            textField.addEventListener("textFieldStyleChange",
                                       textField_textFieldStyleChangeHandler);
            textField.addEventListener("textInsert",
                                       textField_textModifiedHandler);                                       
            textField.addEventListener("textReplace",
                                       textField_textModifiedHandler);
            textField.addEventListener("textFieldWidthChange",
                                       textField_textFieldWidthChangeHandler);
                                       
            if (childIndex == -1)
                addChild(DisplayObject(textField));
            else
                addChildAt(DisplayObject(textField), childIndex);
        }
    }


   /**
    *  @private
    *  Removes the text field from this component.
    */
    mx_internal function removeTextField():void
    {
        if (textField)
        {
            textField.removeEventListener("textFieldStyleChange",
                                          textField_textFieldStyleChangeHandler);
            textField.removeEventListener("textInsert",
                                          textField_textModifiedHandler);                                       
            textField.removeEventListener("textReplace",
                                          textField_textModifiedHandler);                                       
            textField.removeEventListener("textFieldWidthChange",
                                          textField_textFieldWidthChangeHandler);
            removeChild(DisplayObject(textField));
            textField = null;
        }
    }

    /**
     *  Returns a TextLineMetrics object with information about the text 
     *  position and measurements for a line of text in the control.
     *  The component must be validated to get a correct number.
     *  If you set <code>text</code> and then immediately call
     *  <code>getLineMetrics()</code> you may receive an incorrect value.
     *  You should either wait for the component to validate
     *  or call <code>validateNow()</code>.
     *  This is behavior differs from that of the flash.text.TextField class,
     *  which updates the value immediately.
     * 
     *  @param lineIndex The zero-based index of the line for which to get the metrics. 
     *  For the Label control, which has only a single line, must be 0.
     * 
     *  @return The TextLineMetrics object that contains information about the text.
     *
     *  @see flash.text.TextField
     *  @see flash.text.TextLineMetrics
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getLineMetrics(lineIndex:int):TextLineMetrics
    {
        return textField ? textField.getLineMetrics(lineIndex) : null;
    }

    /**
     *  @private
     *  Setting the 'htmlText' of textField changes its 'text',
     *  and vice versa, so afterwards doing so we call this method
     *  to update the storage vars for various properties.
     *  Afterwards, the Label's 'text', 'htmlText', 'textWidth',
     *  and 'textHeight' are all in sync with each other
     *  and are identical to the TextField's.
     */
    private function textFieldChanged(styleChangeOnly:Boolean):void
    {
        var changed1:Boolean;
        var changed2:Boolean;

        if (!styleChangeOnly)
        {
            changed1 = _text != textField.text;
            _text = textField.text;
        }

        changed2 = _htmlText != textField.htmlText;
        _htmlText = textField.htmlText;

        // If the 'text' property changes, dispatch a valueCommit
        // event, which will trigger bindings to 'text'.
        if (changed1)
            dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT));
        // If the 'htmlText' property changes, trigger bindings to it.
        if (changed2)
            dispatchEvent(new Event("htmlTextChanged"));

        _textWidth = textField.textWidth;
        _textHeight = textField.textHeight;
    }

    /**
     *  @private
     */
    private function measureTextFieldBounds(s:String):Rectangle
    {
        // Measure the text we need to display.
        var lineMetrics:TextLineMetrics = isHTML ?
                                          measureHTMLText(s) :
                                          measureText(s);
        
        // In order to display this text completely,
        // a TextField must be 4-5 pixels larger.
        return new Rectangle(0, 0,
                             lineMetrics.width + UITextField.TEXT_WIDTH_PADDING,
                             lineMetrics.height + UITextField.TEXT_HEIGHT_PADDING);
    }

    /**
     *  @private
     *  Some other components which use a Label as an internal
     *  subcomponent need access to its UITextField, but can't access the
     *  textField var because it is protected and therefore available
     *  only to subclasses.
     */
    mx_internal function getTextField():IUITextField
    {
        return textField;
    }
    
    /**
     *  @private 
     */
    mx_internal function getMinimumText(t:String):String
    {
         // If the text is null, empty, or a single character,
        // make the measured size big enough to hold
        // a capital and decending character using the current font.
        if (!t || t.length < 2)
            t = "Wj";
            
        return t;   
    }

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

    /**
     *  @private
     */
    private function textField_textFieldStyleChangeHandler(event:Event):void
    {
        textFieldChanged(true);
    }

    /**
     *  @private
     */
    private function textField_textModifiedHandler(event:Event):void
    {
        textFieldChanged(false);
    }

    /**
     *  @private
     *  Changing the width of the text field can cause the text to reflow.
     *  Make sure our local _textWidth and _textHeight are in sync with text field.
     */
    private function textField_textFieldWidthChangeHandler(event:Event):void
    {
        textFieldChanged(true);
    }   
}

}
