////////////////////////////////////////////////////////////////////////////////
//
//  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 spark.skins.ios7
{

import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.events.SoftKeyboardEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.system.Capabilities;
import flash.text.TextLineMetrics;
import flash.ui.Keyboard;

import mx.core.DPIClassification;
import mx.core.EventPriority;
import mx.core.FlexGlobals;
import mx.core.mx_internal;
import mx.events.FlexEvent;
import mx.utils.Platform;

import spark.components.Group;
import spark.components.Scroller;
import spark.components.TextArea;
import spark.components.supportClasses.StyleableTextField;
import spark.events.CaretBoundsChangeEvent;
import spark.skins.ios7.supportClasses.TextSkinBase;

use namespace mx_internal;

/**
 *  ActionScript-based skin for TextArea components in mobile applications.
 * 
 * @see spark.components.TextArea
 * 
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 2.5 
 *  @productversion Flex 4.5
 */
public class TextAreaSkin extends TextSkinBase 
{
    /**
     *  @private
     *  Right-margin of iOS native text control when editing on a retina display
     *  based on fontSize 32.
     */
    mx_internal static var IOS_RIGHT_MARGIN_320:Number = 19;
    
    /**
     *  @private
     *  Right-margin of iOS native text control when editing on a retina display
     *  based on fontSize 16 scaling from applicationDPI 160.
     */
    mx_internal static var IOS_RIGHT_MARGIN_160_SCALED_TO_320:Number = 9.4;
    
    /**
     *  @private
     *  Right-margin of iOS native text control when editing on a standard display
     *  based on fontSize 16 and runtimeDPI 160.
     */
    mx_internal static var IOS_RIGHT_MARGIN_160:Number = 20.6;
    
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------
    
    /**
     *  Constructor.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function TextAreaSkin()
    {
        super();
        
        addEventListener(Event.RESIZE, resizeHandler);
        
        switch (applicationDPI)
        {
			case DPIClassification.DPI_640:
			{
				measuredDefaultWidth = 1024;
				measuredDefaultHeight = 212;
				layoutBorderSize = 3;
				roundheight = 24;
				break;
			}
			case DPIClassification.DPI_480:
			{
				measuredDefaultWidth = 880;
				measuredDefaultHeight = 140;
				layoutBorderSize = 2;
				roundheight = 18;	
				break;
			}
            case DPIClassification.DPI_320:
            {
                measuredDefaultWidth = 612;
                measuredDefaultHeight = 106;
				layoutBorderSize = 1.5;
				roundheight = 14;	
                break;
            }
			case DPIClassification.DPI_240:
			{
				measuredDefaultWidth = 440;
				measuredDefaultHeight = 70;
				layoutBorderSize = 1;
				roundheight = 10;
				break;
			}
			case DPIClassification.DPI_120:
			{
				measuredDefaultWidth = 220;
				measuredDefaultHeight = 35;
				layoutBorderSize = .5;
				roundheight = 5;
				break;
			}
            default:
            {
                measuredDefaultWidth = 306;
                measuredDefaultHeight = 53;
				layoutBorderSize = .5;
				roundheight = 7; 
                break;
            }
        }
		addEventListener(FocusEvent.FOCUS_IN, focusChangeHandler);
		addEventListener(FocusEvent.FOCUS_OUT, focusChangeHandler);
    }
    
    //--------------------------------------------------------------------------
    //
    //  Skin parts
    //
    //--------------------------------------------------------------------------
    
    /**
     *  Scroller skin part.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5 
     *  @productversion Flex 4.5
     */ 
    public var scroller:Scroller;
    
    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------
    
    /** 
     *  @copy spark.skins.spark.ApplicationSkin#hostComponent
     */
    public var hostComponent:TextArea;
    
    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------
	
	protected var isFocused:Boolean = false;
	
	protected var roundheight:uint;
	
    /**
     *  @private
     *  The width of the component on the previous layout manager 
     *  pass.  This gets set in updateDisplayList() and used in measure() on 
     *  the next layout pass.  This is so our "guessed width" in measure() 
     *  will be as accurate as possible since textDisplay is multiline and 
     *  the textDisplay height is dependent on the width.
     * 
     *  In the constructor this is actually set based on the DPI.
     */
    mx_internal var oldUnscaledWidth:Number;
    
    private var textDisplayGroup:Group;
    private var _isIOS:Boolean;
    private var invalidateCaretPosition:Boolean = true;
    private var oldCaretBounds:Rectangle = new Rectangle(-1, -1, -1, -1);
    private var lastTextHeight:Number;
    private var lastTextWidth:Number;
    
    private var isTextDisplayTall:Boolean = true;
    private var growTextDisplay:Boolean = false;
    private var shrinkTextDisplay:Boolean = false;
    
    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    override protected function createChildren():void
    {
        if (!textDisplay)
        {
            // wrap StyleableTextField in UIComponent
            textDisplay = StyleableTextField(createInFontContext(StyleableTextField));
            textDisplay.styleName = this;
            textDisplay.multiline = true;
            textDisplay.editable = true;
            textDisplay.lineBreak = getStyle("lineBreak");
            textDisplay.useTightTextBounds = false;
            textDisplay.scrollToRangeDelegate = scrollToRange;
            
            // on iOS, resize the TextField and let the native control handle scrolling
            _isIOS = Platform.isIOS;
            
            if (_isIOS)
            {
                // hard-coded rightMargin for iOS native text control
                // this value is independent of the paddingRight style
                var rightMargin:Number = 0;
                var isRetina:Boolean = false;
                var isScaling160to320:Boolean = false;
                
                // check for scaling
                if ("runtimeDPI" in FlexGlobals.topLevelApplication)
                {
                    var runtimeDPI:Number = FlexGlobals.topLevelApplication.runtimeDPI as Number;
                    isRetina = (runtimeDPI == DPIClassification.DPI_320);
                    isScaling160to320 = isRetina
                        && (applicationDPI == DPIClassification.DPI_160);
                }
                
                if (isRetina && !isScaling160to320)
                    rightMargin = IOS_RIGHT_MARGIN_320;
                else if (isRetina && isScaling160to320)
                    rightMargin = IOS_RIGHT_MARGIN_160_SCALED_TO_320;
                else
                    rightMargin = IOS_RIGHT_MARGIN_160;
                
                textDisplay.rightMargin = rightMargin;
            }
            else
            {
                textDisplay.addEventListener(KeyboardEvent.KEY_DOWN, textDisplay_keyHandler);
            }
            
            textDisplay.addEventListener(Event.CHANGE, textDisplay_changeHandler);
            textDisplay.addEventListener(FlexEvent.VALUE_COMMIT, textDisplay_changeHandler);
            textDisplay.addEventListener(Event.SCROLL, textDisplay_scrollHandler);
            // Use a lower priority so that the StyleableTextField event handler is called first. 
            // That handler cancels the event and we need to check for that case
            textDisplay.addEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATING, textDisplay_softKeyboardActivatingHandler, false, EventPriority.DEFAULT_HANDLER);
            textDisplay.addEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATE, textDisplay_softKeyboardActivateHandler);
            textDisplay.addEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_DEACTIVATE, textDisplay_softKeyboardDeactivateHandler);
            
            textDisplay.left = getStyle("paddingLeft");
            textDisplay.top = getStyle("paddingTop");
            textDisplay.right = getStyle("paddingRight");
            textDisplay.bottom = getStyle("paddingBottom");
            
            // wrap StyleableTextComponent in Group for viewport
            textDisplayGroup = new Group();
            textDisplayGroup.clipAndEnableScrolling = true;
            textDisplayGroup.addElement(textDisplay);
        }
        
        if (!scroller)
        {
            scroller = new Scroller();
            scroller.minViewportInset = 0;
            scroller.measuredSizeIncludesScrollBars = false;
            scroller.ensureElementIsVisibleForSoftKeyboard = false;
            
            addChild(scroller);
        }
        
        if (!scroller.viewport)
            scroller.viewport = textDisplayGroup;
        
        super.createChildren();
    }
    
    /**
     *  @private
     *  TextArea prompt supports wrapping and multiline
     */
    override protected function createPromptDisplay():StyleableTextField
    {
        var prompt:StyleableTextField = super.createPromptDisplay();
        prompt.editable = true;
        prompt.wordWrap = true;
        
        return prompt;
    }
    
    /**
     *  @private
     */
    override protected function measure():void
    {
        super.measure();
        
        var paddingTop:Number = getStyle("paddingTop");
        var paddingBottom:Number = getStyle("paddingBottom");
        var paddingLeft:Number = getStyle("paddingLeft");
        var paddingRight:Number = getStyle("paddingRight");
        
        // TextDisplay always defaults to 440 pixels wide (the value is DPI dependent), 
        // and tall enough to show all text.
        // 
        // You can set an explicit width and the height will adjust accordingly. The opposite
        // is not true: setting an explicit height will not adjust the width accordingly.
        
        measuredWidth = measuredDefaultWidth;
        
        // now we need to measure textDisplay's height.  Unfortunately, this is tricky and 
        // is dependent on textDisplay's width.  Let's use the heuristic that our width 
        // is the same as our last width.
        // We don't use layoutMeasuredWidth, because that value is just a constant and doesn't
        // take into account the fact that the TextArea could have an explicitWidth or could 
        // be constrained by some value.  However, we still default oldTextDisplayWidth to 
        // be layoutMeasuredWidth the first time through.
        var textDisplayEstimatedWidth:Number = oldUnscaledWidth - paddingLeft - paddingRight;
        
        // now we need to measure textDisplay's height.  Unfortunately, this is tricky and 
        // is dependent on textDisplay's width.  
        // Use the old textDisplay width as an estimte for the new one.  
        // If we are wrong, we'll find out in updateDisplayList()
        textDisplay.commitStyles();
        
        // Clear min sizes first.
        textDisplay.minWidth = textDisplay.minHeight = NaN;
        
        // If lineBreak == explicit, always use NaN for estimated width
        if (getStyle("lineBreak") == "explicit")
            textDisplayEstimatedWidth = NaN;
        
        setElementSize(textDisplay, textDisplayEstimatedWidth, NaN);
        
        measuredHeight = getElementPreferredHeight(textDisplay) + paddingTop + paddingBottom;
    }
    
    /**
     *  @private
     */
    override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.layoutContents(unscaledWidth, unscaledHeight);
        
        // position & size border
        if (border)
        {
            setElementSize(border, unscaledWidth, unscaledHeight);
            setElementPosition(border, 0, 0);
        }
        
        setElementSize(scroller, unscaledWidth, unscaledHeight);
        setElementPosition(scroller, 0, 0);
        
        // position & size the text
        var explicitLineBreak:Boolean = getStyle("lineBreak") == "explicit";
        var paddingLeft:Number = getStyle("paddingLeft");
        var paddingRight:Number = getStyle("paddingRight");
        var paddingTop:Number = getStyle("paddingTop");
        var paddingBottom:Number = getStyle("paddingBottom");
        
        var unscaledTextWidth:Number = unscaledWidth - paddingLeft - paddingRight;
        var unscaledTextHeight:Number = unscaledHeight - paddingTop - paddingBottom;
        var textHeight:Number;
        var textWidth:Number = explicitLineBreak ? textDisplay.measuredTextSize.x : unscaledTextWidth;
        
        var lineIndex:int;
        var topCharIndex:int;
        var charBounds:Rectangle;
        
        // grab old measured textDisplay height before resizing it
        var oldPreferredTextHeight:Number = getElementPreferredHeight(textDisplay);
        
        // set width first to measure height correctly
        textDisplay.commitStyles();
        textDisplay.setLayoutBoundsSize(textWidth, NaN);
        
        // In iOS, when we go into editing mode, the runtime overlays a native 
        // text control over the textDisplay. In order to prevent the text 
        // from overflowing the component and to get scrolling support, the 
        // native text control must be the same size as the TextArea
        if (_isIOS)
        {
            if (shrinkTextDisplay)
            {
                // Switching to edit mode. Convert from viewport scrolling to 
                // TextField scrolling
                var vsp:Number = textDisplayGroup.verticalScrollPosition;
                            
                var lineMetrics:TextLineMetrics = textDisplay.getLineMetrics(0);
                var lineHeight:Number = lineMetrics.ascent + lineMetrics.descent;
                
                // TODO Figure out how to get the x offset. Right now is hard coded to 2
                // At least half the line should be showing before we scroll to that line
                // This makes the conversion from pixel to line based scrolling a little less jumpy
                lineIndex = textDisplay.getLineIndexAtPoint(2, vsp + lineHeight / 2) + 1;
                textDisplayGroup.verticalScrollPosition = 0;
                isTextDisplayTall = false;
                //trace("TAS.layoutContents shrinkText vsp",vsp,"lineIndex",lineIndex);
            }
            
            else if (growTextDisplay)
            {
                // Leaving edit mode. Convert from TextField scrolling to 
                // viewport scrolling
                var scrollV:Number = textDisplay.scrollV;
                
                // TODO (jszeto) investigate using lineMetrics.lineHeight * scrollV instead of getCharBoundaries
                topCharIndex = textDisplay.getLineOffset(scrollV - 1);
                charBounds = textDisplay.getCharBoundaries(topCharIndex);
                // If the charBounds is null, just set vsp to 0
                if (charBounds == null)
                    charBounds = new Rectangle(0, 0, 0, 0);
                textDisplay.scrollV = 1;
                isTextDisplayTall = true;
                //trace("TAS.layoutContents growText scrollV",scrollV,"topCharIndex",topCharIndex,"charBounds",charBounds);
            }
        }
        
        // TextField height should match its content or the TextArea bounds at minimum
        // iOS special case to prevent Flex Scroller scrolling when editable
        if (isTextDisplayTall)
            textHeight = Math.max(textDisplay.measuredTextSize.y, unscaledTextHeight);
        else
            textHeight = unscaledTextHeight;
        
        // FIXME (jasonsj): iOS native scroll bar appears even when explictHeight
        //                  is not specified. Focus-in is jumpy.
        
        if (promptDisplay)
        {
            promptDisplay.commitStyles();
            setElementSize(promptDisplay, unscaledTextWidth, textHeight);
            setElementPosition(promptDisplay, paddingLeft, paddingTop);
            
            // no need to update textDisplay if promptDisplay is present
            return;
        }
        
        // keep track of oldUnscaledWidth so we have a good guess as to the width 
        // of the textDisplay on the next measure() pass
        oldUnscaledWidth = unscaledWidth;
        
        // set the width of textDisplay to textWidth.
        // set the height to oldTextHeight.  If the height's actually wrong, 
        // we'll invalidateSize() and go through this layout pass again anyways
        setElementSize(textDisplay, textWidth, textHeight);
        
        // Set minWidth/Height on the text so the textDisplayGroup sizes accordingly
        textDisplay.minWidth = textWidth;
        textDisplay.minHeight = textHeight;
        textDisplayGroup.invalidateDisplayList();
        
        // grab new measured textDisplay height after the textDisplay has taken its final width
        var newPreferredTextHeight:Number = getElementPreferredHeight(textDisplay);
        
        // if the resize caused the textDisplay's height to change (because of 
        // text reflow), then we need to remeasure ourselves with our new width
        if (oldPreferredTextHeight != newPreferredTextHeight)
            invalidateSize();
        
        if (_isIOS)
        {
            if (shrinkTextDisplay)
            {
                scroller.validateNow();
                textDisplay.scrollV = lineIndex;
            }
            else if (growTextDisplay)
            {
                scroller.validateNow();
                textDisplayGroup.verticalScrollPosition = charBounds.y;
            }               
            
            shrinkTextDisplay = false;
            growTextDisplay = false;
        }
        
        //trace("TAS.layoutContents tH",textHeight,"tW",textWidth,"invalidateCaret",invalidateCaretPosition);
        
        // checking if text fits in TextArea
        // does not apply to iOS due to native text editing and scrolling
        // invalidateCaretPosition will never be true for iOS
        if (invalidateCaretPosition && isTextDisplayTall)
        {
            // if the caret is outside the viewport, update the Group verticalScrollPosition
            var charIndex:int = textDisplay.selectionBeginIndex;
            var caretBounds:Rectangle = textDisplay.getCharBoundaries(charIndex);
            lineIndex = textDisplay.getLineIndexOfChar(charIndex);
            
            // getCharBoundaries() returns null for new lines
            if (!caretBounds)
            {
                // temporarily insert a character at the caretIndex
                textDisplay.replaceText(charIndex, charIndex, "W");
                caretBounds = textDisplay.getCharBoundaries(charIndex);
                lineIndex = textDisplay.getLineIndexOfChar(charIndex);
                textDisplay.replaceText(charIndex, charIndex + 1, "");   
            }
           
            if (caretBounds)
            {
                // Scroll the internal Scroller to ensure the caret is visible
                if (textHeight > unscaledTextHeight)
                {
                    
                    if (charIndex == textDisplay.text.length)
                    {
                        // Make sure textDisplayGroup is validated, otherwise the 
                        // verticalScrollPosition may be out of bounds, which will
                        // cause a bounce effect.
                        textDisplayGroup.validateNow();
                        textDisplayGroup.verticalScrollPosition = textHeight;
                    }
                    else
                    {
                        // caretTopPositon and caretBottomPosition are TextField-relative positions
                        // the TextField is inset by padding styles of the TextArea (via the VGroup)
                        
                        // adjust top position to 0 when on the first line
                        // caretTopPosition will be negative when off stage
                        var caretTopPosition:Number = ((caretBounds.y) < 0 || (lineIndex == 0))
                            ? 0 : caretBounds.y;
                        
                        // caretBottomPosition is the y coordinate of the bottom bounds of the caret
                        var caretBottomPosition:Number = caretBounds.y + caretBounds.height;
                        
                        // note that verticalScrollPosition min/max do not account for padding
                        var vspTop:Number = textDisplayGroup.verticalScrollPosition;
                        
                        // vspBottom should be the max visible Y in the TextField
                        // coordinate space.
                        // remove paddingBottom for some clearance between caret and border
                        var vspBottom:Number = vspTop + unscaledHeight - paddingTop - paddingBottom;
                        
                        // is the caret in or below the padding and viewport?
                        if (caretBottomPosition > vspBottom)
                        {
                            // adjust caretBottomPosition to max scroll position when on the last line
                            if (lineIndex + 1 == textDisplay.numLines)
                            {
                                // use textHeight+paddings instead of textDisplayGroup.contentHeight
                                // Group has not been resized by this point
                                textDisplayGroup.verticalScrollPosition = (textHeight + paddingTop + paddingBottom) - textDisplayGroup.height;
                            }
                            else
                            {
                                // bottom edge of the caret moves just inside the bottom edge of the scroller
                                // add delta between caret and vspBottom
                                textDisplayGroup.verticalScrollPosition = vspTop + (caretBottomPosition - vspBottom);
                            }
                        }
                            // is the caret above the viewport?
                        else if (caretTopPosition < vspTop)
                        {
                            // top edge of the caret moves inside the top edge of the scroller
                            textDisplayGroup.verticalScrollPosition = caretTopPosition;
                        }
                    }
                    
                    scroller.validateNow();
                }
                
                // Convert to local coordinates
                // Dispatch an event for an ancestor Scroller
                // It will scroll the TextArea so the caret is in view
                convertBoundsToLocal(caretBounds);
                if (oldCaretBounds == null || caretBounds.bottom != oldCaretBounds.bottom || caretBounds.top != oldCaretBounds.top)
                {
                    //trace("TAS.layoutContents send caret CHANGE");
                    dispatchEvent(new CaretBoundsChangeEvent(CaretBoundsChangeEvent.CARET_BOUNDS_CHANGE,true,true,oldCaretBounds,caretBounds));
                }
                
                oldCaretBounds = caretBounds;   
            }

            invalidateCaretPosition = false;
        }
        
        // Make sure final scroll position is valid
        if (isTextDisplayTall)
            snapTextScrollPosition();
    }
    
	override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
	{
		super.drawBackground(unscaledWidth, unscaledHeight);
		
		var contentBackgroundColor:uint = getStyle("contentBackgroundColor");
		var contentBackgroundAlpha:Number = getStyle("contentBackgroundAlpha");	
		//change border color and thickness when in focus
		var borderColor:uint = isFocused ? getStyle("focusColor") : getStyle("borderColor");
		var borderWidth:uint = layoutBorderSize * 2;
		if (isNaN(contentBackgroundAlpha))
		{
			contentBackgroundAlpha = 1;
		}        
		if (getStyle("contentBackgroundBorder") == "roundedrect")
		{		
			graphics.lineStyle(layoutBorderSize, borderColor, 1, true);
			graphics.beginFill(contentBackgroundColor, contentBackgroundAlpha);
			graphics.drawRoundRectComplex(layoutBorderSize, layoutBorderSize, unscaledWidth - borderWidth, unscaledHeight - borderWidth, roundheight, roundheight, roundheight, roundheight);
			graphics.endFill();
		}
		if (getStyle("contentBackgroundBorder") == "rectangle")
		{
			
			//rectangle border and background
			graphics.lineStyle(layoutBorderSize, borderColor, 1);
			graphics.beginFill(contentBackgroundColor, contentBackgroundAlpha);
			graphics.drawRect(layoutBorderSize, layoutBorderSize, unscaledWidth - borderWidth, unscaledHeight - borderWidth);
			graphics.endFill();
		}
		else if (getStyle("contentBackgroundBorder") == "none")
		{
			
			//rectangle border and background
			graphics.beginFill(contentBackgroundColor, contentBackgroundAlpha);
			graphics.drawRect(0, 0, unscaledWidth - borderWidth, unscaledHeight - borderWidth);
			graphics.endFill();
		}
	}
	
    /**
     *  @private
     *  Make sure the scroll positions are valid, and adjust if needed.
     */
    private function snapTextScrollPosition():void
    {
        var maxHsp:Number = textDisplayGroup.contentWidth > textDisplayGroup.width ? 
            textDisplayGroup.contentWidth-textDisplayGroup.width : 0; 
        textDisplayGroup.horizontalScrollPosition =  Math.min(Math.max(0,textDisplayGroup.horizontalScrollPosition),maxHsp);
        
        var maxVsp:Number = textDisplayGroup.contentHeight > textDisplayGroup.height ? 
            textDisplayGroup.contentHeight-textDisplayGroup.height : 0; 
        
        textDisplayGroup.verticalScrollPosition = 
            Math.min(Math.max(0,textDisplayGroup.verticalScrollPosition),maxVsp);
    }
    
    /**
     *  @private
     *  Get the bounds of the caret
     */    
    private function getCaretBounds():Rectangle
    {
        var charIndex:int = textDisplay.selectionBeginIndex;
        var caretBounds:Rectangle = textDisplay.getCharBoundaries(charIndex);
        
        if (!caretBounds)
        {
            textDisplay.replaceText(charIndex, charIndex, "W");
            caretBounds = textDisplay.getCharBoundaries(charIndex);
            textDisplay.replaceText(charIndex, charIndex + 1, "");
        }
        
        return caretBounds;
    }
    
    /**
     *  @private
     *  Convert bounds from textDisplay to local coordinates
     */
    private function convertBoundsToLocal(bounds:Rectangle):void
    {
        if (bounds)
        {
            var position:Point = new Point(bounds.x, bounds.y);
            position = textDisplay.localToGlobal(position);
            position = globalToLocal(position);
            bounds.x = position.x;
            bounds.y = position.y;
        }
    }
    
    /**
     *  @private
     */
    private function scrollToRange(anchorPosition:int, activePosition:int):void
    {
        var pos:int = Math.min(anchorPosition, activePosition);
        var bounds:Rectangle = textDisplay.getCharBoundaries(pos);
        var vsp:int = textDisplayGroup.verticalScrollPosition;
        var paddingTop:Number = getStyle("paddingTop");
        var paddingBottom:Number = getStyle("paddingBottom");
        
        if (bounds && (bounds.top < vsp - paddingTop || 
             bounds.bottom > vsp + unscaledHeight - paddingTop - paddingBottom))
        {
            textDisplayGroup.verticalScrollPosition = bounds.top + paddingTop;
            snapTextScrollPosition();
        }
    }
    
    /**
     *  @private
     *  Handle size and caret position changes that occur when text content
     *  changes.
     */
    private function textDisplay_changeHandler(event:Event):void
    {
        var tH:Number = textDisplay.textHeight;
        var tW:Number = textDisplay.textWidth;
        var explicitLineBreak:Boolean = getStyle("lineBreak") == "explicit";
        
        // Size and caret position have changed if the text height is different or
        // the text width is different and we aren't word wrapping
        if (tH != lastTextHeight || ( explicitLineBreak && tW != lastTextWidth))
        {
            invalidateSize();
            invalidateDisplayList();
            invalidateCaretPosition = true;   
        }
        
        lastTextHeight = tH;
        lastTextWidth = tW;
    }
    
    /**
     *  @private
     *  Cancels any native scroll that the Flash Player attempts to do
     */
    private function textDisplay_scrollHandler(event:Event):void
    {
        // if iOS, let the OS handle scrolling
        if (_isIOS)
            return;
        
        // If not IOS, we will handle scrolling, so don't let the native
        // flash textfield scroll at all.
        if (textDisplay.scrollV > 1)
            textDisplay.scrollV = 1;
        if (textDisplay.scrollH > 0)
            textDisplay.scrollH = 0;
    }
    
    /**
     *  @private
     *  Adjust viewport when using key navigation
     */
    private function textDisplay_keyHandler(event:KeyboardEvent):void
    {
        // update scroll position when caret changes
        if ((event.keyCode == Keyboard.UP
                || event.keyCode == Keyboard.DOWN
                || event.keyCode == Keyboard.LEFT
                || event.keyCode == Keyboard.RIGHT))
        {
            invalidateDisplayList();
            invalidateCaretPosition = true;
        }
        
        // Change event is not always sent when delete key is pressed, so
        // invalidate the size here
        if (event.keyCode == Keyboard.BACKSPACE)
        {
            invalidateSize();
        }
    }
    
    /**
     *  @private
     *  When entering edit mode on iOS, we need to shrink the textDisplay to 
     *  the size of the TextArea  
     */ 
    private function textDisplay_softKeyboardActivatingHandler(event:SoftKeyboardEvent):void
    {
        if (event.isDefaultPrevented())
            return;
        
        if (_isIOS && isTextDisplayTall)
        {
            //trace("TAS.SK ACTIVATING targ",event.target);
            shrinkTextDisplay = true;
            invalidateDisplayList();
            validateNow();
        }
    }  
    
    /**
     *  @private
     *  Send a caret change event to an ancestor Scroller
     */
    private function textDisplay_softKeyboardActivateHandler(event:SoftKeyboardEvent):void
    {
        var keyboardRect:Rectangle = stage.softKeyboardRect;
        
        if (keyboardRect.width > 0 && keyboardRect.height > 0)
        {
            var newCaretBounds:Rectangle = getCaretBounds();
            convertBoundsToLocal(newCaretBounds);
            
            if (oldCaretBounds != newCaretBounds)
            {
                //trace("TAS.SK ACTIVATE",keyboardRect,"dispatch caret CHANGE","newCaretBounds",newCaretBounds);
                dispatchEvent(new CaretBoundsChangeEvent(CaretBoundsChangeEvent.CARET_BOUNDS_CHANGE,true,true,oldCaretBounds,newCaretBounds));
                oldCaretBounds = newCaretBounds;
            }
        }
    }
    
    /**
     *  @private
     *  On iOS, when leaving edit mode, we need to restore the textDisplay to the
     *  height of the text.
     */  
    private function textDisplay_softKeyboardDeactivateHandler(event:SoftKeyboardEvent):void
    {
        if (_isIOS && !isTextDisplayTall)
        {
            growTextDisplay = true;
            invalidateDisplayList();
        }
    }
    
    /**
     *  @private
     */
    private function resizeHandler(event:Event):void
    {
        // Resizing needs to tickle the TextArea's internal auto-scroll logic
        invalidateCaretPosition = true;
        invalidateDisplayList();
    }
    
    /**
     *  @private
     */
    override public function styleChanged(styleProp:String):void
    {
        super.styleChanged(styleProp);
        
        // propogate styleChanged explicitly to textDisplay
        if (textDisplay)
            textDisplay.styleChanged(styleProp);
        
        // Check for padding style changes
        if (!styleProp || styleProp == "styleName" || styleProp.indexOf("padding") >= 0)
        {
            if (textDisplay)
            {
                textDisplay.left = getStyle("paddingLeft");
                textDisplay.top = getStyle("paddingTop");
                textDisplay.right = getStyle("paddingRight");
                textDisplay.bottom = getStyle("paddingBottom");
            }
        }
    }
	
	private function focusChangeHandler(event:FocusEvent):void
	{
		isFocused = event.type == FocusEvent.FOCUS_IN;
		invalidateDisplayList();		
	}
	
}
}