////////////////////////////////////////////////////////////////////////////////
//
//  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 flashx.textLayout.container
{
	import flash.display.BlendMode;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.InteractiveObject;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.ContextMenuEvent;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.FocusEvent;
	import flash.events.IMEEvent;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.events.TextEvent;
	import flash.geom.Rectangle;
	import flash.text.engine.TextBlock;
	import flash.text.engine.TextLine;
	import flash.text.engine.TextLineValidity;
	import flash.ui.ContextMenu;
	import flash.ui.ContextMenuClipboardItems;
	import flash.ui.Mouse;
	import flash.ui.MouseCursor;
	import flash.utils.Dictionary;
	
	import flashx.textLayout.compose.BaseCompose;
	import flashx.textLayout.compose.ISWFContext;
	import flashx.textLayout.compose.SimpleCompose;
	import flashx.textLayout.compose.StandardFlowComposer;
	import flashx.textLayout.compose.TextFlowLine;
	import flashx.textLayout.compose.TextLineRecycler;
	import flashx.textLayout.debug.Debugging;
	import flashx.textLayout.debug.assert;
	import flashx.textLayout.edit.EditManager;
	import flashx.textLayout.edit.EditingMode;
	import flashx.textLayout.edit.IEditManager;
	import flashx.textLayout.edit.IInteractionEventHandler;
	import flashx.textLayout.edit.ISelectionManager;
	import flashx.textLayout.edit.SelectionFormat;
	import flashx.textLayout.edit.SelectionManager;
	import flashx.textLayout.elements.Configuration;
	import flashx.textLayout.elements.FlowElement;
	import flashx.textLayout.elements.FlowLeafElement;
	import flashx.textLayout.elements.IConfiguration;
	import flashx.textLayout.elements.ParagraphElement;
	import flashx.textLayout.elements.SpanElement;
	import flashx.textLayout.elements.TextFlow;
	import flashx.textLayout.events.CompositionCompleteEvent;
	import flashx.textLayout.events.DamageEvent;
	import flashx.textLayout.events.FlowOperationEvent;
	import flashx.textLayout.events.SelectionEvent;
	import flashx.textLayout.events.StatusChangeEvent;
	import flashx.textLayout.events.TextLayoutEvent;
	import flashx.textLayout.events.UpdateCompleteEvent;
	import flashx.textLayout.factory.StringTextLineFactory;
	import flashx.textLayout.factory.TextFlowTextLineFactory;
	import flashx.textLayout.factory.TextLineFactoryBase;
	import flashx.textLayout.formats.BlockProgression;
	import flashx.textLayout.formats.FormatValue;
	import flashx.textLayout.formats.ITextLayoutFormat;
	import flashx.textLayout.formats.TextLayoutFormat;
	import flashx.textLayout.property.Property;
	import flashx.textLayout.tlf_internal;
	import flashx.undo.IUndoManager;
	import flashx.undo.UndoManager;

	use namespace tlf_internal;
	/**
	 *
	 *  @eventType flashx.textLayout.events.FlowOperationEvent.FLOW_OPERATION_BEGIN
	 *
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 */
	 
	[Event(name="flowOperationBegin", type="flashx.textLayout.events.FlowOperationEvent")]
	
	/**
	 * 
	 * @eventType flashx.textLayout.events.FlowOperationEvent.FLOW_OPERATION_END
	 *
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 */
	 
	[Event(name="flowOperationEnd", type="flashx.textLayout.events.FlowOperationEvent")]
	
	
	/**
	 * 
	 * @eventType flashx.textLayout.events.FlowOperationEvent.FLOW_OPERATION_COMPLETE
	 *
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 */
	
	[Event(name="flowOperationComplete", type="flashx.textLayout.events.FlowOperationEvent")]
	
	/** Dispatched whenever the selection is changed.  Primarily used to update selection-dependent user interface. 
	 *
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 */
	
	[Event(name="selectionChange", type="flashx.textLayout.events.SelectionEvent")]
	
	/** Dispatched after every recompose. 
	*
	* @playerversion Flash 10
	* @playerversion AIR 1.5
	* @langversion 3.0
	*/
	
	[Event(name="compositionComplete", type="flashx.textLayout.events.CompositionCompleteEvent")]
	
	/** Dispatched when the mouse is pressed down over any link. 
	 *
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 */
	
	[Event(name="mouseDown", type="flashx.textLayout.events.FlowElementMouseEvent")]
	
	/** Dispatched when the mouse is released over any link. 
	 *
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 */
	
	[Event(name="mouseUp", type="flashx.textLayout.events.FlowElementMouseEvent")]
	
	/** Dispatched when the mouse passes over any link. 
	 *
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 */
	
	[Event(name="mouseMove", type="flashx.textLayout.events.FlowElementMouseEvent")]	
	
	/** Dispatched when the mouse first enters any link. 
	 *
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 */
	
	[Event(name="rollOver", type="flashx.textLayout.events.FlowElementMouseEvent")]
	
	/** Dispatched when the mouse goes out of any link. 
	 *
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 */
	
	[Event(name="rollOut", type="flashx.textLayout.events.FlowElementMouseEvent")]	
	
	/** Dispatched when any link is clicked. 
	 *
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 */
	
	[Event(name="click", type="flashx.textLayout.events.FlowElementMouseEvent")]
	
	/** Dispatched when a InlineGraphicElement is resized due to having width or height as auto or percent 
	 * and the graphic has finished loading. 
	 *
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 */
	
	[Event(name="inlineGraphicStatusChanged", type="flashx.textLayout.events.StatusChangeEvent")]
	
	/** Dispatched by a TextFlow object after text is scrolled within a controller container.  
	 *
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 */
	
	[Event(name="scroll", type="flashx.textLayout.events.TextLayoutEvent")]
	
	/** Dispatched by a TextFlow object each time it is damaged 
	 *
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 */
	
	[Event(name="damage", type="flashx.textLayout.events.DamageEvent")]

	/** Dispatched by a TextFlow object each time a container has had new DisplayObjects added or updated as a result of composition.
	 *
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 */
	
	[Event(name="updateComplete", type="flashx.textLayout.events.UpdateCompleteEvent")]
		
	[Exclude(name="getBaseSWFContext",kind="method")]
	
	[Exclude(name="callInContext",kind="method")]
	/** Manages text in a container. Assumes that it manages all children of the container. 
	 * Consider using TextContainerManager for better performance in cases where there is a 
	 * one container per TextFlow, and the TextFlow is not the main focus, is static text, or
	 * is infrequently selected. Good for text in form fields, for example.
	 * 
	 * @includeExample examples\TextContainerManager.as -noswf
	 *
 	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 * 
	 * @see ContainerController
	 */			
	public class TextContainerManager extends EventDispatcher implements ISWFContext, IInteractionEventHandler, ISandboxSupport
	{		
		// all events that are listened for need to be in this list.
		static private const eventList:Array = [ 
			FlowOperationEvent.FLOW_OPERATION_BEGIN,
			FlowOperationEvent.FLOW_OPERATION_END,
			FlowOperationEvent.FLOW_OPERATION_COMPLETE,
			SelectionEvent.SELECTION_CHANGE,
			CompositionCompleteEvent.COMPOSITION_COMPLETE,
			MouseEvent.CLICK,		//from FlowElementMouseEvent
			MouseEvent.MOUSE_DOWN,	//from FlowElementMouseEvent
			MouseEvent.MOUSE_OUT,	//from FlowElementMouseEvent
			MouseEvent.MOUSE_UP,	//from FlowElementMouseEvent
			MouseEvent.MOUSE_OVER,	//from FlowElementMouseEvent
			MouseEvent.MOUSE_OUT,	//from FlowElementMouseEvent
			StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE,
		 	TextLayoutEvent.SCROLL,
			DamageEvent.DAMAGE,
			UpdateCompleteEvent.UPDATE_COMPLETE
		];
		
		/** Configuration to be used by the TextContainerManager.  This can only be set once and before the inputmanager is used.  */
		static private var _defaultConfiguration:IConfiguration = null;
		
		/** The default configuration for this TextContainerManager. Column and padding attributes
		 * are set to <code>FormatValue.INHERIT</code>.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 * 
	 	 * @see flashx.textLayout.elements.IConfiguration IConfiguration
	 	 * @see flashx.textLayout.formats.FormatValue#INHERIT FormatValue.INHERIT
		 */
		static public function get defaultConfiguration():IConfiguration
		{
			if (_defaultConfiguration == null)
				_defaultConfiguration = customizeConfiguration(null);
			return _defaultConfiguration; 
		}
		
		/** @private Make a configuration acceptable to the TCM */
		static tlf_internal function customizeConfiguration(config:IConfiguration):IConfiguration
		{
			var newConfig:Configuration;
			if (config)
			{
				if (config.flowComposerClass == TextLineFactoryBase.getDefaultFlowComposerClass())
					return config;
				newConfig = (config as Configuration).clone();
			}
			else
				newConfig = new Configuration();
			newConfig.flowComposerClass = TextLineFactoryBase.getDefaultFlowComposerClass();
			return newConfig;
		}
		
		static private var _inputManagerTextFlowFactory:TCMTextFlowTextLineFactory;
		static private function inputManagerTextFlowFactory():TCMTextFlowTextLineFactory
		{
			if (!_inputManagerTextFlowFactory)
				_inputManagerTextFlowFactory  = new TCMTextFlowTextLineFactory();
			return _inputManagerTextFlowFactory;
		}

		// dictionary of stringfactories so that they can share a configuration
		static private var stringFactoryDictionary:Dictionary;
		static private function inputManagerStringFactory(config:IConfiguration):StringTextLineFactory
		{
			if (!stringFactoryDictionary)
				stringFactoryDictionary = new Dictionary(true);
			var factory:StringTextLineFactory = stringFactoryDictionary[config];
			if (factory == null)
			{
				factory = new StringTextLineFactory(config);
				stringFactoryDictionary[config] = factory;
			}
			return factory;
		}
		
		/** @private Method to release all references to factories so they can be gc'ed, for example when Flex unloads a module. */
		static tlf_internal function releaseReferences():void
		{
			stringFactoryDictionary = null;
			_inputManagerTextFlowFactory = null;
		}
		
		/** Shared definition of the scrollPolicy property. @private */
		static tlf_internal const editingModePropertyDefinition:Property = Property.NewEnumStringProperty("editingMode", EditingMode.READ_WRITE, false, null, 
			EditingMode.READ_WRITE, EditingMode.READ_ONLY, EditingMode.READ_SELECT);	
		
		private var _container:Sprite;
		private var _compositionWidth:Number;
		private var _compositionHeight:Number;
		
		private var _text:String;
		private var _textDamaged:Boolean;				// indicates the _text property needs updating when sourceState is SOURCE_TEXTFLOW
		private var _lastSeparator:String;
		
		private var _hostFormat:ITextLayoutFormat;
		// textFlow format to be used by a string factory - combination of config.initialTextLayoutFormat and hostFormat
		private var _stringFactoryTextFlowFormat:ITextLayoutFormat;
		
		private var _contentTop:Number;
		private var _contentLeft:Number;
		private var _contentHeight:Number;
		private var _contentWidth:Number;
		
		private var _horizontalScrollPolicy:String;
		private var _verticalScrollPolicy:String;
		
		private var _swfContext:ISWFContext;
		private var _config:IConfiguration;
		
		/** @private */
		static tlf_internal const SOURCE_STRING:int = 0;
		/** @private */
		static tlf_internal const SOURCE_TEXTFLOW:int = 1;
		
		/** @private */
		static tlf_internal const COMPOSE_FACTORY:int = 0;
		/** @private */
		static tlf_internal const COMPOSE_COMPOSER:int = 1;
		
		/** @private */
		static tlf_internal const HANDLERS_NOTADDED:int  = 0;
		/** @private */
		static tlf_internal const HANDLERS_NONE:int      = 1;
		/** @private */
		static tlf_internal const HANDLERS_CREATION:int  = 2;
		/** @private */
		static tlf_internal const HANDLERS_ACTIVE:int    = 3;
		/** @private */
		static tlf_internal const HANDLERS_MOUSEWHEEL:int = 4;
		
		private var _sourceState:int;
		private var _composeState:int;
		private var _handlersState:int;
		// track hasFocus.  Depending on various factors focus and mouseDown can occur in different order
		private var _hasFocus:Boolean;
		private var _editingMode:String;
		private var _ibeamCursorSet:Boolean;
		private var _interactionCount:int;
		
		/** @private */
		tlf_internal function get sourceState():int
		{ return _sourceState; }
		/** @private */
		tlf_internal function get composeState():int
		{ return _composeState; }
		/** @private */
		tlf_internal function get handlersState():int
		{ return _handlersState; }
	
		// Tracks damage when sourceState is SOURCE_STRING. TODO - Might be worthwhile to always set and clear this
		private var _damaged:Boolean;			
		private var _textFlow:TextFlow;
		private var _needsRedraw:Boolean;
		
		/** Constructor function - creates a TextContainerManager instance.
		 *
		 * For best results:
		 * <ol>
		 *	<li>Start with TextContainerManager.defaultConfiguration and modify it</li>   
		 *	<li>Share the same Configuration among many InputManagers</li>
		 * </ol>
		 *
		 * @param container The DisplayObjectContainer in which to manage the text lines.
		 * @param config - The IConfiguration instance to use with this TextContainerManager instance. 
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0	 	
		 */
		public function TextContainerManager(container:Sprite,configuration:IConfiguration =  null)
		{
			_container = container;
			_compositionWidth = 100;
			_compositionHeight = 100;
			
			_config = configuration ? customizeConfiguration(configuration) : defaultConfiguration;				
			_config = (_config as Configuration).getImmutableClone();

			_horizontalScrollPolicy = _verticalScrollPolicy = String(ScrollPolicy.scrollPolicyPropertyDefinition.defaultValue);

			_damaged = true;
			_needsRedraw = false;
			_text = "";
			_textDamaged = false;
			
			_sourceState = SOURCE_STRING;
			_composeState = COMPOSE_FACTORY;
			_handlersState = HANDLERS_NOTADDED;
			_hasFocus = false;
			
			_editingMode = editingModePropertyDefinition.defaultValue as String;
			_ibeamCursorSet = false;
			_interactionCount = 0;
			
			if (_container is InteractiveObject)
			{
				_container.doubleClickEnabled = true;
				// so the textlines can be swapped on the first click and a double click still works
				_container.mouseChildren = false;
				_container.focusRect = false;
			}
		}

		/** Returns the container (DisplayObjectContainer) that holds the text that this TextContainerManager manages.
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 *
	 	 * @see ContainerController#container
	 	 */
	 	 
		public function get container():Sprite
		{ return _container; }
		
		/** Returns <code>true</code> if the content needs composing. 
		 * 
		 * @return	<code>true</code> if the content needs composing; <code>false</code> otherwise.
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 */
		public function isDamaged():Boolean
		{ return _composeState == COMPOSE_FACTORY ? _damaged : _textFlow.flowComposer.isDamaged(_textFlow.textLength); }
		
		/** Editing mode of this TextContainerManager. Modes are reading only, reading and selection permitted, 
		 * and editing (reading, selection, and writing)  permitted. Use the constant values of the EditingMode
		 * class to set this property. 
		 * <p>Default value is READ_WRITE.</p>
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 *
		 * @see flashx.textLayout.edit.EditingMode EditingMode
		 */
		public function get editingMode():String
		{ return _editingMode; }
		public function set editingMode(val:String):void
		{
			var newMode:String = editingModePropertyDefinition.setHelper(_editingMode, val) as String;
			
			if (newMode != _editingMode)
			{
				if (composeState == COMPOSE_COMPOSER)
				{
					_editingMode = newMode;
					invalidateInteractionManager();
				}
				else
				{
					removeActivationEventListeners();
					_editingMode = newMode;
					// there is no way to turn it on here if going from READ_ONLY to editable and mouse is over the inputmanager field
					if (_editingMode == EditingMode.READ_ONLY)
						removeIBeamCursor();
					addActivationEventListeners();
				}
			}
		}
		
		/**
		 * Returns the current text using a separator between paragraphs.
		 * The separator can be specified with the <code>separator</code>
		 * argument. The default value of the <code>separator</code> argument
		 * is the Unicode character <code>'PARAGRAPH SEPARATOR' (U+2029)</code>.
		 *
		 * <p>Calling the setter discards any attached TextFlow. Any selection is lost.</p>
		 * 
		 * @param separator String to set between paragraphs.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
	 	 */
		public function getText(separator:String = '\u2029'):String
		{
			if (_sourceState == SOURCE_STRING)
				return _text;

			if (_textDamaged || _lastSeparator != separator)
			{
				_text = "";
				var firstLeaf:FlowLeafElement = _textFlow.getFirstLeaf();
				if (firstLeaf != null)
				{
					var para:ParagraphElement = firstLeaf.getParagraph();
					while (para)
					{
						var nextPara:ParagraphElement = para.getNextParagraph();
						_text += para.getText();
						_text += nextPara ? separator : "";
						para = nextPara;
					}
				}
				_textDamaged = false;
				_lastSeparator = separator;
			}
			return _text;
		}
		/**
		 * Sets the <code>text</code> property to the specified String.
		 *
		 * Discards any attached TextFlow. Any selection is lost.
		 * 
		 * @param str the String to set
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
	 	 */
		public function setText(text:String):void
		{
			var hadPreviousSelection:Boolean = false;

			if (_sourceState == SOURCE_TEXTFLOW)
			{
				if (_textFlow.interactionManager && _textFlow.interactionManager.hasSelection())
					hadPreviousSelection = true;
				removeTextFlowListeners();
				if (_textFlow.flowComposer)
					_textFlow.flowComposer.removeAllControllers();
				_textFlow.unloadGraphics();
				_textFlow = null;
				_sourceState = SOURCE_STRING;
				_composeState = COMPOSE_FACTORY;
				if (_container is InteractiveObject)
					_container.mouseChildren = false;
				addActivationEventListeners();
			}
			_text = text ? text : ""; 
			_damaged = true;
			_textDamaged = false;
			
			// Generate a damage event 
			if (hasEventListener(DamageEvent.DAMAGE))
				dispatchEvent(new DamageEvent(DamageEvent.DAMAGE, false, false, null, 0, _text.length));
			
			// generate a selection changed event
			if (hadPreviousSelection && hasEventListener(SelectionEvent.SELECTION_CHANGE))
				dispatchEvent(new SelectionEvent(SelectionEvent.SELECTION_CHANGE, false, false, null));
			
			if (_hasFocus)
				requiredFocusInHandler(null);
		}
				
		/** Sets the format when display just a string.  If displaying a TextFlow this has no immediate effect.  The supplied ITextLayoutFormat is not copied.  Modifying it without calling this setter has indeterminate effects. */
		public function get hostFormat():ITextLayoutFormat
		{ return _hostFormat; }
		public function set hostFormat(val:ITextLayoutFormat):void
		{
			_hostFormat = val;
			_stringFactoryTextFlowFormat = null;
			
			if (_sourceState == SOURCE_TEXTFLOW)
				_textFlow.hostFormat = _hostFormat;
			if (_composeState == COMPOSE_FACTORY)
				_damaged = true;
		}
		
		/** Returns the horizontal extent allowed for text inside the container. The value is specified in pixels.
		 * 
		 * <p>After setting this property, the text in the container is damaged and requires composing.</p>
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0  
	 	 */
		public function get compositionWidth():Number
		{ return _compositionWidth; }
		public function set compositionWidth(val:Number):void
		{
			if (_compositionWidth == val || (isNaN(_compositionWidth) && isNaN(val)))
				return;
			_compositionWidth = val; 
			if (_composeState == COMPOSE_COMPOSER)
			{
				getController().setCompositionSize(_compositionWidth,_compositionHeight);
			}
			else
			{
				_damaged = true; 
			}
		}
	
		/** Returns the vertical extent allowed for text inside the container. The value is specified in pixels. 
		 * <p>After setting this property, the text in the container is damaged and requires composing.</p>
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 */
	 	 
		public function get compositionHeight():Number
		{ return _compositionHeight; }
		public function set compositionHeight(val:Number):void
		{
			if (_compositionHeight == val || (isNaN(_compositionHeight) && isNaN(val)))
				return;
			_compositionHeight = val; 
			if (_composeState == COMPOSE_COMPOSER)
			{
				getController().setCompositionSize(_compositionWidth,_compositionHeight);
			}
			else
			{
				_damaged = true; 
			}
		}
		
		/** The Configuration object for this TextContainerManager. 
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 *
	 	 * @see flashx.textLayout.IConfiguration IConfiguration
	 	 */
		public function get configuration():IConfiguration
		{ return _config; }
			
		/** Creates a rectangle that shows where the last call to either the <code>compose()</code> 
		 * method or the <code>updateContainer()</code> method placed the text.
		 *
		 * @return  the bounds of the content
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 *
	 	 * @see #compose()
	 	 * @see #updateContainer()
		 */
		public function getContentBounds():Rectangle
		{
			if (_composeState == COMPOSE_FACTORY)
				return new Rectangle(_contentLeft, _contentTop, _contentWidth, _contentHeight);
			var controller:ContainerController = getController();
			return controller.getContentBounds();
		}	
		
		/** The current TextFlow. Converts this to a full TextFlow representation if it 
		 * isn't already one. 
		 *
		 * @return 	the current TextFlow object
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 */
		public function getTextFlow():TextFlow
		{
			if (_sourceState != SOURCE_TEXTFLOW)
			{
				var wasDamaged:Boolean = isDamaged();
				convertToTextFlow();
				if (!wasDamaged)
					updateContainer();
			}
			return _textFlow;
		}

		/** Sets a TextFlow into this TextContainerManager replacing any existing TextFlow and discarding the 
		 * current text. 
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 */
		public function setTextFlow(textFlow:TextFlow):void
		{
			if (textFlow == _textFlow)
				return;
			
			if (textFlow == null)
			{
				setText(null);
				return;
			}

			// Remove the old textFlow from its TextContainerManager, if it has one
			if (textFlow.flowComposer && textFlow.flowComposer.numControllers > 0 && textFlow.flowComposer.getControllerAt(0) is TMContainerController)
			{
				var controller:TMContainerController = textFlow.flowComposer.getControllerAt(0) as TMContainerController;
				if (controller.textContainerManager && controller.textContainerManager.getTextFlow() == textFlow)
					controller.textContainerManager.setTextFlow(null);
			}  

			if (_sourceState == SOURCE_TEXTFLOW)
			{
				removeTextFlowListeners();
				if (_textFlow.flowComposer)
					_textFlow.flowComposer.removeAllControllers();
				_textFlow.unloadGraphics();
				_textFlow = null;
			}
				
			_textFlow = textFlow;
			// damages the entire flow
			_textFlow.hostFormat = hostFormat;
			_sourceState = SOURCE_TEXTFLOW;
			_composeState = textFlow.interactionManager || textFlow.mustUseComposer() ? COMPOSE_COMPOSER : COMPOSE_FACTORY;
			_textDamaged = true;
			addTextFlowListeners();
			
			if (_composeState == COMPOSE_COMPOSER)
			{
				// Possible issue - this clear call could be delayed until updateToController
				_container.mouseChildren = true;
				clearContainerChildren(true);
				clearComposedLines();
				_textFlow.flowComposer = new StandardFlowComposer();
				_textFlow.flowComposer.swfContext = _swfContext;
				_textFlow.flowComposer.addController(new TMContainerController(_container,_compositionWidth,_compositionHeight,this));
				
				invalidateInteractionManager();
				
				// always start with an empty selection
				if (_textFlow.interactionManager)
					_textFlow.interactionManager.selectRange(-1,-1);
			}
			else
				_damaged = true;
			
			if (_hasFocus)
				requiredFocusInHandler(null);
			
			addActivationEventListeners();
		}
		
		/** 
		 * Controls whether the factory generates all text lines or stops when the container bounds are filled.
		 * 
		 * @copy flashx.textLayout.container.ContainerController#horizontalScrollPolicy 
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
	 	 */
	 	public function get horizontalScrollPolicy():String
		{
			return _horizontalScrollPolicy;
		}
		public function set horizontalScrollPolicy(scrollPolicy:String):void
		{
			_horizontalScrollPolicy = ScrollPolicy.scrollPolicyPropertyDefinition.setHelper(_horizontalScrollPolicy, scrollPolicy) as String;
			if (_composeState == COMPOSE_COMPOSER)
				getController().horizontalScrollPolicy = _horizontalScrollPolicy;
			else
				_damaged = true;
		}
		
		/** 
		 * Controls whether the factory generates all text lines or stops when the container bounds are filled.
		 * 
		 * @copy flashx.textLayout.container.ContainerController#verticalScrollPolicy 
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
	 	 */
	 	 
		public function get verticalScrollPolicy():String
		{
			return _verticalScrollPolicy;
		}
		public function set verticalScrollPolicy(scrollPolicy:String):void
		{
			_verticalScrollPolicy = ScrollPolicy.scrollPolicyPropertyDefinition.setHelper(_verticalScrollPolicy, scrollPolicy) as String;
			if (_composeState == COMPOSE_COMPOSER)
				getController().verticalScrollPolicy = _verticalScrollPolicy;
			else
				_damaged = true;
		}
			
		/** 
		 * @copy flashx.textLayout.container.ContainerController#horizontalScrollPosition
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
	 	 */
		public function get horizontalScrollPosition():Number
		{ return _composeState == COMPOSE_COMPOSER ? getController().horizontalScrollPosition : 0; }
		public function set horizontalScrollPosition(val:Number):void
		{ 
			if (val == 0 && _composeState == COMPOSE_FACTORY)
				return;
			if (_composeState != COMPOSE_COMPOSER)
				convertToTextFlowWithComposer();
			getController().horizontalScrollPosition = val;
		}
		
		/** 
		 * @copy flashx.textLayout.container.ContainerController#verticalScrollPosition 
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
	 	 */
		public function get verticalScrollPosition():Number
		{ return _composeState == COMPOSE_COMPOSER ? getController().verticalScrollPosition : 0; }
		public function set verticalScrollPosition(val:Number):void
		{
			if (val == 0 && _composeState == COMPOSE_FACTORY)
				return;
			if (_composeState != COMPOSE_COMPOSER)
				convertToTextFlowWithComposer();
			getController().verticalScrollPosition = val;
		}

		/** 
		* @copy flashx.textLayout.container.ContainerController#getScrollDelta() 
		*
		* @playerversion Flash 10
		* @playerversion AIR 1.5
		* @langversion 3.0
	 	*/
		public function getScrollDelta(numLines:int):Number
		{
			if (_composeState != COMPOSE_COMPOSER)
				convertToTextFlowWithComposer();
			return getController().getScrollDelta(numLines);
		}
		
		/** 
		* @copy flashx.textLayout.container.ContainerController#scrollToRange() 
		*
		* @playerversion Flash 10
		* @playerversion AIR 1.5
		* @langversion 3.0
	 	*/
	 	public function scrollToRange(activePosition:int,anchorPosition:int):void
	 	{
			if (_composeState != COMPOSE_COMPOSER)
				convertToTextFlowWithComposer();
			getController().scrollToRange(activePosition,anchorPosition);	 		
	 	}

		/** 
		* Optional ISWFContext instance used to make FTE calls as needed in the proper swf context. 
		*
		* 
		* @see flashx.textLayout.compose.ISWFContext
		* 
		* @playerversion Flash 10
		* @playerversion AIR 1.5
	 	* @langversion 3.0
	 	*/
 	
		public function get swfContext():ISWFContext
		{ return _swfContext; }
		public function set swfContext(context:ISWFContext):void
		{ 
			_swfContext = context;
			if (_composeState == COMPOSE_COMPOSER)
				_textFlow.flowComposer.swfContext = _swfContext;
			else
				_damaged = true;
		}
		
		/** @private - TextContainerManager wraps an underlying swfcontext - tell it to FlowComposerBase so it can avoid extra invalidation */
		public function getBaseSWFContext():ISWFContext
		{ return _swfContext; }
				
		/** @private - this is part of a performance optimziation for reusing existing TextLines in place iff recreateTextLine is available. */
	    public function callInContext(fn:Function, thisArg:Object, argsArray:Array, returns:Boolean=true):*
		{
			var textBlock:TextBlock = thisArg as TextBlock;
			if (textBlock && _expectedFactoryCompose == TextLineFactoryBase._factoryComposer)
			{
			 	if (fn == textBlock.createTextLine)
					return createTextLine(textBlock,argsArray);
				if (Configuration.playerEnablesArgoFeatures && fn == thisArg["recreateTextLine"])
					return recreateTextLine(textBlock,argsArray);
			}

			var swfContext:ISWFContext = _swfContext ? _swfContext : BaseCompose.globalSWFContext;
	        if (returns)
	            return swfContext.callInContext(fn,thisArg,argsArray,returns);
			swfContext.callInContext(fn,thisArg,argsArray,returns);
		}
		
		public function resetLine(textLine:TextLine):void
		{
			// this line is being reset
			if (textLine == _composedLines[_composeRecycledInPlaceLines-1])
				_composeRecycledInPlaceLines--;
		}
		
		/** 
		 * Uses the <code>textBlock</code> parameter, and calls the <code>TextBlock.createTextLine()</code> method on it 
		 * using the remaining parameters.
		 * WARNING: modifies argsArray
		 *  
		 * @copy flash.text.engine.TextBlock
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 */
		private function createTextLine(textBlock:TextBlock, argsArray:Array):TextLine
		{
			var swfContext:ISWFContext = _swfContext ? _swfContext : BaseCompose.globalSWFContext;
			CONFIG::debug { assert(Configuration.playerEnablesArgoFeatures,"Bad call to createTextLine"); }

			if (_composeRecycledInPlaceLines < _composedLines.length && _expectedFactoryCompose == TextLineFactoryBase._factoryComposer)
			{
				var textLine:TextLine = _composedLines[_composeRecycledInPlaceLines++];

				argsArray.splice(0,0,textLine);
				return swfContext.callInContext(textBlock["recreateTextLine"],textBlock,argsArray);
			}

			return swfContext.callInContext(textBlock.createTextLine,textBlock,argsArray);
		}

		/** 
		 * Uses the <code>textBlock</code> parameter, and calls the <code>FlowComposerBase.recreateTextLine()</code> method on it 
		 * using the remaining parameters.
		 *
		 * @param textBlock The TextBlock to which the TextLine belongs.
		 * @param textLine  The TextLine to be recreated.
		 * @param previousLine Specifies the previously broken line after 
		 *	which breaking is to commence. Can be null when breaking the first line.  
		 * @param width Specifies the desired width of the line in pixels. The 
		 * 	actual width may be less.  
		 * @param lineOffset An optional parameter which specifies the difference in 
		 *	pixels between the origin of the line and the origin of the tab stops. This can be used when lines are not aligned, 
		 * 	but it is desirable for their tabs to be so. 
		 * @param fitSomething An optional parameter that instructs the runtime to fit at least one 
		 * 	character into the text line, no matter what width has been specified (even if width is zero or negative, which 
		 * 	would otherwise result in an exception being thrown).  
		 * @return The recreated TextLine instance.
		 *  
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 */
		private function recreateTextLine(textBlock:TextBlock, argsArray:Array):TextLine
		{
			var swfContext:ISWFContext = _swfContext ? _swfContext : BaseCompose.globalSWFContext;
			CONFIG::debug { assert(Configuration.playerEnablesArgoFeatures,"Bad call to createTextLine"); }

			if (_composeRecycledInPlaceLines < _composedLines.length)
			{
				CONFIG::debug {assert(argsArray[0] != _composedLines[_composeRecycledInPlaceLines],"Bad args"); }
				TextLineRecycler.addLineForReuse(argsArray[0]);	// not going to use this one
				argsArray[0] = _composedLines[_composeRecycledInPlaceLines++];
			}
			return swfContext.callInContext(textBlock["recreateTextLine"],textBlock,argsArray);
		}

		
		/** Returns the current ISelectionManager instance. Converts to TextFlow instance and creates one if necessary. 
		 *
		 * @return  the interaction manager for this TextContainerManager instance.
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 *
	 	 * @see flashx.textLayout.edit.ISelectionManager ISelectionManager
	 	 */
		public function beginInteraction():ISelectionManager
		{
			++_interactionCount;
			if (_composeState != COMPOSE_COMPOSER)
				convertToTextFlowWithComposer();
			return _textFlow.interactionManager;
		}
		
		/** Terminates interaction. 
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 *
		 * @see flashx.textLayout.edit.ISelectionManager ISelectionManager
	 	 */
		
		public function endInteraction():void
		{
			--_interactionCount;
		}
		
		/** Call this if you are editing, and want to reset the undo manager used for editing.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 *
		 */
		public function invalidateUndoManager():void
		{
			if (_editingMode == EditingMode.READ_WRITE)
				invalidateInteractionManager(true);
		}
		
		
		/** Call this if you change the selection formats (SelectionFormat) and want the interactionManager 
		 * to update. 
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 *
	 	 */
		public function invalidateSelectionFormats():void
		{
			invalidateInteractionManager();
		}
		
		/** The interactionManager is invalid - update it. Clients should call this if they change the 
		 * selectionFormats.  Its called automatically if editingMode is changed. */
		private function invalidateInteractionManager(alwaysRecreateManager:Boolean = false):void
		{
			if (_composeState == COMPOSE_COMPOSER)
			{
				var interactionManager:ISelectionManager = _textFlow.interactionManager;
				var activePos:int = interactionManager ? interactionManager.activePosition : -1
				var anchorPos:int = interactionManager ? interactionManager.anchorPosition : -1;

				if (_editingMode == EditingMode.READ_ONLY)
				{
					if (interactionManager)
						_textFlow.interactionManager = null;
				}
				else if (_editingMode == EditingMode.READ_WRITE)
				{
					if (alwaysRecreateManager || interactionManager == null || interactionManager.editingMode == EditingMode.READ_SELECT)
					{
						_textFlow.interactionManager = createEditManager(getUndoManager());
						if (_textFlow.interactionManager is SelectionManager)
							SelectionManager(_textFlow.interactionManager).cloneSelectionFormatState(interactionManager);
					}
				}
				else if (_editingMode == EditingMode.READ_SELECT)
				{
					if (alwaysRecreateManager || interactionManager == null || interactionManager.editingMode == EditingMode.READ_WRITE)
					{
						_textFlow.interactionManager = createSelectionManager();
						if (_textFlow.interactionManager is SelectionManager)
							SelectionManager(_textFlow.interactionManager).cloneSelectionFormatState(interactionManager);
					}
				}
				
				interactionManager = _textFlow.interactionManager;
				if (interactionManager)
				{
					interactionManager.unfocusedSelectionFormat  = getUnfocusedSelectionFormat();
					interactionManager.focusedSelectionFormat    = getFocusedSelectionFormat();
					interactionManager.inactiveSelectionFormat = getInactiveSelectionFormat();
					interactionManager.selectRange(anchorPos,activePos);
				}				
			}
		}
		
		/**Create a selection manager to use for selection. Override this method if you have a custom SelectionManager that you
		 * want to use in place of the default.
		 *
		 * @return	a new SelectionManager instance.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
		 */
		protected function createSelectionManager():ISelectionManager
		{
			return new SelectionManager();
		}
		
		/**Create an edit manager to use for editing. Override this method if you have a custom EditManager that you
		 * want to use in place of the default.
		 *
		 * @param  an IUndoManager instance for the EditManager being created.
		 * @return	the editing manager for this TextContainerManager instance.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
		 */
		protected function createEditManager(undoManager:flashx.undo.IUndoManager):IEditManager
		{
			return new EditManager(undoManager);
		}
		
		private function getController():TMContainerController
		{ return _textFlow.flowComposer.getControllerAt(0) as TMContainerController; }

		/** @private */
		tlf_internal var _composedLines:Array = [];
		
		/** Return the TextLine at the index from array of composed lines.
		 *
		 * @param index	Finds the line at this index position in the text.
		 *
		 * @return 	the TextLine that occurs at the specified index.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
		 */
		public function getLineAt(index:int):TextLine
		{ 
			// note: this method is not reliable for damaged text
			if (_composeState == COMPOSE_FACTORY)
			{
				// watch out for the empty TCM optimization and make a TextLine
				if (_sourceState == SOURCE_STRING && _text.length == 0 && !_damaged && _composedLines.length == 0)
				{					
					if (_needsRedraw)
						compose();
					else
						updateContainer();
					CONFIG::debug { assert(_composeState == COMPOSE_FACTORY,"no longer a factory??"); }
				}
				return _composedLines[index];
			}
			var tfl:TextFlowLine = _textFlow.flowComposer.getLineAt(index);
			return tfl ? tfl.getTextLine(true) : null;
		}
		
		/** @copy flashx.textLayout.compose.IFlowComposer#numLines 
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 */
		public function get numLines():int
		{ 
			// note: this method is not reliable for damaged text
			if (_composeState == COMPOSE_COMPOSER)
				return _textFlow.flowComposer.numLines;
			// watch out for possibly optimized zero length text
			if (_sourceState == SOURCE_STRING && _text.length == 0)
				return 1;
			return _composedLines.length; 
		}
		
		/** @private 
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 */
		tlf_internal function getActualNumLines():int
		{ 
			if (_composeState != COMPOSE_COMPOSER)
				convertToTextFlowWithComposer();
			// composes all lines
			_textFlow.flowComposer.composeToPosition();
			return _textFlow.flowComposer.numLines;
		}
		
		/** @private */
		tlf_internal function clearComposedLines():void
		{
			if (_composedLines)
				_composedLines.length = 0;
		}
		
		private function populateComposedLines(displayObject:DisplayObject):void
		{
			_composedLines.push(displayObject);
		}
		
		// TODO FOR ARGO - think about moving these variables into a separate helper class 
		private var _composeRecycledInPlaceLines:int;
		private var _composePushedLines:int;
		private function populateAndRecycleComposedLines(object:DisplayObject):void
		{
			var textLine:TextLine = object as TextLine;
			if (textLine)
			{
				CONFIG::debug { assert(_composePushedLines >= _composedLines.length || _composedLines[_composePushedLines] == textLine,"mismatched recycled textline"); }
				if (_composePushedLines >= _composedLines.length)
					_composedLines.push(textLine);
			}
			else	// this is the background color and goes at the head of the list
				_composedLines.splice(0,0,object);
			_composePushedLines++;
		}		
		
		static private var _expectedFactoryCompose:SimpleCompose;

		
		/** Composes the container text; calls either the factory or <code>updateAllControllers()</code>.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 */
		public function compose():void
		{
			if (_composeState == COMPOSE_COMPOSER)
				_textFlow.flowComposer.compose();
			else if (_damaged)
			{
				if (_sourceState == SOURCE_TEXTFLOW && _textFlow.mustUseComposer())
				{
					convertToTextFlowWithComposer(false);
					_textFlow.flowComposer.compose();
					return;
				}
				else
				{
					var callback:Function;
					if (Configuration.playerEnablesArgoFeatures)
					{
						// while the first thing in the array is not a TextLine its the background color OR its some floats OR something else from the last compose - remove it
						for (;;)
						{
							var firstObj:Object = _composedLines[0];
							if (firstObj == null || (firstObj is TextLine))
								break;
							_composedLines.splice(0,1);
						}
						_composeRecycledInPlaceLines = 0;
						_composePushedLines = 0;
						callback = populateAndRecycleComposedLines;
					}
					else
					{
						clearComposedLines();
						callback = populateComposedLines;
					}
					var inputManagerFactory:TextLineFactoryBase = (_sourceState == SOURCE_STRING) ? inputManagerStringFactory(_config) : inputManagerTextFlowFactory();
					inputManagerFactory.verticalScrollPolicy = _verticalScrollPolicy;
					inputManagerFactory.horizontalScrollPolicy = _horizontalScrollPolicy;
					inputManagerFactory.compositionBounds = new Rectangle(0,0,_compositionWidth,_compositionHeight);
					inputManagerFactory.swfContext = Configuration.playerEnablesArgoFeatures ? this : _swfContext;
					
					// compose can recurse for composing.  this sets up the swfContext so it doesn't recycle a line into a numberline
					_expectedFactoryCompose = TextLineFactoryBase.peekFactoryCompose();
					if (_sourceState == SOURCE_STRING)
					{
						var stringFactory:StringTextLineFactory = inputManagerFactory as StringTextLineFactory;
						if (!_stringFactoryTextFlowFormat)
						{
							if (_hostFormat == null)
								_stringFactoryTextFlowFormat = _config.textFlowInitialFormat;
							else
							{
								// mini cascade of initialFormat onto the hostFormat
								var format:TextLayoutFormat = new TextLayoutFormat(_hostFormat);
								TextLayoutFormat.resetModifiedNoninheritedStyles(format);
								var holderStyles:Object = (_config.textFlowInitialFormat as TextLayoutFormat).getStyles();
								for (var key:String in holderStyles)
								{
									var val:* = holderStyles[key];
									format[key] = (val !== FormatValue.INHERIT) ? val : _hostFormat[key];
								}
								_stringFactoryTextFlowFormat = format;
							}
						}
						if (!TextLayoutFormat.isEqual(stringFactory.textFlowFormat,_stringFactoryTextFlowFormat))
							stringFactory.textFlowFormat = _stringFactoryTextFlowFormat;
						stringFactory.text = _text;
						stringFactory.createTextLines(callback);
					}
					else
					{
						var factory:TCMTextFlowTextLineFactory = inputManagerFactory as TCMTextFlowTextLineFactory;
						factory.tcm = this;
						factory.createTextLines(callback,_textFlow);
						factory.tcm = null;
					}
					inputManagerFactory.swfContext = null;	// release any references to the swfContext
					_expectedFactoryCompose = null;
							
					if (Configuration.playerEnablesArgoFeatures)
						_composedLines.length = _composePushedLines;

					var bounds:Rectangle = inputManagerFactory.getContentBounds();
					
					_contentLeft   = bounds.x;
					_contentTop    = bounds.y;
					_contentWidth  = bounds.width;
					_contentHeight = bounds.height;
					_damaged = false;
					
					// generate a compositionComplete event.  Note that the last composed position isn't known
					if (hasEventListener(CompositionCompleteEvent.COMPOSITION_COMPLETE))
						dispatchEvent(new CompositionCompleteEvent(CompositionCompleteEvent.COMPOSITION_COMPLETE,false,false,_textFlow,0,-1));						
				}
				_needsRedraw = true;
			}

		}
		
		/** Updates the display; calls either the factory or updateAllControllers().
		 * 
		 * @return true if anything changed.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 */
		public function updateContainer():Boolean
		{
			if (_composeState == COMPOSE_COMPOSER)
				return _textFlow.flowComposer.updateAllControllers();
			
			compose();
			
			// depending on edits the Flow may now have a composer
			if (_composeState == COMPOSE_COMPOSER)
			{
				_textFlow.flowComposer.updateAllControllers();
				return true;
			}
				
			if (!_needsRedraw)
				return false;
			
			factoryUpdateContainerChildren();									
			drawBackgroundAndSetScrollRect(0,0);
					
			if (_handlersState == HANDLERS_NOTADDED)
				addActivationEventListeners();
	
			// generate a updateComplete event.  Note that the controller isn't known
			if (hasEventListener(UpdateCompleteEvent.UPDATE_COMPLETE))
				dispatchEvent(new UpdateCompleteEvent(UpdateCompleteEvent.UPDATE_COMPLETE,false,false,null));	
						
			_needsRedraw = false;
			return true;	// things changed
		}
		
		/** @private */
		tlf_internal function factoryUpdateContainerChildren():void
		{
			var textObject:DisplayObject; 	// scratch - TextLines and background shapes
			if (Configuration.playerEnablesArgoFeatures)
			{
				// while the first child in the container is a Shape - its the background color OR a Float OR something else - lose it
				while (_container.numChildren != 0)
				{
					textObject = _container.getChildAt(0);
					if (textObject is TextLine)
						break;
					_container.removeChildAt(0);
				}
				
				// add leading children _composedLines that are not TextLines into the Container
				for (var idx:int = 0; idx < _composedLines.length; idx++)
				{
					textObject = _composedLines[idx];
					if (textObject is TextLine)
						break;
					_container.addChildAt(textObject,idx);
				}
				
				// expect the leading lines are reused
				while (_container.numChildren < _composedLines.length)
					_container.addChild(_composedLines[_container.numChildren]);
				// recycle any trailing lines
				while (_container.numChildren > _composedLines.length)
				{
					var textLine:TextLine = _container.getChildAt(_composedLines.length) as TextLine;
					_container.removeChildAt(_composedLines.length);
					if (textLine)
					{
						// lines were rebroken but aren't being displayed
						if (textLine.validity == TextLineValidity.VALID)
							textLine.textBlock.releaseLines(textLine,textLine.textBlock.lastLine);
						textLine.userData = null;
						TextLineRecycler.addLineForReuse(textLine);
					}
				}
			}
			else
			{
				clearContainerChildren(false);
				
				for each (textObject in _composedLines)
					_container.addChild(textObject);
				
				clearComposedLines();
			}
		}
		
		private function addActivationEventListeners():void
		{	
			var newState:int =  HANDLERS_NONE;
			
			if (_composeState == COMPOSE_FACTORY)
			{
				if (_editingMode == EditingMode.READ_ONLY)
					newState = HANDLERS_MOUSEWHEEL;
				else
					newState = _handlersState == HANDLERS_NOTADDED ? HANDLERS_CREATION : HANDLERS_ACTIVE;
			}
			
			if (newState == _handlersState)
				return;
			
			removeActivationEventListeners();
				
			if (newState == HANDLERS_CREATION)
			{
				_container.addEventListener(FocusEvent.FOCUS_IN, requiredFocusInHandler);				
				_container.addEventListener(MouseEvent.MOUSE_OVER, requiredMouseOverHandler);
			}
			else if (newState == HANDLERS_ACTIVE)
			{
				_container.addEventListener(FocusEvent.FOCUS_IN, requiredFocusInHandler);				
				_container.addEventListener(MouseEvent.MOUSE_OVER, requiredMouseOverHandler);
				_container.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
				_container.addEventListener(MouseEvent.MOUSE_OUT,  mouseOutHandler);
				_container.addEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelHandler);
			//	_container.addEventListener(IMEEvent.IME_START_COMPOSITION, imeStartCompositionHandler);
			// attach by literal event name to avoid Argo dependency
				_container.addEventListener("imeStartComposition", imeStartCompositionHandler);
				
				// If TCM's getContextMenu returns null assume client has control of the contextMenu
				if (getContextMenu() != null)
					_container.contextMenu = _contextMenu;
				if (_container.contextMenu)
					_container.contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, menuSelectHandler);
		            
		        _container.addEventListener(Event.SELECT_ALL, editHandler);
			}
			else if (newState == HANDLERS_MOUSEWHEEL)
				_container.addEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelHandler);				
			
			_handlersState = newState;
		}
		
		// The ContextMenu to be used.  The idea is that this is undefined until createContextMenu is called and then 
		// createContextMenu is only called once and the result is shared with the ContainerController when it gets created
		private var _contextMenu:*;
		
		/** @private  Returns the already created contextMenu.  If not created yet create it.  */
		tlf_internal function getContextMenu():ContextMenu
		{
			if (_contextMenu === undefined)
				_contextMenu = createContextMenu();
			return _contextMenu;
		}

		private function removeActivationEventListeners():void
		{
			if (_handlersState == HANDLERS_CREATION)
			{
				CONFIG::debug { assert(_composeState != COMPOSE_COMPOSER,"Bad call to removeActivationEventListeners"); }
				_container.removeEventListener(FocusEvent.FOCUS_IN, requiredFocusInHandler);				
				_container.removeEventListener(MouseEvent.MOUSE_OVER, requiredMouseOverHandler);
			}
			else if (_handlersState == HANDLERS_ACTIVE)
			{
				CONFIG::debug { assert(_composeState != COMPOSE_COMPOSER,"Bad call to removeActivationEventListeners"); }
				_container.removeEventListener(FocusEvent.FOCUS_IN, requiredFocusInHandler);				
				_container.removeEventListener(MouseEvent.MOUSE_OVER, requiredMouseOverHandler);
				_container.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
				_container.removeEventListener(MouseEvent.MOUSE_OUT,  mouseOutHandler);
				_container.removeEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelHandler);
			//	_container.removeEventListener(IMEEvent.IME_START_COMPOSITION, imeStartCompositionHandler);
			// detach by literal event name to avoid Argo dependency
				_container.removeEventListener("imeStartComposition", imeStartCompositionHandler);
				// if _contextMenu is set then this TCM created the contextMenu and is manging it
				if (_container.contextMenu)
					_container.contextMenu.removeEventListener(ContextMenuEvent.MENU_SELECT, menuSelectHandler);
				// otherwise client is managing it
				if (_contextMenu)	
					_container.contextMenu = null;

		        _container.removeEventListener(Event.SELECT_ALL, editHandler);
			}
			else if (_handlersState == HANDLERS_MOUSEWHEEL)
			{
				CONFIG::debug { assert(_composeState != COMPOSE_COMPOSER,"Bad call to removeActivationEventListeners"); }
				_container.removeEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelHandler);		
			}

			_handlersState = HANDLERS_NOTADDED;
		}
		
		private function addTextFlowListeners():void
		{
			for each (var event:String in eventList)			
				_textFlow.addEventListener(event,dispatchEvent);
		}
		
		private function removeTextFlowListeners():void
		{
			for each (var event:String in eventList)			
				_textFlow.removeEventListener(event,dispatchEvent);
			_handlersState = HANDLERS_NONE;
		}
		
		/**
		 * @copy flash.events.IEventDispatcher#dispatchEvent()
		 * @private
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
 		 */
		public override function dispatchEvent(event:Event):Boolean
		{
			if (event.type == DamageEvent.DAMAGE)
			{
				_textDamaged = true;
				if (_composeState == COMPOSE_FACTORY)
					_damaged = true;
			}
			else if (event.type == FlowOperationEvent.FLOW_OPERATION_BEGIN)
			{
				if (_container.mouseChildren == false)
					_container.mouseChildren = true;
			}
			var result:Boolean = super.dispatchEvent(event);
			if (!result)
				event.preventDefault();
			return result;
		}
		
		/** @private */
		tlf_internal function clearContainerChildren(recycle:Boolean):void
		{
			while(_container.numChildren)
			{
				var textLine:TextLine = _container.getChildAt(0) as TextLine;
				_container.removeChildAt(0);
				if (textLine)
				{
					// releasing all textLines so release each still connected textBlock
					if (textLine.validity != TextLineValidity.INVALID && textLine.validity != TextLineValidity.STATIC)
					{
						var textBlock:TextBlock = textLine.textBlock;
						CONFIG::debug { Debugging.traceFTECall(null,textBlock,"releaseLines",textBlock.firstLine, textBlock.lastLine); }	
						textBlock.releaseLines(textBlock.firstLine,textBlock.lastLine);
					}					
					if (recycle)
					{
						textLine.userData = null;	// clear any userData
						TextLineRecycler.addLineForReuse(textLine);
					}
				}
			}
		}
		
		private function convertToTextFlow():void
		{
			CONFIG::debug { assert(_sourceState != SOURCE_TEXTFLOW,"bad call to convertToTextFlow"); }
									
			_textFlow = new TextFlow(_config);
			_textFlow.hostFormat = _hostFormat;
			if(_swfContext)
			{
				_textFlow.flowComposer.swfContext = _swfContext;
			}
	
			var p:ParagraphElement = new ParagraphElement();
			_textFlow.addChild(p)
			var s:SpanElement = new SpanElement();
			s.text = _text;
			p.addChild(s);
			_sourceState = SOURCE_TEXTFLOW;
			addTextFlowListeners();			
		}
				
		/** @private */
		tlf_internal function convertToTextFlowWithComposer(callUpdateContainer:Boolean = true):void
		{
			removeActivationEventListeners();
			
			if (_sourceState != SOURCE_TEXTFLOW)
				convertToTextFlow();
			
			if (_composeState != COMPOSE_COMPOSER)
			{
				clearContainerChildren(true);
				clearComposedLines();
				var controller:TMContainerController = new TMContainerController(_container,_compositionWidth,_compositionHeight,this);
				_textFlow.flowComposer = new StandardFlowComposer();
				_textFlow.flowComposer.addController(controller);
				_textFlow.flowComposer.swfContext = _swfContext;
				_composeState = COMPOSE_COMPOSER;
				
				invalidateInteractionManager();
				if (callUpdateContainer)
					updateContainer();
			}
		}
		
		private function get effectiveBlockProgression():String
		{
			if (_textFlow)
				return _textFlow.computedFormat.blockProgression;
			return _hostFormat && _hostFormat.blockProgression && _hostFormat.blockProgression != FormatValue.INHERIT ? _hostFormat.blockProgression : BlockProgression.TB;
		}
		
		/* CONFIG::debug private static function doTrace(msg:String):void
		{ trace(msg); } */
		
		private function removeIBeamCursor():void
		{
			if (_ibeamCursorSet)
			{
				Mouse.cursor = MouseCursor.AUTO;
				_ibeamCursorSet = false;
			}
		}
		
		private var _hasScrollRect:Boolean = false;
		
		/** 
		 * Specifies whether this container has attached a ScrollRect object. Value is <code>true</code>
		 * or <code>false</code>. A display object is cropped to the size defined by the scroll rectangle, and 
		 * it scrolls within the rectangle when you change the x and y properties of the scrollRect object. 
		 *
		 * <p>This property enables a client to test for a ScrollRect object without accessing 
		 * the DisplayObject.scrollRect property, which can have side effects in some cases.</p> 
		 *
		 * @return true if the controller has attached a ScrollRect instance.
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 *
		 * @see #drawBackgroundAndSetScrollRect 
		 */
		private function get hasScrollRect():Boolean
		{ return _hasScrollRect; }
		private function set hasScrollRect(value:Boolean):void
		{ _hasScrollRect = value; }
		
		/**   
		 * Returns <code>true</code> if it has filled in the container's scrollRect property.  
		 * This method enables you to test whether <code>scrollRect</code> is set without actually accessing the <code>scrollRect</code> property 
		 * which can possibly create a  performance issue. 
		 * <p>Override this method to draw a background or a border.  Overriding this method can be tricky as the scrollRect <bold>must</bold> 
		 * be set as specified.</p>
		 * 
		 * @param scrollX The starting horizontal position of the scroll rectangle.
		 * @param scrollY The starting vertical position of the scroll rectangle.
		 * 
		 * @return 	<code>true</code> if it has created the <code>scrollRect</code> object.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 */
		public function drawBackgroundAndSetScrollRect(scrollX:Number,scrollY:Number):Boolean
		{
			var cont:Sprite = this.container;

 			var contentWidth:Number;
			var contentHeight:Number;
			if (_composeState == COMPOSE_FACTORY)
			{
				contentWidth = _contentWidth;
				contentHeight = _contentHeight;
			}
			else
			{
				var controller:ContainerController = getController();
				contentWidth = controller.contentWidth;
				contentHeight = controller.contentHeight;
			}
			var width:Number;
			if (isNaN(compositionWidth))
			{
				var contentLeft:Number = (_composeState == COMPOSE_FACTORY) ? _contentLeft : controller.contentLeft;
				width = contentLeft + contentWidth - scrollX;
			}
			else
				width = compositionWidth;
			var height:Number;
			if (isNaN(compositionHeight))
			{ 
				var contentTop:Number = (_composeState == COMPOSE_FACTORY) ? _contentTop : controller.contentTop;
				height = contentTop + contentHeight - scrollY;
			}
			else
				height = compositionHeight;
			
			if (scrollX == 0 && scrollY == 0 && contentWidth <= width && contentHeight <= height)
			{
				// skip the scrollRect
				if (_hasScrollRect)
				{
					cont.scrollRect = null;
					_hasScrollRect = false;					
				}
			}
			else
			{
				cont.scrollRect = new Rectangle(scrollX, scrollY, width, height);
				_hasScrollRect = true;
				
				// adjust to the values actually in the scrollRect
				scrollX = cont.scrollRect.x;
				scrollY = cont.scrollRect.y;
				width = cont.scrollRect.width;
				height = cont.scrollRect.height;
			}
			
	        // NOTE: must draw a background for interaction support - even it if is 100% transparent
	        var s:Sprite = cont as Sprite;
	        if (s)
	        {
				s.graphics.clear();
				s.graphics.beginFill(0, 0); 
		       	s.graphics.drawRect(scrollX,scrollY,width,height);
		        s.graphics.endFill();
		    }
	
	        return _hasScrollRect;
		}
		
		/** Returns the focusedSelectionFormat - by default get it from the configuration.
		 * This can be overridden in the subclass to supply a different SelectionFormat
		 */
		protected function getFocusedSelectionFormat():SelectionFormat
		{
			return _config.focusedSelectionFormat;
		}
		
		/** Returns the inactiveSelectionFormat - by default get it from the configuration 
		 * This can be overridden in the subclass to supply a different SelectionFormat
		 */
		protected function getInactiveSelectionFormat():SelectionFormat
		{
			return _config.inactiveSelectionFormat;
		}
		
		/** Returns the unfocusedSelectionFormat - by default get it from the configuration 
		 * You can override this method in the subclass to supply a different SelectionFormat.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 */
		protected function getUnfocusedSelectionFormat():SelectionFormat
		{
			return _config.unfocusedSelectionFormat;
		}
		
		/** 
		 * Returns the undo manager to use. By default, creates a unique undo manager. 
		 * You can override this method in the subclass if you want to customize the undo manager
		 * (for example, to use a shared undo manager for multiple TextContainerManager instances).
		 *
		 * @return 	new IUndoManager instance.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
	 	 */
		 
		protected function getUndoManager():IUndoManager
		{
			return new UndoManager();
		}
						
		/** Creates a ContextMenu for the TextContainerManager. Use the methods of the ContextMenu 
		 *  class to add items to the menu. 
		 * <p>You can override this method to define a custom context menu.</p>
		 *
		 * @return 	the created context menu.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 *
		 * @see flash.ui.ContextMenu ContextMenu
		 */
		protected function createContextMenu():ContextMenu
		{
			return ContainerController.createDefaultContextMenu();
		}
		/** @copy flashx.textLayout.container.ContainerController#editHandler()
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
 		 * @langversion 3.0
 		 *
 		 * @see flash.events.Event Event
		 */	
		public function editHandler(event:Event):void
		{
			if (_composeState == COMPOSE_FACTORY)
			{
				convertToTextFlowWithComposer();
				getController().editHandler(event);
				_textFlow.interactionManager.setFocus();
			}
			else
				getController().editHandler(event);
		}
		
		/** @copy flashx.textLayout.container.ContainerController#keyDownHandler() 
		*
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
 		* @see flash.events.KeyboardEvent#KEY_DOWN KeyboardEvent.KEY_DOWN
		*/	
		public function keyDownHandler(event:KeyboardEvent):void
		{
			if (_composeState == COMPOSE_COMPOSER)
				getController().keyDownHandler(event);
		}
		
		/** @copy flashx.textLayout.container.ContainerController#keyUpHandler().
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
 		* @see flash.events.KeyboardEvent#KEY_UP KeyboardEvent.KEY_UP
		*/	
		public function keyUpHandler(event:KeyboardEvent):void
		{
			if (_composeState == COMPOSE_COMPOSER)
				getController().keyUpHandler(event);
		}

		/** @copy flashx.textLayout.container.ContainerController#keyFocusChangeHandler().
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
 	 	 * @langversion 3.0
		 * 	@param	event	the FocusChange event
		 */	
		public function keyFocusChangeHandler(event:FocusEvent):void
		{
			if (_composeState == COMPOSE_COMPOSER)
				getController().keyFocusChangeHandler(event);
		}
		
		/** @copy flashx.textLayout.container.ContainerController#textInputHandler()
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
 		* @see flash.events.TextEvent#TEXT_INPUT TextEvent.TEXT_INPUT
		*/
		public function textInputHandler(event:TextEvent):void
		{
			if (_composeState == COMPOSE_COMPOSER)
				getController().textInputHandler(event);
		}

		/** Processes the <code>IME_START_COMPOSITION</code> event when the client manages events.
		 *
		 * @param event  The IMEEvent object.
		 *
		 * @playerversion Flash 10.1
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 * 
		 *
		 * @see flash.events.IMEEvent#IME_START_COMPOSITION IMEEvent.IME_START_COMPOSITION
		 */
		public function imeStartCompositionHandler(event:IMEEvent):void
		{
			if (_composeState == COMPOSE_COMPOSER)
				getController().imeStartCompositionHandler(event);
		}
		
		/** Processes the <code>SOFT_KEYBOARD_ACTIVATING</code> event when the client manages events.
		 *
		 * @param event  The SoftKeyboardEvent object.
		 *
		 * @playerversion Flash 10.2
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 * 
		 *
		 * @see flash.events.SoftKeyboardEvent#SOFT_KEYBOARD_ACTIVATING SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATING
		 */
		public function softKeyboardActivatingHandler(event:Event):void
		{
			if (_composeState == COMPOSE_COMPOSER)
				getController().softKeyboardActivatingHandler(event);
		}
		
		/** @copy flashx.textLayout.container.ContainerController#mouseDownHandler()
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
 		* @see flash.events.MouseEvent#MOUSE_DOWN MouseEvent.MOUSE_DOWN
		*/	
		public function mouseDownHandler(event:MouseEvent):void
		{
			// doTrace("IM:mouseDownHandler");
			// before the mouseDown do a mouseOver
			if (_composeState == COMPOSE_FACTORY)
			{
				CONFIG::debug { assert(event.currentTarget == this.container,"TextContainerManager:mouseDownHandler - unexpected currentTarget"); }
				convertToTextFlowWithComposer();
				getController().requiredFocusInHandler(null);
				getController().requiredMouseOverHandler(event.target != container ? new RemappedMouseEvent(event) : event);
				if (_hasFocus)
					getController().requiredFocusInHandler(null);
				getController().requiredMouseDownHandler(event);
			}
			else
				getController().mouseDownHandler(event);
		}

		/** @copy flashx.textLayout.container.ContainerController#mouseMoveHandler()
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
 		* @see flash.events.MouseEvent#MOUSE_MOVE MouseEvent.MOUSE_MOVE
		*/	
		public function mouseMoveHandler(event:MouseEvent):void
		{
			if (_composeState == COMPOSE_COMPOSER)
				getController().mouseMoveHandler(event);
		}
		
		/** @copy flashx.textLayout.container.ContainerController#mouseUpHandler()
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
 		* @see flash.events.MouseEvent#MOUSE_UP MouseEvent.MOUSE_UP
		*/	
		public function mouseUpHandler(event:MouseEvent):void
		{
			if (_composeState == COMPOSE_COMPOSER)
				getController().mouseUpHandler(event);
		}
		
		/** @copy flashx.textLayout.container.ContainerController#mouseDoubleClickHandler()
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
 		* @see flash.events.MouseEvent#DOUBLE_CLICK MouseEvent.DOUBLE_CLICK
		*/	
		public function mouseDoubleClickHandler(event:MouseEvent):void
		{
			if (_composeState == COMPOSE_COMPOSER)
				getController().mouseDoubleClickHandler(event);
		}

		/** @private Process a mouseOver event.
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
		*/			
		tlf_internal final function requiredMouseOverHandler(event:MouseEvent):void
		{
			if (_composeState == COMPOSE_FACTORY)
				mouseOverHandler(event);
			if (_composeState == COMPOSE_COMPOSER)
				getController().requiredMouseOverHandler(event);
		}
		

		/** Process a mouseOver event.
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
 		* @see flash.events.MouseEvent#MOUSE_OVER MouseEvent.MOUSE_OVER
		*/			
		public function mouseOverHandler(event:MouseEvent):void
		{
			if (_composeState == COMPOSE_COMPOSER)
				getController().mouseOverHandler(event);
			else
			{
				// doTrace("IM:mouseOverHandler");
				if (effectiveBlockProgression != BlockProgression.RL)
				{
					Mouse.cursor = MouseCursor.IBEAM;
					_ibeamCursorSet = true;
				}	
				addActivationEventListeners();
			}
		}
		/** @copy flashx.textLayout.container.ContainerController#mouseOutHandler()
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
 		* @see flash.events.MouseEvent#MOUSE_OUT MouseEvent.MOUSE_OUT
		*/					
		public function mouseOutHandler(event:MouseEvent):void
		{
			// doTrace("IM:mouseOutHandler");
			if (_composeState == COMPOSE_FACTORY)
				removeIBeamCursor();
			else
				getController().mouseOutHandler(event);
		}		
		/** @copy flashx.textLayout.container.ContainerController#focusInHandler()
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
 		* @see flash.events.FocusEvent#FOCUS_IN FocusEvent.FOCUS_IN
		*/

		
		/** Process a focusIn event.
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
		*/
		public function focusInHandler(event:FocusEvent):void
		{
			_hasFocus = true;
			if (_composeState == COMPOSE_COMPOSER)
				getController().focusInHandler(event);
		}
		
		/** @private hook to get at requiredFocusOutHandler as needed */
		tlf_internal function requiredFocusOutHandler(event:FocusEvent):void
		{
			if (_composeState == COMPOSE_COMPOSER)
				getController().requiredFocusOutHandler(event);
		}
		/** @copy flashx.textLayout.container.ContainerController#focusOutHandler()
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
 		* @see flash.events.FocusEvent#FOCUS_OUT FocusEvent.FOCUS_OUT
		*/
		public function focusOutHandler(event:FocusEvent):void
		{
			_hasFocus = false;
			if (_composeState == COMPOSE_COMPOSER)
				getController().focusOutHandler(event);
		}

		/** @copy flashx.textLayout.container.ContainerController#activateHandler()
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
 		* @see flash.events.Event#ACTIVATE Event.ACTIVATE
		*/				
		public function activateHandler(event:Event):void
		{
			if (_composeState == COMPOSE_COMPOSER)
				getController().activateHandler(event);
		}		
		/** @copy flashx.textLayout.container.ContainerController#deactivateHandler()
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
 		* @see flash.events.Event#DEACTIVATE Event.DEACTIVATE
		*/				
		public function deactivateHandler(event:Event):void
		{
			if (_composeState == COMPOSE_COMPOSER)
				getController().deactivateHandler(event);
		}
		
		/** @copy flashx.textLayout.container.ContainerController#focusChangeHandler()
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
 		*
 		* @see flash.events.FocusEvent#KEY_FOCUS_CHANGE FocusEvent.KEY_FOCUS_CHANGE
		* @see flash.events.FocusEvent#MOUSE_FOCUS_CHANGE FocusEvent.MOUSE_FOCUS_CHANGE
		*/				
		public function focusChangeHandler(event:FocusEvent):void
		{
			if (_composeState == COMPOSE_COMPOSER)
				getController().focusChangeHandler(event);
		}
		
		/** @copy flashx.textLayout.container.ContainerController#menuSelectHandler()
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
 		*
 		* @see flash.events.ContextMenuEvent#MENU_SELECT ContextMenuEvent.MENU_SELECT
		*/				
		public function menuSelectHandler(event:ContextMenuEvent):void
		{
			if (_composeState == COMPOSE_FACTORY)
			{
				// there is no selection
				var contextMenu:ContextMenu = _container.contextMenu as ContextMenu;
				if (contextMenu)
				{
					var cbItems:ContextMenuClipboardItems = contextMenu.clipboardItems;
					cbItems.selectAll = _editingMode != EditingMode.READ_ONLY;
					cbItems.clear = false;
					cbItems.copy = false;
					cbItems.cut = false;
					cbItems.paste = false;
				}
			}
			else
				getController().menuSelectHandler(event);			
		}
		
		/** @copy flashx.textLayout.container.ContainerController#mouseWheelHandler()
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
 		*
 		* @see flash.events.MouseEvent#MOUSE_WHEEL MouseEvent.MOUSE_WHEEL
		*/				
		public function mouseWheelHandler(event:MouseEvent):void
		{
			if (event.isDefaultPrevented())
				return;

			if (_composeState == COMPOSE_FACTORY)
			{
				convertToTextFlowWithComposer();
				getController().requiredMouseOverHandler(event);
			}
			getController().mouseWheelHandler(event);
		}

		
		/** @private required FocusIn handler.  Clients override focusInHandler
		* @playerversion Flash 10
		* @playerversion AIR 1.5
 		* @langversion 3.0
		*/
		tlf_internal final function requiredFocusInHandler(event:FocusEvent):void
		{			
			// doTrace("IM:focusInHandler");
			if (_composeState == COMPOSE_FACTORY)
			{
				addActivationEventListeners();
				focusInHandler(event);
			}			
			if (_composeState == COMPOSE_COMPOSER)
				getController().requiredFocusInHandler(event);
		}
		
		/** 
		 * Called to request clients to begin the forwarding of mouseup and mousemove events from outside a security sandbox.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 *
		 */
		public function beginMouseCapture():void
		{ }
		/** 
		 * Called to inform clients that the the forwarding of mouseup and mousemove events from outside a security sandbox is no longer needed.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 *
		 */
		public function endMouseCapture():void
		{ }
		/** Client call to forward a mouseUp event from outside a security sandbox.  Coordinates of the mouse up are not needed.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 *
		 */
		public function mouseUpSomewhere(e:Event):void
		{
			if (_composeState == COMPOSE_COMPOSER)
				getController().mouseUpSomewhere(e);
		}
		/** Client call to forward a mouseMove event from outside a security sandbox.  Coordinates of the mouse move are not needed.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 *
		 */		
		public function mouseMoveSomewhere(e:Event):void
		{ 
			if (_composeState == COMPOSE_COMPOSER)
				getController().mouseUpSomewhere(e);
		}
	
		/** @private
		 * Gets the index at which the first text line must appear in its parent.
		 * The default implementation of this method, which may be overriden, returns the child index 
		 * of the first <code>flash.text.engine.TextLine</code> child of <code>container</code>
		 * if one exists, and that of the last child of <code>container</code> otherwise. 
		 * 
		 * @return the index at which the first text line must appear in its parent.
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 * 
		 * @see flash.text.engine.TextLine
		 * @see #container
		 */	
		tlf_internal function getFirstTextLineChildIndex():int
		{			
			// skip past any non-TextLine children below the text in the container,
			// This also means that in a container devoid of text, we will always
			// populate the text starting at index container.numChildren, which is intentional.
			var firstTextLine:int;
			for(firstTextLine = 0; firstTextLine<_container.numChildren; ++firstTextLine)
			{
				if(_container.getChildAt(firstTextLine) is TextLine)
				{
					break;
				}
			}
			return firstTextLine;
		}
		
		/** @private
		 * Adds a <code>flash.text.engine.TextLine</code> object as a descendant of <code>container</code>.
		 * The default implementation of this method, which may be overriden, adds the object
		 * as a direct child of <code>container</code> at the specified index.
		 * 
		 * @param textLine the <code>flash.text.engine.TextLine</code> object to add
		 * @param index insertion index of the text line in its parent 
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 * 
		 * @see flash.text.engine.TextLine
		 * @see #container
		 * 
		 */	
		tlf_internal function addTextLine(textLine:TextLine, index:int):void
		{ 
			_container.addChildAt(textLine, index);
		}
		
		/** @private
		 * Removes a <code>flash.text.engine.TextLine</code> object from its parent. 
		 * The default implementation of this method, which may be overriden, removes the object
		 * from <code>container</code> if it is a direct child of the latter.
		 * 
		 * This method may be called even if the object is not a descendant of <code>container</code>.
		 * Any implementation of this method must ensure that no action is taken in this case.
		 * 
		 * @param textLine the <code>flash.text.engine.TextLine</code> object to remove 
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 * 
		 * @see flash.text.engine.TextLine
		 * @see #container
		 * 
		 */	
		tlf_internal function removeTextLine(textLine:TextLine):void
		{
			if (_container.contains(textLine))
				_container.removeChild(textLine);
		}
		
		/** @private
		 * Adds a <code>flash.display.Shape</code> object on which background shapes (such as background color) are drawn.
		 * The default implementation of this method, which may be overriden, adds the object to <code>container</code>
		 * just before the first <code>flash.text.engine.TextLine</code> child, if one exists, and after the last exisiting
		 * child otherwise. 
		 * 
		 * @param shape <code>flash.display.Shape</code> object to add
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 * 
		 * @see flash.display.Shape
		 * @see flash.text.engine.TextLine
		 * @see #container
		 * 
		 */
		tlf_internal function addBackgroundShape(shape:Shape):void	// No PMD
		{
			_container.addChildAt(shape, getFirstTextLineChildIndex());
		}
		
		/** @private
		 * Removes a <code>flash.display.Shape</code> object on which background shapes (such as background color) are drawn.
		 * The default implementation of this method, which may be overriden, removes the object from its <code>parent</code>.
		 * 
		 * @param shape <code>flash.display.Shape</code> object to remove
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 * 
		 * @see flash.display.Shape
		 * @see flash.text.engine.TextLine
		 * @see #container
		 * 
		 */
		tlf_internal function removeBackgroundShape(shape:Shape):void	
		{
			if (shape.parent)
				shape.parent.removeChild(shape);
		}
		
		/** @private
		 * Adds a <code>flash.display.DisplayObjectContainer</code> object to which selection shapes (such as block selection highlight, cursor etc.) are added.
		 * The default implementation of this method, which may be overriden, has the following behavior:
		 * The object is added just before first <code>flash.text.engine.TextLine</code> child of <code>container</code> if one exists 
		 * and the object is opaque and has normal blend mode. 
		 * In all other cases, it is added as the last child of <code>container</code>.
		 * 
		 * @param selectionContainer <code>flash.display.DisplayObjectContainer</code> object to add
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 * 
		 * @see flash.display.DisplayObjectContainer
		 * @see flash.text.engine.TextLine
		 * @see #container
		 */
		tlf_internal function addSelectionContainer(selectionContainer:DisplayObjectContainer):void
		{
			if (selectionContainer.blendMode == BlendMode.NORMAL && selectionContainer.alpha == 1)
			{
				// don't put selection behind background color or existing content in container, put it behind first text line
				_container.addChildAt(selectionContainer, getFirstTextLineChildIndex());
			}
			else
				_container.addChild(selectionContainer);
		}
		
		/** @private
		 * Removes the <code>flash.display.DisplayObjectContainer</code> object which contains selection shapes (such as block selection highlight, cursor etc.).
		 * The default implementation of this method, which may be overriden, removes the object from its parent if one exists.
		 * 
		 * @param selectionContainer <code>flash.display.DisplayObjectContainer</code> object to remove
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 * 
		 * @see flash.display.DisplayObjectContainer
		 * @see #container
		 * 
		 */
		tlf_internal function removeSelectionContainer(selectionContainer:DisplayObjectContainer):void
		{	
			selectionContainer.parent.removeChild(selectionContainer);
		}
		
		/** @private
		 * Adds a <code>flash.display.DisplayObject</code> object as a descendant of <code>parent</code>.
		 * The default implementation of this method, which may be overriden, adds the object
		 * as a direct child of <code>parent</code> at the specified index. This is called to add 
		 * InlineGraphicElements to the TextLine or container.
		 * 
		 * @param parent the <code>flash.display.DisplayObjectContainer</code> object to add the inlineGraphicElement to
		 * @param inlineGraphicElement the <code>flash.display.DisplayObject</code> object to add
		 * @param index insertion index of the float in its parent 
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 2.0
		 * @langversion 3.0
		 * 
		 * @see flash.display.DisplayObjectContainer
		 * @see flash.display.DisplayObject
		 * @see #container
		 * 
		 */	
		tlf_internal function addInlineGraphicElement(parent:DisplayObjectContainer, inlineGraphicElement:DisplayObject, index:int):void
		{
			parent.addChildAt(inlineGraphicElement, index);
		}
		
		/** @private
		 * Removes a <code>flash.display.DisplayObject</code> object from its parent. 
		 * The default implementation of this method, which may be overriden, removes the object
		 * from <code>container</code> if it is a direct child of the latter.
		 * 
		 * This method may be called even if the object is not a descendant of <code>parent</code>.
		 * Any implementation of this method must ensure that no action is taken in this case.
		 * 
		 * @param float the <code>flash.display.DisplayObject</code> object to remove 
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 2.0
		 * @langversion 3.0
		 * 
		 * @see flash.display.DisplayObjectContainer
		 * @see flash.display.DisplayObject
		 * @see #container
		 * 
		 */	
		tlf_internal function removeInlineGraphicElement(parent:DisplayObjectContainer, inlineGraphicElement:DisplayObject):void
		{
			if (inlineGraphicElement.parent == parent)
				parent.removeChild(inlineGraphicElement);
		}
	
	}
	
}

import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.text.engine.TextLine;
import flash.ui.ContextMenu;

import flashx.textLayout.compose.IFlowComposer;
import flashx.textLayout.compose.SimpleCompose;
import flashx.textLayout.container.ContainerController;
import flashx.textLayout.container.ScrollPolicy;
import flashx.textLayout.container.TextContainerManager;
import flashx.textLayout.edit.IInteractionEventHandler;
import flashx.textLayout.elements.ContainerFormattedElement;
import flashx.textLayout.factory.FactoryDisplayComposer;
import flashx.textLayout.factory.TextFlowTextLineFactory;
import flashx.textLayout.factory.TextLineFactoryBase;
import flashx.textLayout.formats.BackgroundColor;
import flashx.textLayout.formats.BlockProgression;
import flashx.textLayout.tlf_internal;

use namespace tlf_internal;

class TMContainerController extends ContainerController
{
	private var _inputManager:TextContainerManager;
	
	public function TMContainerController(container:Sprite, compositionWidth:Number, compositionHeight:Number, tm:TextContainerManager)
	{
		super(container,compositionWidth,compositionHeight);
		_inputManager = tm;
		verticalScrollPolicy = tm.verticalScrollPolicy;
		horizontalScrollPolicy = tm.horizontalScrollPolicy;
	}

	public function get textContainerManager():TextContainerManager { return _inputManager; }
	
	/** Reroute to the TextContainerManger's override.  Reuse the one that's already been created. */
	protected override function createContextMenu():ContextMenu
	{ return _inputManager.getContextMenu(); }

	/** @private */
	protected override function get attachTransparentBackground():Boolean
	{ return false; }
	
	/** @private */
	tlf_internal function doUpdateVisibleRectangle():void
	{ updateVisibleRectangle(); }
	
	/** @private. Override clones and enhances parent class functionality. */
	protected override function updateVisibleRectangle() :void
	{
		var xpos:Number;
		var ypos:Number;
		// see the adjustLines boolean in ContainerController.fillShapeChildren - this logic clones that and allows for skipping the scrollRect
		xpos = horizontalScrollPosition;
		if (effectiveBlockProgression == BlockProgression.RL && (verticalScrollPolicy != ScrollPolicy.OFF || horizontalScrollPolicy != ScrollPolicy.OFF))
			xpos -= !isNaN(compositionWidth) ? compositionWidth : contentWidth;

		ypos = verticalScrollPosition;
			
		_hasScrollRect = _inputManager.drawBackgroundAndSetScrollRect(xpos,ypos);
	}
		
	/** @private */
	tlf_internal override function getInteractionHandler():IInteractionEventHandler
	{ return _inputManager; }
	
	
	/** @private */
	tlf_internal override function attachContextMenu():void
	{ 
		if (_inputManager.getContextMenu() != null)
			super.attachContextMenu();
	}
	
	/** @private */
	tlf_internal override function removeContextMenu():void
	{ 				
		// otherwise client is managing it
		if (_inputManager.getContextMenu())	
			super.removeContextMenu();
	}
	
	// ////////////////////////////////////////////////////////////////////////////
	// push all these methods for manipulating the object list to the _inputmanager
	// ////////////////////////////////////////////////////////////////////////////
	protected override function getFirstTextLineChildIndex():int
	{ return _inputManager.getFirstTextLineChildIndex(); }
	protected override function addTextLine(textLine:TextLine, index:int):void
	{ _inputManager.addTextLine(textLine,index); }
	protected override function removeTextLine(textLine:TextLine):void
	{ _inputManager.removeTextLine(textLine); }
	protected override function addBackgroundShape(shape:Shape):void
	{ _inputManager.addBackgroundShape(shape); }
	protected override function removeBackgroundShape(shape:Shape):void
	{ _inputManager.removeBackgroundShape(shape); }
	protected override function addSelectionContainer(selectionContainer:DisplayObjectContainer):void
	{ _inputManager.addSelectionContainer(selectionContainer); }
	protected override function removeSelectionContainer(selectionContainer:DisplayObjectContainer):void
	{ _inputManager.removeSelectionContainer(selectionContainer); }
	protected override function addInlineGraphicElement(parent:DisplayObjectContainer, inlineGraphicElement:DisplayObject, index:int):void
	{ _inputManager.addInlineGraphicElement(parent,inlineGraphicElement,index); }
	protected override function removeInlineGraphicElement(parent:DisplayObjectContainer, inlineGraphicElement:DisplayObject):void
	{ _inputManager.removeInlineGraphicElement(parent,inlineGraphicElement); }
}

// remap the mouse event for processing inside TLF.  This is just the initial click.  Make it as if the event was on the container and not the textline
class RemappedMouseEvent extends MouseEvent
{
	private var _event:MouseEvent;
	
	public function RemappedMouseEvent(event:MouseEvent,cloning:Boolean = false)
	{
		var containerPoint:Point;
		if (!cloning)
		{
			containerPoint = DisplayObject(event.target).localToGlobal(new Point(event.localX, event.localY));
			containerPoint = DisplayObject(event.currentTarget).globalToLocal(containerPoint);
		}
		else
			containerPoint = new Point();

		/* event.commandKey,event.controlKey,event.clickCount are also supported in AIR.  IMHO they are a nonissue for the initial click */
		super(event.type,event.bubbles,event.cancelable,containerPoint.x,containerPoint.y,event.relatedObject,event.ctrlKey,event.altKey,event.shiftKey,event.buttonDown,event.delta);
		
		_event = event;
	}

	// override methods/getters for things we couldn't set in the base class	

	public override function get target():Object
	{ return _event.currentTarget; }
	
	public override function get currentTarget():Object
	{ return _event.currentTarget; }
	
	public override function get eventPhase():uint
	{ return _event.eventPhase; }
	
	public override function get isRelatedObjectInaccessible():Boolean
	{ return _event.isRelatedObjectInaccessible; }
	
	public override function get stageX():Number
	{ return _event.stageX; }
	
	public override function get stageY():Number
	{ return _event.stageY; }
	
	public override function clone():Event
	{ 
		var rslt:RemappedMouseEvent = new RemappedMouseEvent(_event,true); 
		rslt.localX = localX;
		rslt.localY = localY;
		return rslt;
	}
	
	public override function updateAfterEvent():void
	{ _event.updateAfterEvent(); }
	
	public override function isDefaultPrevented():Boolean
	{ return _event.isDefaultPrevented(); }
	
	public override function preventDefault():void
	{ _event.preventDefault(); }
	
	public override function stopImmediatePropagation():void
	{ _event.stopImmediatePropagation(); }
	
	public override function stopPropagation():void
	{ _event.stopPropagation(); }
}

class TCMTextFlowTextLineFactory extends TextFlowTextLineFactory
{
	private var _tcm:TextContainerManager;
	
	public function TCMTextFlowTextLineFactory()
	{ super(); }
	
	/** @private */
	tlf_internal override function createFlowComposer():IFlowComposer
	{ return new TCMFactoryDisplayComposer(_tcm); }
	
	public function get tcm():TextContainerManager
	{ return _tcm; }
	public function set tcm(val:TextContainerManager):void
	{ _tcm = val; }
}


class TCMFactoryDisplayComposer extends FactoryDisplayComposer
{
	tlf_internal var _tcm:TextContainerManager;
	public function TCMFactoryDisplayComposer(tcm:TextContainerManager)
	{ _tcm = tcm; }
	
	tlf_internal override function callTheComposer(absoluteEndPosition:int, controllerEndIndex:int):ContainerController
	{
		// always do a full compose
		clearCompositionResults();
		
		var state:SimpleCompose = TextLineFactoryBase._factoryComposer;
		state.resetLineHandler = _tcm.resetLine;
		state.composeTextFlow(textFlow, -1, -1);
		state.releaseAnyReferences()
		return getControllerAt(0);
	}
}