////////////////////////////////////////////////////////////////////////////////
//
//  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.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);
			}			
		}
		// **************************************** 
		// 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();
						effectiveParent.impliedElement = true;
						replaceChildren(_numChildren, _numChildren, effectiveParent);
					}
					if ( (child is SpanElement) || (child is SubParagraphGroupElement))
						child.bindableElement = true;
					effectiveParent.replaceChildren(effectiveParent.numChildren, effectiveParent.numChildren, FlowElement(child) );
				}
				else if (child is String)
				{
					var s:SpanElement = new SpanElement();
					s.text = String(child);
					s.bindableElement = true;
					s.impliedElement = true;
					
					if (effectiveParent is ContainerFormattedElement)
					{
						// See note 1. above
	 					effectiveParent = new ParagraphElement();
						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) ]));
			}
		}

		/** @private */
		override tlf_internal function createGeometry(parentToBe:DisplayObjectContainer):void
		{
			for (var idx:int = 0; idx < _numChildren; idx++)
			{
				var child:FlowElement = getChildAt(idx);
				child.createGeometry(parentToBe);
			}
		}
				
		// **************************************** 
		// 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 return an element or matching idName. */
		tlf_internal override function getElementByIDHelper(idName:String):FlowElement
		{
			var rslt:FlowElement = super.getElementByIDHelper(idName);
			if (rslt == null)
			{
				for (var idx:int = 0; idx < _numChildren; idx++)
				{
					var child:FlowElement = getChildAt(idx);
					rslt = child.getElementByIDHelper(idName);
					if (rslt != null)
						break;
				}
			}
			return rslt;
		}
		
		/** @private return adding elements with matching styleName to an array. */
		tlf_internal override function getElementsByStyleNameHelper(a:Array,styleName:String):void
		{
			super.getElementsByStyleNameHelper(a,styleName);
			for (var idx:int = 0; idx < _numChildren; idx++)
			{
				var child:FlowElement = getChildAt(idx);
				child.getElementsByStyleNameHelper(a,styleName);
			}

		}
		// **************************************** 
		// 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 SubParagraphGroupElement);
		}
		
		/** @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);
					child.modelChanged(ModelChange.ELEMENT_REMOVAL, 0, 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)
					{
						if (newChild.parent)
						{
							if (newChild.parent == this)
							{
								// special handling in this case
								var childIndex:int = getChildIndex(newChild);
								newChild.parent.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
							{
								thisAbsStart = getAbsoluteStart();	// is it in the same flow?
								newChild.parent.removeChild(newChild);
							}
						}
						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];
					newChild.modelChanged(ModelChange.ELEMENT_ADDED, 0, 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.GEOMETRY, 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():void
		{
			for (var idx:int = 0; idx < _numChildren;)
			{
				var child:FlowElement = getChildAt(idx);
				child.applyWhiteSpaceCollapse();
				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();
		}
		
		/** @private */
		tlf_internal override function appendElementsForDelayedUpdate(tf:TextFlow):void
		{ 
			for (var idx:int = 0; idx < _numChildren; idx++)
			{
				var child:FlowElement = getChildAt(idx);
				child.appendElementsForDelayedUpdate(tf);
			}
		}
		

		
			
		// **************************************** 
		// 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
		// ****************************************	
	}
}
