////////////////////////////////////////////////////////////////////////////////
//
//  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.elements 
{
	import flash.display.DisplayObjectContainer;
	import flash.text.engine.ContentElement;
	import flash.text.engine.GroupElement;
	import flash.utils.getQualifiedClassName;
	
	import flashx.textLayout.compose.FlowDamageType;
	import flashx.textLayout.container.ContainerController;
	import flashx.textLayout.debug.assert;
	import flashx.textLayout.events.ModelChange;
	import flashx.textLayout.formats.FormatValue;
	import flashx.textLayout.formats.ITextLayoutFormat;
	import flashx.textLayout.formats.TextLayoutFormat;
	import flashx.textLayout.tlf_internal;
	
	use namespace tlf_internal;

	[DefaultProperty("mxmlChildren")]

	/** 
	 * The FlowGroupElement class is the base class for FlowElement objects that can have an array of children. These classes include
	 * TextFlow, ParagraphElement, DivElement, and LinkElement.
	 *
	 * <p>You cannot create a FlowGroupElement object directly. Invoking <code>new FlowGroupElement()</code> throws an error 
 	 * exception.</p>
 	 *
 	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 *
	 * @see DivElement
	 * @see LinkElement
	 * @see ParagraphElement
	 * @see TextFlow
	 */ 
	public class FlowGroupElement extends FlowElement
	{
		/** children of the FlowGroupElement.  They must all be FlowElements. Depending on _numChildren either store a single child in _singleChild or multiple children in the array. */
		private var _childArray:Array;
		private var _singleChild:FlowElement;
		private var _numChildren:int;
		
		/** Base class - invoking <code>new FlowGroupElement()</code> throws an error exception.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 */
		public function FlowGroupElement()
		{
			_numChildren = 0;
		}
		
		/** @private */
		public override function deepCopy(startPos:int = 0, endPos:int = -1):FlowElement
		{
			if (endPos == -1)
				endPos = textLength;
				
			var retFlow:FlowGroupElement = shallowCopy(startPos, endPos) as FlowGroupElement;
			var newFlowElement:FlowElement;
			for (var idx:int = 0; idx < _numChildren; idx++)
			{
				var child:FlowElement = getChildAt(idx);
				if (((startPos - child.parentRelativeStart) < child.textLength) && ((endPos - child.parentRelativeStart) > 0))			
				{
					//child is in Selected area
					newFlowElement = child.deepCopy(startPos - child.parentRelativeStart, endPos - child.parentRelativeStart);
					retFlow.replaceChildren(retFlow.numChildren,retFlow.numChildren,newFlowElement);	
					if (retFlow.numChildren > 1)
					{
						var possiblyEmptyFlowElement:FlowElement = retFlow.getChildAt(retFlow.numChildren - 2);
						if (possiblyEmptyFlowElement.textLength == 0)
						{
							retFlow.replaceChildren(retFlow.numChildren - 2, retFlow.numChildren - 1);
						}
					}									
				}
			}
			return retFlow;
		}
		
		/* @private */
		public override function getText(relativeStart:int=0, relativeEnd:int=-1, paragraphSeparator:String="\n"):String
		{
			var text:String = super.getText();
			
			if (relativeEnd == -1)
				relativeEnd = textLength;

			var pos:int = relativeStart;
			for (var idx:int = findChildIndexAtPosition(relativeStart); idx < _numChildren && pos < relativeEnd; idx++)
			{
				var child:FlowElement = getChildAt(idx);
				var copyStart:int = pos - child.parentRelativeStart;
				var copyEnd:int = Math.min(relativeEnd - child.parentRelativeStart, child.textLength);
				text += child.getText(copyStart, copyEnd, paragraphSeparator);
				pos += copyEnd - copyStart;
				if (paragraphSeparator && child is ParagraphFormattedElement && pos < relativeEnd)
					text += paragraphSeparator;
			}
			return text;
		}
		
		// **************************************** 
		// Begin TextLayoutFormat Related code
		// ****************************************
		/** @private */
		tlf_internal override function formatChanged(notifyModelChanged:Boolean = true):void
		{
			super.formatChanged(notifyModelChanged);
			for (var idx:int = 0; idx < _numChildren; idx++)
			{
				var child:FlowElement = getChildAt(idx);
				child.formatChanged(false);
			}			
		}
		
		/** This gets called when an element has changed its style selection related attributes. This may happen because an
		 * ancestor element changed it attributes.
		 * @private 
		 */		
		tlf_internal override function styleSelectorChanged():void
		{
			super.styleSelectorChanged();
			formatChanged(false);
		}
		// **************************************** 
		// End TLFFormat Related code
		// ****************************************
	
		// **************************************** 
		// Begin import helper code 
		// ****************************************	
		[RichTextContent]
		/** 
		 * Appends an array of children to this object. Uses the <code>replaceChildren()</code> method to append each 
		 * element in the array. Intended for use during an mxml compiled import.
		 * 
		 * @throws TypeError if array element is not a FlowElement or String
		 * @param array - array of children to attach.  Each element of the array must be a FlowElement object or a String.
		 * @see FlowGroupElement#replaceChildren()
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0 
		 */
		public function get mxmlChildren():Array
		{
			return _numChildren == 0 ? null : (_numChildren == 1 ? [ this._singleChild ] : _childArray.slice() );
		}
		public function set mxmlChildren(array:Array):void
		{
			/* NOTE: all FlowElement implementers and overrides of mxmlChildren must specify [RichTextContent] metadata */

			// remove all existing children
			this.replaceChildren(0,_numChildren);
			
			// In the text model, non-ParagraphFormattedElements (i.e. spans, images, links, TCY) cannot be children of a ContainerFormattedElement (TextFlow, DivElement etc.)
			// They can only be children of paragraphs or subparagraph blocks. 
			// In XML, however, <p> elements can be implied (for example, a <span> may appear as a direct child of <flow>).  
			// So, while parsing the XML, if we enounter a non-ParagraphFormattedElement child of a ContainerFormattedElement 
			// 1. an explicitly created paragraph is used as the parent instead
			// 2. such explicitly created paragraphs are shared by adjacent flow elements provided there isn't an intervening ParagraphFormattedElement
			var effectiveParent:FlowGroupElement = this; 
			
			// append them on the end		
			for each (var child:Object in array)
			{
				if (child is FlowElement)
				{
					if (child is ParagraphFormattedElement)
					{
						// Reset due to possibly intervening FlowParagrpahElement; See note 2. above
						effectiveParent = this; 
					}
					else if (effectiveParent is ContainerFormattedElement)
					{
						// See note 1. above
						effectiveParent = new ParagraphElement();	// NO PMD
						effectiveParent.impliedElement = true;
						replaceChildren(_numChildren, _numChildren, effectiveParent);
					}
					if ( (child is SpanElement) || (child is SubParagraphGroupElementBase))
						child.bindableElement = true;
					effectiveParent.replaceChildren(effectiveParent.numChildren, effectiveParent.numChildren, FlowElement(child) );
				}
				else if (child is String)
				{
					var s:SpanElement = new SpanElement();	// NO PMD
					s.text = String(child);
					s.bindableElement = true;
					s.impliedElement = true;
					
					if (effectiveParent is ContainerFormattedElement)
					{
						// See note 1. above
	 					effectiveParent = new ParagraphElement();	// No PMD
						replaceChildren(_numChildren, _numChildren, effectiveParent);
						effectiveParent.impliedElement = true;
					}
					effectiveParent.replaceChildren(effectiveParent.numChildren, effectiveParent.numChildren, s);
				}
				else if (child != null)
					throw new TypeError(GlobalSettings.resourceStringFunction("badMXMLChildrenArgument",[ getQualifiedClassName(child) ]));	// NO PMD
			}
		}

		// **************************************** 
		// End import helper code
		// ****************************************	
		// **************************************** 
		// Begin tree navigation code
		// ****************************************	
		
		/** 
		* Returns the number of FlowElement children that this FlowGroupElement object has.
		*
		* @playerversion Flash 10
		* @playerversion AIR 1.5
	 	* @langversion 3.0
	 	*/
	 	
		public function get numChildren(): int
		{
			return _numChildren;
		}
		
		/** 
		 * Searches in children for the specified FlowElement object and returns its index position.
		 *
		 * @param child	The FlowElement object item to locate among the children.
		 * @return The index position of the specified chilc.  If <code>child</code> is not found, returns -1.
		 *  
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 */
	 	 
		public function getChildIndex(child:FlowElement):int
		{
			var hi:int = _numChildren-1;
			// one hole here - if child is null and this has no children then we'll return 0
			if (hi <= 0)
				return _singleChild == child ? 0 : -1;
			
			var lo:int = 0;
			while (lo <= hi)
			{
				var mid:int = (lo+hi)/2;
				var p:FlowElement = _childArray[mid];
				if (p.parentRelativeStart == child.parentRelativeStart)
				{
					// during intermediate caluclations there are zero length elements lurking about
					if (p == child)
					{
						CONFIG::debug { assert(_childArray.indexOf(child) == mid,"Bad getChildIndex"); }
						return mid;
					}
					var testmid:int;
					if (p.textLength == 0)
					{
						// look forward for a match
						for (testmid = mid; testmid < _numChildren; testmid++)
						{
							p = _childArray[testmid];
							if (p == child)
							{
								CONFIG::debug { assert(_childArray.indexOf(child) == testmid,"Bad getChildIndex"); }
								return testmid;
							}
							if (p.textLength != 0)
								break;
						}
					}
					
					// look backwards
					while (mid > 0)
					{
						mid--;
						p = _childArray[mid];
						if (p == child)
						{
							CONFIG::debug { assert(_childArray.indexOf(child) == mid,"Bad getChildIndex"); }
							return mid;
						}
						if (p.textLength != 0)
							break;
					}
					CONFIG::debug { assert(_childArray.indexOf(child) == -1,"Bad getChildIndex"); }
					return -1;
				}
				if (p.parentRelativeStart < child.parentRelativeStart)
					lo = mid+1;
				else
					hi = mid-1;
			}
			CONFIG::debug { assert(_childArray.indexOf(child) == -1,"Bad getChildIndex"); }
			return -1;
		}
		/** 
		 * Returns the FlowElement child at the specified index.
		 * 
		 * @param index the position at which to find the FlowElement object.
		 *
		 * @return  the child FlowElement object at the specified position.
		 * @includeExample examples\FlowGroupElement_getChildAtExample.as -noswf
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 */
	 	 
		public function getChildAt(index:int):FlowElement
		{
			if (_numChildren > 1)
				return _childArray[index];
			return index == 0 ? _singleChild : null;
		}
	
		/** @private */
		tlf_internal function getNextLeafHelper(limitElement:FlowGroupElement,child:FlowElement):FlowLeafElement
		{
			var idx:int = getChildIndex(child);
			if (idx == -1)
				return null;	// bug?
			
			if (idx == _numChildren-1)
			{
				if (limitElement == this || !parent)
					return null;
				
				return parent.getNextLeafHelper(limitElement,this);
			}
			
			var child:FlowElement = getChildAt(idx+1);
			return (child is FlowLeafElement) ? FlowLeafElement(child) : FlowGroupElement(child).getFirstLeaf();
		}
				
		/** @private */
		tlf_internal function getPreviousLeafHelper(limitElement:FlowGroupElement,child:FlowElement):FlowLeafElement
		{
			var idx:int = getChildIndex(child);
			if (idx == -1)
				return null;	// bug?
			
			if (idx == 0)
			{
				if (limitElement == this || !parent)
					return null;
				
				return parent.getPreviousLeafHelper(limitElement,this);
			}
			
			var child:FlowElement = getChildAt(idx-1);
			return (child is FlowLeafElement) ? FlowLeafElement(child) : FlowGroupElement(child).getLastLeaf();
		}
	
		/**
		 * Given a relative text position, find the leaf element that contains the position. 
		 *
		 * <p>Looks down the flow element hierarchy to find the FlowLeafElement that 
		 * contains the specified position. The specified position 
		 * is relative to this FlowElement object.</p>
		 *
		 * @param relativePosition	relative text index to look up.
		 * @return	the leaf element containing the relative position.
		 *
		 * @includeExample examples\FlowGroupElement_findLeafExample.as -noswf
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
		 */
		 
		public function findLeaf(relativePosition:int):FlowLeafElement
		{
			var found:FlowLeafElement = null;
			var childIdx:int = findChildIndexAtPosition(relativePosition);
			if (childIdx != -1)
			{
				// childIdx is index of the first child containing pos. Many of its following siblings
				// may also contain pos if their respective previous siblings are zero-length. 
				// Check them all until a leaf containing pos is found.
				do
				{
					var child:FlowElement = this.getChildAt(childIdx++);
					if (!child)
						break;
					
					var childRelativePos: int = relativePosition - child.parentRelativeStart;
					if (child is FlowGroupElement)
						found = FlowGroupElement(child).findLeaf(childRelativePos);
					else
					{
						// if its not a FlowGroupElement than it must be a FlowLeafElement
						CONFIG::debug { assert(child is FlowLeafElement,"Invalid child in FlowGroupElement.findLeaf"); }
						if (childRelativePos >= 0 && childRelativePos < child.textLength || (child.textLength == 0 && _numChildren == 1))
							found = FlowLeafElement(child);
					}
				} while (!found && !child.textLength);
				
			}
			return found;
		}
		
		/**
		 * Given a relative text position, find the index of the first child FlowElement that contains the relative position. 
		 * More than one child can contain relative position because of zero length FlowElements.
		 *  
		 * <p>Examine the children to find the FlowElement that contains the relative position. The supplied relative position 
		 * is relative to this FlowElement.</p>
		 *
		 * @param relativePosition 	the position relative to this element
		 * @return 	index of first child element containing <code>relativePosition</code>
		 *
		 * @includeExample examples\FlowGroupElement_findChildIndexAtPositionExample.as -noswf
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
		 */
		 
		public function findChildIndexAtPosition(relativePosition:int):int
		{
			var lo:int = 0;
			var hi:int = _numChildren-1;
			while (lo <= hi)
			{
				var mid:int = (lo+hi)/2;
				var child:FlowElement = getChildAt(mid);
				if (child.parentRelativeStart <= relativePosition)
				{
					// always return the first zero length element in the list
					if (child.parentRelativeStart == relativePosition)
					{
						while (mid != 0)
						{
							child = getChildAt(mid-1);
							if (child.textLength != 0)
								break;
							mid--;
						}
						return mid;
					}
					if (child.parentRelativeStart + child.textLength > relativePosition)
						return mid;
					lo = mid+1;
				}
				else
					hi = mid-1;
			}
			return -1;
		}
		
		/**
		 * Returns the first FlowLeafElement descendant of this group.
		 *
		 * @return the first FlowLeafElement object.
		 *
		 * @includeExample examples\FlowGroupElement_getFirstLeafExample.as -noswf
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
		 */
		 
		public function getFirstLeaf(): FlowLeafElement
		{
			if (_numChildren > 1)
			{
				for (var idx:int = 0; idx < _numChildren; idx++)
				{
					var child:FlowElement = _childArray[idx];
					var leaf:FlowLeafElement = (child is FlowGroupElement) ? FlowGroupElement(child).getFirstLeaf() : FlowLeafElement(child);
					if (leaf)
						return leaf;
				}
				return null;
			}
			return _numChildren == 0 ? null : ((_singleChild is FlowGroupElement) ? FlowGroupElement(_singleChild).getFirstLeaf() : FlowLeafElement(_singleChild));
		}
		
		/**
		 * Returns the last FlowLeafElement descendent of this group.
		 *
		 * @return the last FlowLeafElement object.
		 *
		 * @includeExample examples\FlowGroupElement_getLastLeafExample.as -noswf
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
		 */
		 
		public function getLastLeaf(): FlowLeafElement
		{
			if (_numChildren > 1)
			{
				for (var idx:int = _numChildren; idx != 0; idx--)
				{
					var child:FlowElement = _childArray[idx-1];
					var leaf:FlowLeafElement = (child is FlowGroupElement) ? FlowGroupElement(child).getLastLeaf() : FlowLeafElement(child) ;
					if (leaf)
						return leaf;
				}
				return null;
			}
			return _numChildren == 0 ? null : ((_singleChild is FlowGroupElement) ? FlowGroupElement(_singleChild).getLastLeaf() : FlowLeafElement(_singleChild));
		}
		
		/** @private */
		public override function getCharAtPosition(relativePosition:int):String
		{
			var leaf:FlowLeafElement = findLeaf(relativePosition);
			return leaf ? leaf.getCharAtPosition(relativePosition-leaf.getElementRelativeStart(this)) : "";
		} 
		
		/** @private apply func to all elements until func says stop */
		tlf_internal override function applyFunctionToElements(func:Function):Boolean
		{
			if (func(this))
				return true;
			for (var idx:int = 0; idx < _numChildren; idx++)
			{
				if (getChildAt(idx).applyFunctionToElements(func))
					return true;
			}
			return false;
		}

		// **************************************** 
		// End tree navigation code
		// ****************************************			
		// **************************************** 
		// Begin tree modification support code
		// ****************************************	
		
		/** @private */
		tlf_internal function removeBlockElement(child:FlowElement, block:ContentElement):void
		{
			// when Image's are moved into ParagraphElement's this assertion should always fire
			CONFIG::debug { assert(child is InlineGraphicElement,"invalid call to removeBlockElement"); }
		}
		
		/** @private */
		tlf_internal function insertBlockElement(child:FlowElement, block:ContentElement):void
		{
			// when Image's are moved into ParagraphElement's this assertion should always fire
			CONFIG::debug { assert(child is InlineGraphicElement,"invalid call to insertBlockElement"); }
		}
		
		/** @private 
		 * True if there is a corresponding FTE data structure currently instantiated.
		 */
		tlf_internal function hasBlockElement():Boolean
		{
			CONFIG::debug { assert(false,"invalid call to hasBlockElement"); }
			return false;
		}
		
		/** @private */
		tlf_internal function createContentAsGroup():GroupElement
		{
			CONFIG::debug { assert(false,"invalid call to createContentAsGroup"); }
			return null;
		}
				
		/** @private This is only called from SpanElement.splitAtPosition */
		tlf_internal function addChildAfterInternal(child:FlowElement, newChild:FlowElement):void
		{
			//this function was kept for efficiency purposes. It is used by splitForChange
			//which in turn is used by applyCharacterFormat, when changing the
			//attributes applied to characters.  In the end, the length of the document
			//will be the same. So, without this fnction, we would be creating a new
			//span, updating the lengths, and then removing a part of the span and updating
			//the lengths again (getting the same exact lengths we had before). This can be
			//inefficient. So, this function does everything addChildAfter does, without
			//updating the lengths. This is an internal function since the user really has
			//to know what they're doing and will not be exposed as a public API
			CONFIG::debug { assert(_numChildren != 0, "addChildAfter must have children"); }
			CONFIG::debug { assert(getChildIndex(child) != -1, "addChildAfter: before child must be in array"); }
			if (_numChildren > 1)
			{
				// TODO: binary search for indexOf child
				CONFIG::debug { assert(_childArray.indexOf(child) != -1,"Bad call to addChildAfterInternal"); }
				_childArray.splice(_childArray.indexOf(child)+1,0,newChild);
			}
			else
			{
				// not found returns above returns -1 so behave the same
				CONFIG::debug { assert(_singleChild == child,"Bad call to addChildAfterInternal"); }
				_childArray = [ _singleChild, newChild ];
				_singleChild = null;
			}
			_numChildren++;
			newChild.setParentAndRelativeStartOnly(this,child.parentRelativeEnd);
		}
		
		/**
		 * Helper for replaceChildren.  Determines if elem can legally be a child of this.
		 * @return true --> ok, false--> not a legal child
		 * @private 
		 */
		tlf_internal function canOwnFlowElement(elem:FlowElement):Boolean
		{
			return !(elem is TextFlow) && !(elem is FlowLeafElement) && !(elem is SubParagraphGroupElementBase) && !(elem is ListItemElement);
		}
		
		/** @private */	
		private static function getNestedArgCount(obj:Object):uint
		{
			return (obj is Array) ? obj.length : 1;
		}		
		
		/** @private */	
		private static function getNestedArg(obj:Object, index:uint):FlowElement
		{
			CONFIG::debug { assert(index < getNestedArgCount(obj),"bad index to getNestedArg"); } 
			return ((obj is Array) ? obj[index] : obj) as FlowElement;
		}
				
		/**
		 * Replaces child elements in the group with the specified new elements. Use the <code>beginChildIndex</code> and
		 * <code>endChildIndex</code> parameters to govern the operation as follows:
		 * <p><ul>
		 * <li>To delete elements, do not pass any replacement elements.</li>
		 * <li>To insert elements, pass the same value for <code>beginChildIndex</code> and <code>endChildIndex</code>.  
		 * The new elements is inserted before the specified index.</li>
		 * <li>To append elements, pass <code>numChildren</code> for <code>beginChildIndex</code> and <code>endChildIndex</code>.</li>
		 * </ul></p>
		 * <p>Otherwise, this method replaces the specified elements, starting with the element at <code>beginChildIndex</code> 
		 * and up to but not including <code>endChildIndex</code>.</p>
		 * 
		 * @param beginChildIndex The index value for the start position of the replacement range in the children array.
		 * @param endChildIndex The index value following the end position of the replacement range in the children array.
		 * @param rest The elements to replace the specified range of elements. Can be a sequence containing flow elements or
		 * arrays or vectors thereof.
		 *	 
	     * @throws RangeError The <code>beginChildIndex</code> or <code>endChildIndex</code> specified is out of range.
	     * 
	     * @includeExample examples\FlowGroupElement_replaceChildrenExample.as -noswf
		 *
	     * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
		 */
		 
		public function replaceChildren(beginChildIndex:int, endChildIndex:int, ...rest):void
		{
			if (beginChildIndex > _numChildren || endChildIndex > _numChildren)
				throw RangeError(GlobalSettings.resourceStringFunction("badReplaceChildrenIndex"));	
			
			var thisAbsStart:int = getAbsoluteStart();
			var absStartIdx:int =  thisAbsStart + (beginChildIndex == _numChildren ? textLength : getChildAt(beginChildIndex).parentRelativeStart);
			var relStartIdx:int = beginChildIndex == _numChildren ? textLength : getChildAt(beginChildIndex).parentRelativeStart;
			
			// deletion phase
			if (beginChildIndex < endChildIndex)
			{
				var child:FlowElement;	// scratch variable
				var len:int = 0;

				while (beginChildIndex < endChildIndex)
				{
					child = this.getChildAt(beginChildIndex);
					this.modelChanged(ModelChange.ELEMENT_REMOVAL, child, child.parentRelativeStart, child.textLength);
					len += child.textLength;
					
					child.setParentAndRelativeStart(null,0);
					if (_numChildren == 1)
					{
						_singleChild = null;
						_numChildren = 0;
					}
					else
					{
						_childArray.splice(beginChildIndex,1);
						_numChildren--;
						if (_numChildren == 1)
						{
							_singleChild = _childArray[0];
							_childArray = null;
						}
					}
					endChildIndex--;
				}
				if (len)
				{
					// TODO: this code should move into updateLengths.  updateLengths needs a rewrite
					// as it assumes that any element that is removed has its length set to zero and updateLengths
					// is called on that element first.  replaceChildren doesn't do that - it just removes the element
					
					// until rewrite reuse endChildIndex and update start of all following elements
					while (endChildIndex < _numChildren)
					{
						child = getChildAt(endChildIndex);
						child.setParentRelativeStart(child.parentRelativeStart-len);
						endChildIndex++;
					}
				
					// update lengths
					updateLengths(absStartIdx,-len,true);
					
					deleteContainerText(relStartIdx + len,len);
				}
			}
			CONFIG::debug { assert(thisAbsStart == getAbsoluteStart(),"replaceChildren: Bad thisAbsStart"); }
			var childrenToAdd:int = 0;		// number of children to add
			var flatNewChildList:Array;		// stores number of children when > 1
			var newChildToAdd:FlowElement;	// stores a single child to add - avoids creating an Array for the 99% case
			 
			var newChild:FlowElement; 		// scratch
			var idx:int;					// scratch
			
			for each (var obj:Object in rest)
			{
				if (!obj)
					continue;
				
				var numNestedArgs:int = getNestedArgCount(obj);
				for (idx = 0; idx<numNestedArgs; idx++)
				{
					newChild = getNestedArg(obj, idx);
					if (newChild)
					{
						var newChildParent:FlowGroupElement = newChild.parent;
						if (newChildParent)
						{
							if (newChildParent == this)
							{
								// special handling in this case
								var childIndex:int = getChildIndex(newChild);
								newChildParent.removeChild(newChild);
								thisAbsStart = getAbsoluteStart();	// is it in the same flow?
								if (childIndex <= beginChildIndex)
								{
									beginChildIndex--;
									absStartIdx =  thisAbsStart + (beginChildIndex == _numChildren ? textLength : getChildAt(beginChildIndex).parentRelativeStart);
									relStartIdx = beginChildIndex == _numChildren ? textLength : getChildAt(beginChildIndex).parentRelativeStart;
								}
							}
							else
							{
								newChildParent.removeChild(newChild);
								thisAbsStart = getAbsoluteStart();	// is it in the same flow?
								absStartIdx =  thisAbsStart + (beginChildIndex == _numChildren ? textLength : getChildAt(beginChildIndex).parentRelativeStart);
								relStartIdx = beginChildIndex == _numChildren ? textLength : getChildAt(beginChildIndex).parentRelativeStart;
							}
						}
						if (!canOwnFlowElement(newChild))
							throw ArgumentError(GlobalSettings.resourceStringFunction("invalidChildType"));
						
						// manage as an array or a single child
						if (childrenToAdd == 0)
							newChildToAdd = newChild
						else if (childrenToAdd == 1)
							flatNewChildList = [ newChildToAdd, newChild ];
						else
							flatNewChildList.push(newChild);
						childrenToAdd++;
					}
				}
			}			

			if (childrenToAdd)
			{
				// TODO-9/18/2008-ideally, do the following in one shot, but insertBlockElement
				// called from setParentAndRelativeStart in the loop below has different behavior
				// based on the size of _children (zero vs. non-zero)
				//_children.splice(beginChildIndex,0,flatNewChildList);
				var addedTextLength:uint = 0;
				for (idx = 0; idx < childrenToAdd; idx++)
				{
					newChild = childrenToAdd == 1 ? newChildToAdd : flatNewChildList[idx];
					
					if (_numChildren == 0)
						_singleChild = newChild;
					else if (_numChildren > 1)
						_childArray.splice(beginChildIndex,0,newChild);
					else
					{
						_childArray = beginChildIndex == 0 ? [ newChild, _singleChild ] : [ _singleChild, newChild ];
						_singleChild = null;
					}
					_numChildren++;
					newChild.setParentAndRelativeStart(this,relStartIdx+addedTextLength);
					addedTextLength += newChild.textLength;
					beginChildIndex++;	// points to the next slot
				}
				CONFIG::debug { assert(thisAbsStart == getAbsoluteStart(),"replaceChildren: Bad thisAbsStart"); }
				if (addedTextLength)
				{
					// update following elements - see comment above.
					// it would be best if this loop only ran once
					while (beginChildIndex < _numChildren)
					{
						child = getChildAt(beginChildIndex++);
						child.setParentRelativeStart(child.parentRelativeStart+addedTextLength);
					}
					updateLengths(absStartIdx,addedTextLength,true);
					var enclosingContainer:ContainerController = getEnclosingController(relStartIdx);
					if (enclosingContainer)
						ContainerController(enclosingContainer).setTextLength(enclosingContainer.textLength + addedTextLength);
				}
				for (idx = 0; idx < childrenToAdd; idx++)
				{
					newChild = childrenToAdd == 1 ? newChildToAdd : flatNewChildList[idx];
					this.modelChanged(ModelChange.ELEMENT_ADDED, newChild, newChild.parentRelativeStart, newChild.textLength);
				}
			}
			else 
			{	
				var tFlow:TextFlow = getTextFlow();
				if (tFlow != null)
				{
					// beginChildIndex points to the next element
					// use scratch idx as "damageStart"
					if (beginChildIndex < _numChildren)
            		{
            			// first, look for the next element and damage the beginning.
						idx = thisAbsStart + getChildAt(beginChildIndex).parentRelativeStart;
            		} 
            		else if (beginChildIndex > 1)
            		{
            			// damage the end of the previous element
						newChild = getChildAt(beginChildIndex-1);
						idx = thisAbsStart + newChild.parentRelativeStart + newChild.textLength - 1;
            		} 
					else
					{
						// damage the very end of the textFlow
						idx = thisAbsStart;
						if (idx >= tFlow.textLength)
							idx--;
     				}
     				tFlow.damage(idx, 1, FlowDamageType.INVALID, false);
   				}   				
			}
		}
		
		/** 
		 * Appends a child FlowElement object. The new child is added to the end of the children list.
		 * 
		 * @param child The child element to append.
		 *
		 * @return  the added child FlowElement 
		 * 
		 * @includeExample examples\FlowGroupElement_addChildExample.as -noswf
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
		 */
		 
		public function addChild(child:FlowElement):FlowElement
		{
			replaceChildren(_numChildren, _numChildren, child);
			return child;
		}
		
		/** 
		 * Adds a child FlowElement object at the specified index position.
		 *
		 * @param The index of the position at which to add the child element, with the first position being 0.
		 * @param child The child element to add.
		 * @throws RangeError The <code>index</code> is out of range.
		 *
		 * @return  the added child FlowElement 
		 *
		 * @includeExample examples\FlowGroupElement_addChildAtExample.as -noswf
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 *
		 */
		 
		public function addChildAt(index:uint, child:FlowElement):FlowElement
		{
			replaceChildren(index, index, child);
			return child;
		}
		
		/** 
		 * Removes the specified child FlowElement object from the group.
		 *
		 * @param child The child element to remove.
		 * @throws ArgumentError The <code>child</code> is not found.
		 *
		 * @return  the removed child FlowElement object 
		 *
		 * @includeExample examples\FlowGroupElement_removeChildExample.as -noswf
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
		 *
		 */
		 
		public function removeChild(child:FlowElement):FlowElement
		{
			var index:int = getChildIndex(child);
			if (index == -1)
				throw ArgumentError(GlobalSettings.resourceStringFunction("badRemoveChild"));
				
			removeChildAt(index);
			return child;
		}
		
		/** 
		 * Removes the child FlowElement object at the specified index position.
		 *
		 * @param index position at which to remove the child element.
		 * @throws RangeError The <code>index</code> is out of range.
		 *
		 * @return  the child FlowElement object removed from the specified position.
		 *
		 * @includeExample examples\FlowGroupElement_removeChildAtExample.as -noswf
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
		 */
		 
		public function removeChildAt(index:uint):FlowElement
		{
			var childToReplace:FlowElement = getChildAt(index);
			replaceChildren(index, index+1);
			return childToReplace;
		}
		
		/** 
		 * Splits this object at the position specified by the <code>childIndex</code> parameter. If this group element has 
		 * a parent, creates a shallow copy of this object and replaces its children with the elements up to the index. Moves 
		 * elements following <code>childIndex</code> into the copy.
		 * 
		 * @return the new FlowGroupElement object.
		 * @throws RangeError if <code>childIndex</code> is greater than the length of the children.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
		 */
		 
		public function splitAtIndex(childIndex:int):FlowGroupElement
		{
			if (childIndex > _numChildren)
				throw RangeError(GlobalSettings.resourceStringFunction("invalidSplitAtIndex"));
					
			var newSibling:FlowGroupElement = shallowCopy() as FlowGroupElement;

			var numChildrenToMove:int = _numChildren-childIndex;
			if (numChildrenToMove == 1)
				newSibling.addChild(removeChildAt(childIndex));
			else if (numChildrenToMove != 0)
			{
				var childArray:Array = _childArray.slice(childIndex);
				this.replaceChildren(childIndex,_numChildren-1);
				newSibling.replaceChildren(0, 0, childArray);		
			}
			
			if (parent)
			{
				var myidx:int = parent.getChildIndex(this);
				parent.replaceChildren(myidx+1,myidx+1,newSibling);
			}

			return newSibling;
		}

		/** 
		 * Splits this object at the position specified by the <code>relativePosition</code> parameter, where 
		 * the relative position is a relative text position in this element.
		 * 
		 * @throws RangeError if relativePosition is greater than textLength, or less than 0.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 * 
	 	 * @private
		 */
		 
		public override function splitAtPosition(relativePosition:int):FlowElement
		{
			// Creates a shallowCopy of this and adds it to parent after this.  
			// Moves elements from characterIndex forward into the copy
		 	// returns the new shallowCopy
			if ((relativePosition < 0) || (relativePosition > textLength))
				throw RangeError(GlobalSettings.resourceStringFunction("invalidSplitAtPosition"));
			
			var curElementIdx:int;
			
			if (relativePosition == textLength)
				curElementIdx = _numChildren;
			else
			{
				curElementIdx = findChildIndexAtPosition(relativePosition);
				var curFlowElement:FlowElement = getChildAt(curElementIdx);
				
				if (curFlowElement.parentRelativeStart != relativePosition)
				{										
					if (curFlowElement is FlowGroupElement)
					{
						FlowGroupElement(curFlowElement).splitAtPosition(relativePosition - curFlowElement.parentRelativeStart);
					} 
					else
					{
						//I would imagine that it has to be a span.  That's the only non-FlowGroupElement
						//type that can take up more than a textLength of 1.
						CONFIG::debug { assert(curFlowElement is SpanElement, "SpanElements are the only leaf elements that can currently have > 1 textLength");	}			
						SpanElement(curFlowElement).splitAtPosition(relativePosition - curFlowElement.parentRelativeStart);
					}
					//increase by one. It's the new element that we want to move over.
					curElementIdx++;
				}
			}
			
			//increase by one. It's the new element that we want to move over.
			return splitAtIndex(curElementIdx);
		} 		 
		
		/** @private */
		tlf_internal override function normalizeRange(normalizeStart:uint,normalizeEnd:uint):void
		{
			var idx:int = findChildIndexAtPosition(normalizeStart);
			if (idx != -1 && idx < _numChildren)
			{
				// backup over zero length children
				var child:FlowElement = getChildAt(idx);
				normalizeStart = normalizeStart-child.parentRelativeStart;
				
				CONFIG::debug { assert(normalizeStart >= 0, "bad normalizeStart in normalizeRange"); }
				for (;;)
				{
					// watch out for changes in the length of the child
					var origChildEnd:int = child.parentRelativeStart+child.textLength;
					child.normalizeRange(normalizeStart,normalizeEnd-child.parentRelativeStart);
					var newChildEnd:int = child.parentRelativeStart+child.textLength;
					normalizeEnd += newChildEnd-origChildEnd;	// adjust
					
					// no zero length children
					if (child.textLength == 0 && !child.bindableElement)
						replaceChildren(idx,idx+1);
					else
						idx++;

					if (idx == _numChildren)
						break;
					
					// next child
					child = getChildAt(idx);
					
					if (child.parentRelativeStart > normalizeEnd)
						break;
						
					normalizeStart = 0;		// for the next child	
				}
			}
		}
		
		/** @private */
		tlf_internal override function applyWhiteSpaceCollapse(collapse:String):void
		{
			if (collapse == null)
				collapse = this.computedFormat.whiteSpaceCollapse;	// top of the cascade?
			else
			{
				var ffc:ITextLayoutFormat = this.formatForCascade;
				var wsc:* = ffc ? ffc.whiteSpaceCollapse : undefined;
				if (wsc !== undefined && wsc != FormatValue.INHERIT)
					collapse = wsc;
			}
			for (var idx:int = 0; idx < _numChildren;)
			{
				var child:FlowElement = getChildAt(idx);
				child.applyWhiteSpaceCollapse(collapse);
				if (child.parent == this)	// check to see if child was removed (could have been 
					++idx;
			}
				
			// If the element was added automatically, it may now have no content and needs to be removed
			// This can happen with whitespace between paragraphs that is added by set mxmlChildren
			if (textLength == 0  && impliedElement && parent != null)
				parent.removeChild(this);

			super.applyWhiteSpaceCollapse(collapse);
		}
		
		/** @private */
		tlf_internal override function appendElementsForDelayedUpdate(tf:TextFlow,changeType:String):void
		{ 
			for (var idx:int = 0; idx < _numChildren; idx++)
			{
				var child:FlowElement = getChildAt(idx);
				child.appendElementsForDelayedUpdate(tf,changeType);
			}
		}

			
		// **************************************** 
		// End tree modification support code
		// ****************************************	
		// **************************************** 
		// Begin debug support code
		// ****************************************	
		/** @private */
		CONFIG::debug public override function debugCheckFlowElement(depth:int = 0, extraData:String = ""):int
		{
			
			var rslt:int = super.debugCheckFlowElement(depth,extraData);
			
			// debugging function that asserts if the flow element is in an invalid state
			var totalChildLength:int = 0;
			if (_numChildren)
			{
				for (var childIndex:int = 0; childIndex < _numChildren; ++childIndex)
				{
					var child:FlowElement = getChildAt(childIndex);
					rslt += assert(child.parent == this, "child doesn't point to parent");

					// totalChildLength is relative offset to child
					rslt += assert(child.parentRelativeStart == totalChildLength, "child start offset wrong");
					rslt += child.debugCheckFlowElement(depth+1);
					totalChildLength += child.textLength;				
				}
			}
			else	
			{
				// only spans may own text
				rslt += assert(this is SpanElement || textLength == 0, "only spans may have text");	
				totalChildLength = textLength;	
			}
			assert(totalChildLength == textLength, "child total textLength wrong");
			return rslt;
		}		
		// **************************************** 
		// End debug support code
		// ****************************************	
	}
}
