<?xml version="1.0" encoding="utf-8"?>
<!--
  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.
-->


<!-- Demonstrate some example controls.  This example does not attempt to create a control for every property in the TextLayoutFramework -->

<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" label="Text Editor Example" initialize="init()" backgroundColor="#FFFFFF" horizontalScrollPolicy="off" verticalScrollPolicy="off">
	<mx:Script>
		<![CDATA[

			import flashx.textLayout.container.ContainerController;
			import flashx.textLayout.conversion.TextConverter;
			import flashx.textLayout.edit.EditManager;
			import flashx.textLayout.edit.IEditManager;
			import flashx.textLayout.edit.ElementRange;
			import flashx.textLayout.edit.SelectionState;
			import flashx.textLayout.elements.Configuration;
			import flashx.textLayout.elements.FlowElement;
			import flashx.textLayout.elements.TextFlow;
			import flashx.textLayout.elements.ParagraphElement;
			import flashx.textLayout.elements.SpanElement;
			import flashx.textLayout.events.StatusChangeEvent;
			import flashx.textLayout.events.SelectionEvent;
			import flashx.textLayout.formats.ITextLayoutFormat;
			import flashx.textLayout.formats.TextLayoutFormat;
			import flashx.textLayout.formats.TextAlign;
			import flashx.textLayout.formats.VerticalAlign;
			import flashx.textLayout.formats.BlockProgression;
			import flashx.textLayout.formats.Direction;
			import flashx.textLayout.operations.ApplyElementIDOperation;
    		import flashx.textLayout.operations.ApplyElementStyleNameOperation;
    		import flashx.textLayout.operations.FlowOperation;
			import flashx.textLayout.tlf_internal;
			
			use namespace tlf_internal;

			import flashx.undo.UndoManager;
			
			import flash.display.Sprite;
			import flash.system.Capabilities;	
			
			// the textFlow being worked on
			private var _textFlow:TextFlow = null;
			// container to hold the text
			private var _container:Sprite = null;
			
			// ///////////////////////////////////////
			// data providers for enumerated list boxes
			// ///////////////////////////////////////
			static private const textAlignData:Array = [
				{ label:"Justify",	data:TextAlign.JUSTIFY},
				{ label:"Left",		data:TextAlign.LEFT},
				{ label:"Right",	data:TextAlign.RIGHT},
				{ label:"Center",	data:TextAlign.CENTER},
				{ label:"End",		data:TextAlign.END},
				{ label:"Start",	data:TextAlign.START}
			];
			static private const verticalAlignData:Array = [
				{ label:"Bottom",	data:VerticalAlign.BOTTOM },
				{ label:"Justify",	data:VerticalAlign.JUSTIFY },
				{ label:"Middle",	data:VerticalAlign.MIDDLE },
				{ label:"Top",		data:VerticalAlign.TOP }
			];
			
			static private const blockProgressionData:Array = [
				{ label:"TopToBottom",	data:BlockProgression.TB },
				{ label:"RightToleft",	data:BlockProgression.RL }
			];
			
			static private const directionData:Array = [
				{ label:"LeftToRight",	data:Direction.LTR },
				{ label:"RightToleft",	data:Direction.RTL }
			];
			
			static private const styleLevelData:Array = [
				{ label:"TextFlow",		data:TextFlow },
				{ label:"Paragraph",	data:ParagraphElement},
				{ label:"Span",			data:SpanElement}
			];
			
			/** 
			 * initialization
			 */
			private function init():void
			{
				// create a sprite to hold the TextLines
				_container = new Sprite();
				textArea.rawChildren.addChild(_container);
				
				fontFamily.dataProvider = populateFontFamily();
				
				versionInfo.text = "Vellum: " + flashx.textLayout.TextLayoutVersion.BUILD_NUMBER + (Configuration.tlf_internal::debugCodeEnabled ? " Debug" : " Release") 
					+ ", Flex: " + mx_internal::VERSION
					+ ", Player: " + Capabilities.version;
			}
			
			/**
			* Create an array of available font families
			*/ 
			static private function populateFontFamily():Array
			{
				// really this returns an array of fonts - would be nice to strip it down to just the families
				var fonts:Array = Font.enumerateFonts(true);
				var fontfamily:Array = new Array();
				fonts.sortOn("fontName", Array.CASEINSENSITIVE);
				for(var i:int = 0; i< fonts.length; i++)
				{
					// trace(fonts[i].fontName);
					fontfamily.push({label: fonts[i].fontName, data: fonts[i].fontName});
				}
				return fontfamily;
			}
			
			/** called to set the size of this panel */
			public function setSize(w:int,h:int):void
			{
				this.width = w;
				this.height = h;
				textArea.width = width;
				textArea.height = height > bottomTabs.height ? this.height-bottomTabs.height : 0;
				if (_textFlow)
				{
					_textFlow.flowComposer.getControllerAt(0).setCompositionSize(textArea.width,textArea.height);
					_textFlow.flowComposer.updateAllControllers();
				}
			}
			
			/** called when the bottom tabs finally gets sized. */
			private function bottomTabsResize():void
			{
				setSize(width,height);
			}
			
			/** The TextFlow to edit. */
			public function get textFlow():TextFlow
			{ return _textFlow; }
			
			public function set textFlow(newFlow:TextFlow):void
			{
				// clear any old flow if present
				if (_textFlow)
				{
					_textFlow.flowComposer = null;
					_textFlow = null;
				}
				_textFlow = newFlow;
				if (_textFlow)
				{
					_textFlow.flowComposer.addController(new ContainerController(_container,textArea.width,textArea.height));
					
					// setup event listeners for selection changed and ILG loaded
					_textFlow.addEventListener(SelectionEvent.SELECTION_CHANGE,selectionChangeListener,false,0,true);
					_textFlow.addEventListener(StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE,graphicStatusChangeEvent,false,0,true);
					
					// make _textFlow editable with undo 
					_textFlow.interactionManager = new EditManager(new UndoManager());
					// initialize with a selection before the first character
					_textFlow.interactionManager.selectRange(0,0);
					
					// compose the new textFlow and give it focus
					_textFlow.flowComposer.updateAllControllers();
					_textFlow.interactionManager.setFocus();
				}
			}
			
			/** Receives an event any time an ILG with a computed size finishes loading. */
 			private function graphicStatusChangeEvent(evt:StatusChangeEvent):void
			{
				// recompose if the evt is from an element in this textFlow
				if (_textFlow && evt.element.getTextFlow() == _textFlow)
					_textFlow.flowComposer.updateAllControllers();
			}
			
			/** Receives an event any time the selection is changed.  Update the UI */
			private function selectionChangeListener(e:SelectionEvent):void
 			{ 				
 				var selectionState:SelectionState = e.selectionState;
 				var selectedElementRange:ElementRange = ElementRange.createElementRange(selectionState.textFlow, selectionState.absoluteStart, selectionState.absoluteEnd);

 				// set display according to the values at the beginning of the selection range.  For point selection/characterFormat use getCommonCharacterFormat as that tracks pending attributes waiting for the next character
 				var characterFormat:ITextLayoutFormat = _textFlow.interactionManager.activePosition == _textFlow.interactionManager.anchorPosition ? _textFlow.interactionManager.getCommonCharacterFormat() : selectedElementRange.characterFormat;
 				var paragraphFormat:ITextLayoutFormat = selectedElementRange.paragraphFormat;
 				var containerFormat:ITextLayoutFormat = selectedElementRange.containerFormat;
 				
 				updateComboBox(fontFamily,characterFormat.fontFamily);
 				fontSize.text = characterFormat.fontSize.toString();
 				lineHeight.text = characterFormat.lineHeight.toString();
 				
 				updateComboBox(textAlign,paragraphFormat.textAlign);
 				textIndent.text = paragraphFormat.textIndent.toString();
 				
 				columnCount.text = containerFormat.columnCount.toString();
 				columnGap.text = containerFormat.columnGap.toString();
 				updateComboBox(verticalAlign,containerFormat.verticalAlign);
 				
 				updateComboBox(blockProgression,_textFlow.computedFormat.blockProgression);
 				updateComboBox(directionBox,_textFlow.computedFormat.direction);
 				
 				updateStyling();
 			}
 			
 			/** Helper function to update a comboBox in the UI */
 			private function updateComboBox(box:ComboBox,val:String):void
 			{
 				for (var i:int = 0; i < box.dataProvider.length; i++)
 				{
 					if (box.dataProvider[i].data == val)
 					{
 						box.selectedIndex = i;
 						return;
 					}
 				}
 				box.text = val;
 			}
 			
 			/**
 			 * These functions are helpers for the various widgets to actually perform the operations on the TextFlow
 			 */
			private function changeFontFamily(newFontFamily:String):void
			{
				if (_textFlow && _textFlow.interactionManager is IEditManager)
				{
					var cf:TextLayoutFormat = new TextLayoutFormat();
					cf.fontFamily = newFontFamily;
					IEditManager(_textFlow.interactionManager).applyLeafFormat(cf);
					_textFlow.interactionManager.setFocus();
				}
			}
			private function changeFontSize(newFontSize:String):void
			{
				if (_textFlow && _textFlow.interactionManager is IEditManager)
				{
					var cf:TextLayoutFormat = new TextLayoutFormat();
					cf.fontSize = newFontSize;
					IEditManager(_textFlow.interactionManager).applyLeafFormat(cf);
					_textFlow.interactionManager.setFocus();
				}
			}
			private function changeLeading(newLeading:String):void
			{
				if (_textFlow && _textFlow.interactionManager is IEditManager)
				{
					var cf:TextLayoutFormat = new TextLayoutFormat();
					cf.lineHeight = newLeading;
					IEditManager(_textFlow.interactionManager).applyLeafFormat(cf);
					_textFlow.interactionManager.setFocus();
				}
			}
			
			private function changeTextAlign(newAlign:String):void
			{
				if (_textFlow && _textFlow.interactionManager is IEditManager)
				{
					var pf:TextLayoutFormat = new TextLayoutFormat();
					pf.textAlign = newAlign;
					IEditManager(_textFlow.interactionManager).applyParagraphFormat(pf);
					_textFlow.interactionManager.setFocus();
				}
			}
			
			private function changeTextIndent(newIndent:String):void
			{
				if (_textFlow && _textFlow.interactionManager is IEditManager)
				{
					var pf:TextLayoutFormat = new TextLayoutFormat();
					pf.textIndent = newIndent;
					IEditManager(_textFlow.interactionManager).applyParagraphFormat(pf);
					_textFlow.interactionManager.setFocus();
				}
			}
			
			private function changeColumnCount(newCount:String):void
			{
				if (_textFlow && _textFlow.interactionManager is IEditManager)
				{
					var cf:TextLayoutFormat = new TextLayoutFormat();
					cf.columnCount = newCount;
					IEditManager(_textFlow.interactionManager).applyContainerFormat(cf);
					_textFlow.interactionManager.setFocus();
				}
			}
			
			private function changeColumnGap(newGap:String):void
			{
				if (_textFlow && _textFlow.interactionManager is IEditManager)
				{
					var cf:TextLayoutFormat = new TextLayoutFormat();
					cf.columnGap = newGap;
					IEditManager(_textFlow.interactionManager).applyContainerFormat(cf);
					_textFlow.interactionManager.setFocus();
				}
			}
			
			private function changeVerticalAlign(newAlign:String):void
			{
				if (_textFlow && _textFlow.interactionManager is IEditManager)
				{
					var cf:TextLayoutFormat = new TextLayoutFormat();
					cf.verticalAlign = newAlign;
					IEditManager(_textFlow.interactionManager).applyContainerFormat(cf);
					_textFlow.interactionManager.setFocus();
				}
			}
			
			private function changeBlockProgression(newProgression:String):void
			{
				if (_textFlow && _textFlow.interactionManager is IEditManager)
				{
					var cf:TextLayoutFormat = new TextLayoutFormat();
					cf.blockProgression = newProgression;
					IEditManager(_textFlow.interactionManager).applyFormatToElement(_textFlow,cf);
					_textFlow.interactionManager.setFocus();
				}
			}
			
			/** Set direction on the rootElement.  This effects both columnDirection and default reading order. */
			private function changeDirection(newDirection:String):void
			{
				if (_textFlow && _textFlow.interactionManager is IEditManager)
				{
					var pf:TextLayoutFormat = new TextLayoutFormat();
					pf.direction = newDirection;
					IEditManager(_textFlow.interactionManager).applyFormatToElement(_textFlow,pf);
					_textFlow.interactionManager.setFocus();
				}
			}
			
			/** Currently selected level to display */
			private var currentStyleLevel:Class = TextFlow;
			
			/** Returns the current FlowELement element at the currentStyleLevel */
			private function currentStyleElement(absolutePosition:int):FlowElement
			{
				var e:FlowElement;
				switch(currentStyleLevel)
				{
					case TextFlow:
						e = _textFlow;
						break;
					case ParagraphElement:
						e = _textFlow.findLeaf(absolutePosition).getParagraph();
						break;
					default:
						e = _textFlow.findLeaf(absolutePosition);
				}
				return e;
			}
			
			/** Update the displayed styles. */
			private function updateStyling():void
			{
				var e:FlowElement = currentStyleElement(_textFlow.interactionManager.anchorPosition);
				styleId.text = e.id;
				styleName.text = e.styleName;
			}
			
			/** Sets the level for the current style element to view. */
			private function changeStyleLevel(newLevel:Class):void
			{
				currentStyleLevel = newLevel;
				updateStyling();
			}
			

			/** Function to apply the id or styleName to a range.  Its a bit tricker than I'd like it to be. */
			private function performStyleOperation(newData:String,operationClass:Class):void
			{
				if (_textFlow && _textFlow.interactionManager is IEditManager)
				{
					var op:FlowOperation;
					var target:FlowElement;
					
					// if its a point selection change or TextFlow change the current element - else change the range
					if (_textFlow.interactionManager.isRangeSelection() && currentStyleLevel != TextFlow)
					{
						// possibly multiple targets over the range
						var targetList:Array = [];
						var absStart:int = _textFlow.interactionManager.getSelectionState().absoluteStart;
						var absEnd:int   = _textFlow.interactionManager.getSelectionState().absoluteEnd;
						while (absStart < absEnd)
						{
							target = currentStyleElement(absStart);
							targetList.push(currentStyleElement(absStart));
							absStart = target.getAbsoluteStart() + target.textLength;
						}
						
						absStart = _textFlow.interactionManager.absoluteStart;
						IEditManager(_textFlow.interactionManager).beginCompositeOperation();
						var selectionEndDelta:int = 0;
						for each (target in targetList)
						{
							//if we are extending the style name then normalize which is called in doOp will cause the element to 
							//mergeToPrev.  The result is an invalid index.  Example:
							//
							//Initial State:
							//<span styleID="a">foo</span><span styleID="b">bar</span><span>moreFooBar</span>
							//
							//Selection from "oo" of "foo" to "more" and new styleID="b"
							//"foo" will be split:
							//<span styleID="a">f</span><span styleID="b">oo</span>...
							//
							//During operation, normalize will merge "bar" into "oo":
							//span styleID="a">f</span><span styleID="b">oobar</span>
							//
							//And most importantly, the element of "bar" is removed from the flow and ready for deletion.
							//In this case, skip to the next element.
							//
							//Watson 2291333.  - gak 03.13.09
							if(target.parent == null)
							{
								absStart += target.textLength;
								continue;
							}
							
							// it using the anchhor position to find the style element.  need to give it a range of just the first selected element.  otherwise need to iterate over many
							var operationEnd:int = absEnd < target.getAbsoluteStart()+target.textLength ? absEnd : target.getAbsoluteStart()+target.textLength;
							var textFlowLength:int = _textFlow.textLength;
							// parameters passed to operation class constructor
							// selectionState - ending selection
							// target - element to be modified
							// newData - id or styleName
							// relativeStart - target relative position to begin the modificaiton
							// relativeEnd - target relative position to end the modification
							op = new operationClass(_textFlow.interactionManager.getSelectionState(),target,newData,absStart-target.getAbsoluteStart(),operationEnd-target.getAbsoluteStart());
							IEditManager(_textFlow.interactionManager).doOperation(op);
							// new paragraphs might get created due to splitting so adjust for the additional paragraph terminators that were inserted
							if (textFlowLength < _textFlow.textLength)
							{
								absStart += _textFlow.textLength-textFlowLength;
								absEnd   += _textFlow.textLength-textFlowLength;
								operationEnd += _textFlow.textLength-textFlowLength;
								selectionEndDelta += _textFlow.textLength-textFlowLength;
							}
							absStart = operationEnd;
						}
						IEditManager(_textFlow.interactionManager).endCompositeOperation();
						
						// finally adjust the selection to include any extra chars added by split paragraphs
						if (selectionEndDelta > 0)
						{
							var anchor:int = _textFlow.interactionManager.anchorPosition;
							var active:int = _textFlow.interactionManager.activePosition;
							if (anchor < active)
								active += selectionEndDelta;
							else
								anchor += selectionEndDelta;
							_textFlow.interactionManager.selectRange(anchor,active);
							_textFlow.interactionManager.refreshSelection();
						}
					}
					else	// change the element containing the point selection
					{
						target = currentStyleElement(_textFlow.interactionManager.anchorPosition);
						op = new operationClass(_textFlow.interactionManager.getSelectionState(),target,newData);
						IEditManager(_textFlow.interactionManager).doOperation(op);
					}
					_textFlow.interactionManager.setFocus();
				}
			}
			
			private function changeStyleId(newId:String):void
			{
				performStyleOperation(newId,ApplyElementIDOperation);
			}
			private function changeStyleStyleName(newStyleName:String):void
			{
				performStyleOperation(newStyleName,ApplyElementStyleNameOperation);
			}

		]]>
	</mx:Script>
	<!-- <mx:VBox horizontalScrollPolicy="off" verticalScrollPolicy="off" width="100%" height="100%"> -->
		<mx:Canvas id="textArea" width="520" height="400"/>
		<mx:TabNavigator id="bottomTabs" width="100%" creationPolicy="all" paddingLeft="4" paddingBottom="8" backgroundColor="#D9D9D9" color="#202020" horizontalScrollPolicy="off" verticalScrollPolicy="off" resize="bottomTabsResize()">
			<mx:HBox label="Text" backgroundColor="#D9D9D9" width="496" horizontalScrollPolicy="off" verticalScrollPolicy="off" >
				<mx:Label text="Font:"/>
				<mx:ComboBox id="fontFamily" editable="true" enter="changeFontFamily(fontFamily.text)"  close="changeFontFamily(fontFamily.text)" width="200"/>
				<mx:Label text="Size:"/>
				<mx:TextInput id="fontSize" enter="changeFontSize(fontSize.text)" width="40"/>
				<mx:Label text="LineHeight:"/>
				<mx:TextInput id="lineHeight" enter="changeLeading(lineHeight.text)" width="40"/>
			</mx:HBox>
			<mx:HBox label="Para" backgroundColor="#D9D9D9" width="496">
				<mx:Label text="Alignment:"/>
				<mx:ComboBox id="textAlign" close="changeTextAlign(textAlign.selectedItem.data)" dataProvider="{textAlignData}"/>
				<mx:Label text="FirstLineIdent:"/>
				<mx:TextInput id="textIndent" enter="changeTextIndent(textIndent.text)" width="40"/>
			</mx:HBox>
			<mx:HBox label="Container" backgroundColor="#D9D9D9" width="496">
				<mx:Label text="Columns:"/>
				<mx:TextInput id="columnCount" toolTip="auto or a number" enter="changeColumnCount(columnCount.text)" width="40"/>
				<mx:Label text="Gap:"/>
				<mx:TextInput id="columnGap" toolTip="a number" enter="changeColumnGap(columnGap.text)" width="40"/>
				<mx:Label text="VerticalAlignment:"/>
				<mx:ComboBox id="verticalAlign" close="changeVerticalAlign(verticalAlign.selectedItem.data)" dataProvider="{verticalAlignData}"/>
			</mx:HBox>
			<mx:HBox label="Flow" backgroundColor="#D9D9D9" width="496">
				<mx:Label text="Progression:"/>
				<mx:ComboBox id="blockProgression" close="changeBlockProgression(blockProgression.selectedItem.data)" dataProvider="{blockProgressionData}"/>
				<mx:Label text="Direction:"/>
				<mx:ComboBox id="directionBox" close="changeDirection(directionBox.selectedItem.data)" dataProvider="{directionData}"/>
			</mx:HBox>
			<mx:HBox label="Style" backgroundColor="#D9D9D9" width="496">
				<mx:Label text="Level:"/>
				<mx:ComboBox id="styleLevel" close="changeStyleLevel(styleLevel.selectedItem.data)" dataProvider="{styleLevelData}" selectedIndex="0"/>
				<mx:Label text="id:"/>
				<mx:TextInput id="styleId" enter="changeStyleId(styleId.text)" width="40"/>
				<mx:Label text="stlyleName:"/>
				<mx:TextInput id="styleName" enter="changeStyleStyleName(styleName.text)" width="40"/>
			</mx:HBox>
			<mx:HBox label="Version" backgroundColor="#D9D9D9" width="496">
				<mx:TextInput id="versionInfo" editable="false" width="100%"/>
			</mx:HBox>
		</mx:TabNavigator>
	<!-- </mx:VBox> -->
</mx:VBox>
