////////////////////////////////////////////////////////////////////////////////
//
//  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.text.engine.GroupElement;
	import flash.text.engine.TextElement;
	import flash.utils.getQualifiedClassName;
	
	import flashx.textLayout.container.ContainerController;
	import flashx.textLayout.debug.Debugging;
	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.formats.WhiteSpaceCollapse;
	import flashx.textLayout.property.Property;
	import flashx.textLayout.tlf_internal;
	import flashx.textLayout.utils.CharacterUtil;
	
	use namespace tlf_internal;
			
	[DefaultProperty("mxmlChildren")]
	
	/** 
	* The SpanElement class represents a run of text that has a single set of formatting attributes applied. SpanElement 
	* objects contain the text in a paragraph. A simple paragraph (ParagraphElement) includes one or more SpanElement objects. 
	*
	* <p>A ParagraphElement will have a single SpanElement object if all the text in the paragraph shares the same set of 
	* attributes. It has multiple SpanElement objects if the text in the paragraph has multiple formats.</p>
	*
	* @playerversion Flash 10
	* @playerversion AIR 1.5
	* @langversion 3.0
	*
	* @includeExample examples/SpanElementExample.as -noswf
	*
	* @see FlowElement
	* @see ParagraphElement
	* @see TextFlow
     	*/
     	
	public class SpanElement extends FlowLeafElement
	{	
		/** @private */
		tlf_internal static const kParagraphTerminator:String = '\u2029';
		
		/** Constructor - creates a SpanElement object to hold a run of text in a paragraph.
		*
		* @playerversion Flash 10
		* @playerversion AIR 1.5
	 	* @langversion 3.0
	 	*/
	 	
		public function SpanElement()
		{
			super();
		}
		
		/** @private */
		override tlf_internal function createContentElement():void
		{
			if (_blockElement)
				return;
			
			computedFormat;	// BEFORE creating the element
			_blockElement = new TextElement(_text,null);			
			CONFIG::debug { Debugging.traceFTECall(_blockElement,null,"new TextElement()"); }
			CONFIG::debug { Debugging.traceFTEAssign(_blockElement, "text", _text); }
			super.createContentElement();
		}
		
		/** @private */
		public override function shallowCopy(startPos:int = 0, endPos:int = -1):FlowElement
		{
			if (endPos == -1)
				endPos = textLength;
				
			// Note to callers: If you are calling this function outside a try/catch, do ensure that the 
			// state of the model is coherent before the call.
			var retFlow:SpanElement = super.shallowCopy(startPos, endPos) as SpanElement;
						
			var startSpan:int = 0;
			var endSpan:int = startSpan + textLength;
			
			var leafElStartPos:int = startSpan >= startPos ? startSpan : startPos;
			var leafElEndPos:int =  endSpan < endPos ? endSpan : endPos;
			if (leafElEndPos == textLength && hasParagraphTerminator)
				--leafElEndPos;
				
			if (leafElStartPos > leafElEndPos)
				throw RangeError(GlobalSettings.resourceStringFunction("badShallowCopyRange"));
			
			if (((leafElStartPos != endSpan) && CharacterUtil.isLowSurrogate(_text.charCodeAt(leafElStartPos))) ||
				((leafElEndPos != 0) && CharacterUtil.isHighSurrogate(_text.charCodeAt(leafElEndPos-1))))
					throw RangeError(GlobalSettings.resourceStringFunction("badSurrogatePairCopy"));
			
			if (leafElStartPos != leafElEndPos)
				retFlow.replaceText(0, retFlow.textLength,  _text.substring(leafElStartPos, leafElEndPos));
			
			return retFlow;
		}	
	
		/** @private */
		override protected function get abstract():Boolean
		{ return false; }		
		
		/** @private */
		tlf_internal override function get defaultTypeName():String
		{ return "span"; }

		/** @private */
		public override function get text():String
		{
			// test textLength cause this is a property and the debugger may run this calculation in intermediate states
			if (textLength == 0)
				return "";
			
			return hasParagraphTerminator ? _text.substr(0,textLength-1) : _text;
		}
		/** 
		 * Receives the String of text that this SpanElement object holds.
		 *
		 * <p>The text of a span does not include the carriage return (CR) at the end of the paragraph
		 * but it is included in the value of <code>textLength</code>.</p>
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 */
	 	
	 	public function set text(textValue:String):void
		{
			//original code stripped breaking and tab characters.  new code moved to collapseWhitevar newLineTabPattern:RegExp = /[\n\r\t]/g;
			replaceText(0,textLength, textValue); 
		} 
		
		/** @private */
		public override function getText(relativeStart:int=0, relativeEnd:int=-1, paragraphSeparator:String="\n"):String
		{
			if (relativeEnd == -1)
				relativeEnd = textLength;
			
			if (textLength && relativeEnd == textLength && hasParagraphTerminator)
				--relativeEnd;		// don't include terminator
			return _text ? _text.substring(relativeStart, relativeEnd) : "";
		}

		[RichTextContent]
		/** 
		 * Sets text based on content within span tags; always deletes existing children.
		 * This property is intended for use during MXML compiled import in Flex. Flash Professional ignores this property.
         * When TLF markup elements have other
		 * TLF markup elements as children, the children are assigned to this property.
		 *
		 * @throws TypeError If array element is not a SpecialCharacterElement or a String.
		 * @param array - an array of elements within span tags. Each element of array must be a SpecialCharacterElement or a String.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 */
		public function get mxmlChildren():Array
		{
			return [ text ];
		}
		public function set mxmlChildren(array:Array):void
		{
			/* NOTE: all FlowElement implementers and overrides of mxmlChildren must specify [RichTextContent] metadata */

			var str:String = new String();
			for each (var elem:Object in array)
			{
				if (elem is String)
					str += elem as String;
				else if (elem is Number)	// TODO: remove the Number else if when we can test with the most recent compilers.  The [RichTextContent] metadata fixes the issue
					str += elem.toString();
				else if (elem is BreakElement)
					str += String.fromCharCode(0x2028);
				else if (elem is TabElement)
				{
					// Add a placeholder (from Unicode private use area) instead of '\t' because the latter is 
					// stripped during white space collapse. After white space collapse, we will change the placeholder
					// to '\t' 
					str += String.fromCharCode(0xE000); 
				}	
				else if (elem != null)
					throw new TypeError(GlobalSettings.resourceStringFunction("badMXMLChildrenArgument",[ getQualifiedClassName(elem) ]));	// NO PMD
					
			}
			replaceText(0,textLength, str); 
		}
		
		
		/** 
		 * Specifies whether this SpanElement object terminates the paragraph. The SpanElement object that terminates a 
		 * paragraph has an extra, hidden character at the end. This character is added automatically by the component and is
		 * included in the value of the <code>textLength</code> property.
		 * 
		 * @private */
		 
		tlf_internal function get hasParagraphTerminator():Boolean
		{
			var p:ParagraphElement = getParagraph();
			return (p && p.getLastLeaf() == this); 
		}
		
		/** @private */
		CONFIG::debug tlf_internal function verifyParagraphTerminator():void
		{
			assert(_text && _text.length && _text.charAt(_text.length-1) == SpanElement.kParagraphTerminator,
				"attempting to remove para terminator when it doesn't exist");
		}
		
		
		/**
		 * Makes a shallow copy of this SpanElement between 2 character positions
		 * and returns it as a FlowElement.  Unlike deepCopy, shallowCopy does
		 * not copy any of the children of this SpanElement.
		 * 
		 */
		 
		 // If I have a sequence of different sorts of spaces (e.g., en quad, hair space), would I want them converted down to one space? Probably not.
		 // For now, u0020 is the only space character we consider for eliminating duplicates, though u00A0 (non-breaking space) is potentially eligible. 
		 private static const _dblSpacePattern:RegExp = /[\u0020]{2,}/g;
		 // Tab, line feed, and carriage return
		 private static const _newLineTabPattern:RegExp = /[\u0009\u000a\u000d]/g;
		 private static const _tabPlaceholderPattern:RegExp = /\uE000/g;
		 
		 // static private const anyPrintChar:RegExp = /[^\s]/g;
		 // Consider only tab, line feed, carriage return, and space as characters used for pretty-printing. 
		 // While debatable, this is consistent with what CSS does. 
		 static private const anyPrintChar:RegExp = /[^\u0009\u000a\u000d\u0020]/g; 

		 /** @private */
		tlf_internal override function applyWhiteSpaceCollapse(collapse:String):void
		{
			var ffc:ITextLayoutFormat = this.formatForCascade;
			var wsc:* = ffc ? ffc.whiteSpaceCollapse : undefined;
			if (wsc !== undefined && wsc != FormatValue.INHERIT)
				collapse = wsc;
				
			var origTxt:String = text;
			var tempTxt:String = origTxt;
				
			if (!collapse /* null == default value == COLLAPSE */ || collapse == WhiteSpaceCollapse.COLLAPSE)
			{
				// The span was added automatically when a String was passed to replaceChildren.
				// If it contains only whitespace, we remove the text.
				if (impliedElement && parent != null)
				{
					// var matchArray:Array = tempTxt.search(anyPrintChar);
					if (tempTxt.search(anyPrintChar) == -1)
					{
						parent.removeChild(this);
						return;
					}
				}
				
				// For now, replace the newlines and tabs inside the element with a space.
				// This is necessary for support of compiled mxml files that have newlines and tabs, because
				// these are most likely not intended to be part of the text content, but only there so the
				// text can be conveniently edited in the mxml file. Later on we need to add standalone elements
				// for <br/> and <tab/>. Note that tab character is not supported in HTML.	
				tempTxt = tempTxt.replace(_newLineTabPattern, " ");

				// Replace sequences of 2 or more whitespace characters with single space
				tempTxt = tempTxt.replace(_dblSpacePattern, " ");
			}
			
			// Replace tab placeholders (used for tabs that are expected to survive whitespace collapse) with '\t'
			tempTxt = tempTxt.replace(_tabPlaceholderPattern, '\t')
			if (tempTxt != origTxt)
				replaceText(0, textLength, tempTxt);

			super.applyWhiteSpaceCollapse(collapse);
		}
		
		/** 
		 * Updates the text in text span based on the specified start and end positions. To insert text, set the end position
		 * equal to the start position. To append text to the existing text in the span, set the start position and the
		 * end position equal to the length of the existing text.
		 *
		 * <p>The replaced text includes the start character and up to but not including the end character.</p>
		 * 
		 *  @param relativeStartPosition The index position of the beginning of the text to be replaced, 
		 *   relative to the start of the span. The first character in the span is at position 0.
		 *  @param relativeEndPosition The index one position after the last character of the text to be replaced, 
		 *   relative to the start of the span. Set this value equal to <code>relativeStartPos</code>
		 *   for an insert. 
		 *  @param textValue The replacement text or the text to add, as the case may be.
		 * 
		 *  @throws RangeError The <code>relativeStartPosition</code> or <code>relativeEndPosition</code> specified is out of 
		 * range or a surrogate pair is being split as a result of the replace.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 *
	 	 * @includeExample examples/SpanElement_replaceTextExample.as -noswf
		 */
		 
		public function replaceText(relativeStartPosition:int, relativeEndPosition:int, textValue:String):void
		{
			// Note to callers: If you are calling this function outside a try/catch, do ensure that the 
			// state of the model is coherent before the call.
			if (relativeStartPosition < 0 || relativeEndPosition > textLength || relativeEndPosition < relativeStartPosition)
				throw RangeError(GlobalSettings.resourceStringFunction("invalidReplaceTextPositions"));	


			if ((relativeStartPosition != 0 && relativeStartPosition != textLength && CharacterUtil.isLowSurrogate(_text.charCodeAt(relativeStartPosition))) ||
				(relativeEndPosition != 0 && relativeEndPosition != textLength && CharacterUtil.isHighSurrogate(_text.charCodeAt(relativeEndPosition-1))))
					throw RangeError (GlobalSettings.resourceStringFunction("invalidSurrogatePairSplit"));
				
			if (hasParagraphTerminator)
			{
				CONFIG::debug { assert(textLength > 0,"invalid span"); }
				if (relativeStartPosition == textLength)
					relativeStartPosition--;
				if (relativeEndPosition == textLength)
					relativeEndPosition--;
			}
			
			if (relativeEndPosition != relativeStartPosition)
				modelChanged(ModelChange.TEXT_DELETED,this,relativeStartPosition,relativeEndPosition-relativeStartPosition);
			
			replaceTextInternal(relativeStartPosition,relativeEndPosition,textValue);
			
			if (textValue && textValue.length)
				modelChanged(ModelChange.TEXT_INSERTED,this,relativeStartPosition,textValue.length);
		}
		private function replaceTextInternal(startPos:int, endPos:int, textValue:String):void
		{			
			var textValueLength:int = textValue == null ? 0 : textValue.length;
			var deleteTotal:int = endPos-startPos;
			var deltaChars:int =  textValueLength - deleteTotal;
			if (_blockElement)
			{
				(_blockElement as TextElement).replaceText(startPos,endPos,textValue);
				_text = _blockElement.rawText;
				CONFIG::debug { Debugging.traceFTECall(null,_blockElement as TextElement,"replaceText",startPos,endPos,textValue); }
			}
			else if (_text)
			{
				if (textValue)
					_text = _text.slice(0, startPos) + textValue + _text.slice(endPos, _text.length);
				else
					_text = _text.slice(0, startPos) + _text.slice(endPos, _text.length);
			}
			else
				_text = textValue;
			
			if (deltaChars != 0)
			{
				updateLengths(getAbsoluteStart() + startPos, deltaChars, true);
				deleteContainerText(endPos,deleteTotal);
				
				if (textValueLength != 0)
				{
					var enclosingContainer:ContainerController = getEnclosingController(startPos);
					if (enclosingContainer)
						ContainerController(enclosingContainer).setTextLength(enclosingContainer.textLength + textValueLength);
				}
			}

			CONFIG::debug { 
				assert(textLength == (_text ? _text.length : 0),"span textLength doesn't match the length of the text property, text property length is " + _text.length.toString() + " textLength property is " + textLength.toString());
				assert(_blockElement == null || _blockElement.rawText == _text,"mismatched text");
			}
		}
	
		/** @private */
		tlf_internal function addParaTerminator():void
		{
			CONFIG::debug 
			{ 
				// TODO: Is this assert valid? Do we prevent users from adding para terminators themselves? 
				if (_blockElement && _blockElement.rawText && _blockElement.rawText.length)
					assert(_blockElement.rawText.charAt(_blockElement.rawText.length-1) != SpanElement.kParagraphTerminator,"adding para terminator twice");
			}

			replaceTextInternal(textLength,textLength,SpanElement.kParagraphTerminator);
			
			CONFIG::debug 
			{ 
				// TODO: Is this assert valid? Do we prevent users from adding para terminators themselves? 
				if (_blockElement)
					assert(_blockElement.rawText.charAt(_blockElement.rawText.length-1) == SpanElement.kParagraphTerminator,"adding para terminator failed");
			}			
			
			modelChanged(ModelChange.TEXT_INSERTED,this,textLength-1,1);
		}
		/** @private */
		tlf_internal function removeParaTerminator():void
		{
			CONFIG::debug 
			{ 
				assert(_text && _text.length && _text.charAt(_text.length-1) == SpanElement.kParagraphTerminator,
					"attempting to remove para terminator when it doesn't exist");
			}
			replaceTextInternal(textLength-1,textLength,"");
			modelChanged(ModelChange.TEXT_DELETED,this,textLength > 0 ? textLength-1 : 0,1);
		}
		// **************************************** 
		// Begin tree modification support code
		// ****************************************

		/** 
		 * Splits this SpanElement object at the specified position and returns a new SpanElement object for the content
		 * that follows the specified position. 
		 *
		 * <p>This method throws an error if you attempt to split a surrogate pair. In Unicode UTF-16, a surrogate pair is a pair of 
		 * 16-bit code units (a high code unit and a low code unit) that represent one of the abstract Unicode characters 
		 * that cannot be represented in a single 16-bit word. The 16-bit high code unit is in the range of D800 to DBFF. The
		 * 16-bit low code unit is in the range of DC00 to DFFF.</p>
		 * 
		 * @param relativePosition - relative position in the span to create the split
		 * @return - the newly created span. 
		 * @throws RangeError <code>relativePosition</code> is less than 0 or greater than textLength or a surrogate pair is being split.
		 *
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0
	 	 * 
	 	 * @private
	 	 */
	 	 
		public override function splitAtPosition(relativePosition:int):FlowElement
		{
			// Note to callers: If you are calling this function outside a try/catch, do ensure that the 
			// state of the model is coherent before the call.
			if (relativePosition < 0 || relativePosition > textLength)
				throw RangeError(GlobalSettings.resourceStringFunction("invalidSplitAtPosition"));
			
			if ((relativePosition < textLength) && CharacterUtil.isLowSurrogate(String(text).charCodeAt(relativePosition)))
				throw RangeError (GlobalSettings.resourceStringFunction("invalidSurrogatePairSplit"));
			
			var newSpan:SpanElement = new SpanElement();
			// clone styling information
			newSpan.id = this.id;
			newSpan.typeName = this.typeName;			
			
			if (parent)
			{
				var newBlockElement:TextElement;
				var newSpanLength:int = textLength - relativePosition;
				if (_blockElement)
				{
					// optimized version leverages player APIs
					// TODO: Jeff to add split on TextElement so we don't have to go find a group every time
					var group:GroupElement = parent.createContentAsGroup();
					
					var elementIndex:int = group.getElementIndex(_blockElement);
					
					CONFIG::debug { assert(elementIndex == parent.getChildIndex(this),"bad group index"); }
					CONFIG::debug { assert(elementIndex != -1 && elementIndex < group.elementCount,"bad span split"); }
					//trace("GROUP BEFORE: " + group.rawText);
					//trace("BLOCK BEFORE: " + group.block.content.rawText);
					//trace("calling group.splitTextElement("+elementIndex.toString()+","+relativePosition.toString()+")");
					group.splitTextElement(elementIndex, relativePosition);
					CONFIG::debug { Debugging.traceFTECall(null,group,"splitTextElement",elementIndex,relativePosition); }

					//trace("GROUP AFTER: " + group.rawText);
					//trace("BLOCK AFTER: " + group.block.content.rawText);
					
					// no guarantee on how the split works
					_blockElement = group.getElementAt(elementIndex);
					_text = _blockElement.rawText;
					CONFIG::debug { Debugging.traceFTECall(_blockElement,group,"getElementAt",elementIndex); }
					newBlockElement = group.getElementAt(elementIndex+1) as TextElement;
					CONFIG::debug { Debugging.traceFTECall(newBlockElement,group,"getElementAt",elementIndex+1); }
				}
				else if (relativePosition < textLength)
				{
					newSpan.text = _text.substr(relativePosition);
					_text = _text.substring(0, relativePosition);
				}

				// Split this span at the offset, into two equivalent spans
				modelChanged(ModelChange.TEXT_DELETED,this,relativePosition,newSpanLength);
				newSpan.quickInitializeForSplit(this, newSpanLength, newBlockElement);

				setTextLength(relativePosition);
			
				// slices it in, sets the parent and the start
				parent.addChildAfterInternal(this,newSpan);	
				
				var p:ParagraphElement = this.getParagraph();
				p.updateTerminatorSpan(this,newSpan);
				
				parent.modelChanged(ModelChange.ELEMENT_ADDED,newSpan,newSpan.parentRelativeStart,newSpan.textLength);
			}
			else
			{
				// this version also works if para is non-null but may not be as efficient.
				newSpan.format = format;

				// could be we are splitting 
				if (relativePosition < textLength)
				{
					newSpan.text = String(this.text).substr(relativePosition);
					replaceText(relativePosition,textLength,null);
				}
			}
			
			return newSpan;
		}
		
		/** @private */
		tlf_internal override function normalizeRange(normalizeStart:uint,normalizeEnd:uint):void
		{
			if (this.textLength == 1 && !bindableElement)
			{
				var p:ParagraphElement = getParagraph();
				if (p && p.getLastLeaf() == this)
				{
					var prevLeaf:FlowLeafElement = getPreviousLeaf(p);
					if (prevLeaf)
					{
						if (!TextLayoutFormat.isEqual(this.format, prevLeaf.format))
							this.format = prevLeaf.format;
					}
				}
			}
			super.normalizeRange(normalizeStart,normalizeEnd);
		}

		/** @private */
		tlf_internal override function mergeToPreviousIfPossible():Boolean
		{
			if (parent && !bindableElement)
			{
				var myidx:int = parent.getChildIndex(this);
				if (myidx != 0)
				{
					var sib:SpanElement = parent.getChildAt(myidx-1) as SpanElement;
					
					// If the element we're checking for merge has only the terminator, and the previous element
					// is not a Span, then we always merge with the previous span (NOT the previous sib). 
					// We just remove this span, and add the terminator to the previous span.
					if (!sib && this.textLength == 1 && this.hasParagraphTerminator)
					{
						var p:ParagraphElement = getParagraph();
						if (p)
						{
							var prevLeaf:FlowLeafElement = getPreviousLeaf(p) as SpanElement;
							if (prevLeaf)
							{
								parent.removeChildAt(myidx);
								return true;
							}
						}
					}

					if (sib == null)
						return false;
					
					
					// If this has an active event mirror do not merge
					if (this.hasActiveEventMirror())
						return false;
					var thisIsSimpleTerminator:Boolean = textLength == 1 && hasParagraphTerminator;
					// if sib has an active event mirror still merge if this is a simple terminator span
					if (sib.hasActiveEventMirror() && !thisIsSimpleTerminator)
						return false;
					
					// always merge if this is just a terminator
					if (thisIsSimpleTerminator || equalStylesForMerge(sib))
					{
						CONFIG::debug { assert(this.parent == sib.parent, "Should never merge two spans with different parents!"); }
						CONFIG::debug { assert(TextLayoutFormat.isEqual(this.formatForCascade,sib.formatForCascade) || (this.textLength == 1 && this.hasParagraphTerminator), "Bad merge!"); }

						// Merge the spans
						var siblingInsertPosition:int = sib.textLength;
						sib.replaceText(siblingInsertPosition, siblingInsertPosition, this.text);
						parent.removeChildAt(myidx);
						return true;
					}
				}
			} 
			return false;
		}
		
		// **************************************** 
		// Begin debug support code
		// ****************************************	
		
		/** @private */
		CONFIG::debug public override function debugCheckFlowElement(depth:int = 0, extraData:String = ""):int
		{
			// debugging function that asserts if the flow element tree is in an invalid state
			
			var rslt:int = super.debugCheckFlowElement(depth,"text:"+String(text).substr(0,32)+" "+extraData);

			assert(_blockElement == null || _blockElement.rawText == _text,"debugCheckFlowElement: mismatched text");
			var textLen:int = textLength;
			if (_text)
				rslt += assert(textLen == _text.length,"span is different than its textElement, span text length is " + _text.length.toString() + " expecting " + textLen.toString());
			else	
				rslt += assert(textLen == 0,"span is different than its textElement, span text length is null expecting " + textLen.toString());
			rslt += assert(this != getParagraph().getLastLeaf() || (_text.length >= 1 && _text.substr(_text.length-1,1) == SpanElement.kParagraphTerminator),"last span in paragraph must end with terminator");
			return rslt;
		}
	}
}
