////////////////////////////////////////////////////////////////////////////////
//
//  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)
				relativeEnd = textLength;
			
			if (relativeStart < 0)
				relativeStart = 0;
				
			var pos:int = relativeStart;
			for (var idx:int = findChildIndexAtPosition(relativeStart); idx >= 0 && 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
		// ****************************************	
	}
}
