////////////////////////////////////////////////////////////////////////////////
//
//  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.operations
{
	import flashx.textLayout.debug.assert;
	import flashx.textLayout.edit.ElementMark;
	import flashx.textLayout.edit.ElementRange;
	import flashx.textLayout.edit.IMemento;
	import flashx.textLayout.edit.MementoList;
	import flashx.textLayout.edit.ModelEdit;
	import flashx.textLayout.edit.ParaEdit;
	import flashx.textLayout.edit.SelectionState;
	import flashx.textLayout.elements.FlowElement;
	import flashx.textLayout.elements.FlowGroupElement;
	import flashx.textLayout.elements.FlowLeafElement;
	import flashx.textLayout.elements.ListElement;
	import flashx.textLayout.elements.ListItemElement;
	import flashx.textLayout.elements.ParagraphElement;
	import flashx.textLayout.elements.SubParagraphGroupElementBase;
	import flashx.textLayout.formats.IListMarkerFormat;
	import flashx.textLayout.formats.ITextLayoutFormat;
	import flashx.textLayout.formats.TextLayoutFormat;
	import flashx.textLayout.tlf_internal;

	use namespace tlf_internal;

	/**
	 * The CreateListOperation class encapsulates creating list
	 *
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0 
	 */
	public class CreateListOperation extends FlowTextOperation
	{
		// describes the target
		private var _listParentMarker:ElementMark;
		private var _mementoList:MementoList;

		private var _listFormat:ITextLayoutFormat;
		private var _listElement:ListElement;		// the element that gets created
		
		private var _postOpSelectionState:SelectionState;
		
		/** 
		 * Creates an CreateListOperation object.
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0 
		 */
		public function CreateListOperation(operationState:SelectionState, parent:FlowGroupElement = null, listFormat:ITextLayoutFormat = null)
		{
			super(operationState);
			
			this.parent = parent;
			_listFormat = listFormat;
			_mementoList = new MementoList(operationState.textFlow);
		}
		
		/** 
		 * Specifies the element this operation adds a new ListElement to.
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0 
		 */
		public function get parent():FlowGroupElement
		{
			return _listParentMarker ? _listParentMarker.findElement(originalSelectionState.textFlow) as FlowGroupElement : null;
		}
		public function set parent(value:FlowGroupElement):void
		{
			if (!value)
			{
				// descend to the lowest level non-paragraph element that contains both positions
				// effectively make the new list as close to the spans as possible
				value = textFlow;
				
				var begPos:int = this.absoluteStart;
				var endPos:int = this.absoluteEnd;
				for (;;)
				{
					var begChildIdx:int = value.findChildIndexAtPosition(begPos);
					var elem:FlowGroupElement = value.getChildAt(begChildIdx) as FlowGroupElement;
					if (elem is ParagraphElement)
						break;
					begPos -= elem.parentRelativeStart;
					endPos -= elem.parentRelativeStart;
					if (endPos >= elem.textLength)	// end pos is in the next element
						break;
					value = elem;
				}
			}
			else if (value is SubParagraphGroupElementBase)
				value = value.getParagraph().parent;
			
			_listParentMarker = new ElementMark(value,0);
		}

		/** TextLayoutFormat to be applied to the new ListElement. 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0 
		 */	
		public function get listFormat():ITextLayoutFormat
		{ return _listFormat; }
		public function set listFormat(value:ITextLayoutFormat):void
		{ _listFormat = value; }
		
		/** The new ListElement. 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0 
		 */	
		public function get newListElement():ListElement
		{ return _listElement; }
		
		/** @private */
		public override function doOperation():Boolean
		{
			var target:FlowGroupElement = parent;
			
			// find the starting child that's going to be in the list and 
			var begChildIndex:int = 0;
			var begStart:int = absoluteStart - target.getAbsoluteStart();
			CONFIG::debug { assert(begStart >= 0 && begStart < target.textLength,"CreateListOperation: bad target"); }
			
			var endChildIndex:int;
			var endStart:int = absoluteEnd - target.getAbsoluteStart();
			CONFIG::debug { assert(endStart >= 0 && endStart <= target.textLength,"CreateListOperation: bad target"); }
			
			// scratch vars
			var child:FlowGroupElement;
			
			if (begStart > 0)
			{
				// figure out the starting child
				begChildIndex = target.findChildIndexAtPosition(begStart);
				child = target.getChildAt(begChildIndex) as FlowGroupElement;
				if (child.parentRelativeStart != begStart)
				{					
					_mementoList.push(ModelEdit.splitElement(textFlow,child,begStart-child.parentRelativeStart));
					
					if (child is ParagraphElement)
						endStart++;
					begChildIndex++;
				}
			}
			
			if (endStart >= 0)
			{
				if (endStart >= target.textLength - 1)
					endChildIndex = target.numChildren;
				else
				{
					// figure out the starting child
					endChildIndex = target.findChildIndexAtPosition(endStart);
					child = target.getChildAt(endChildIndex) as FlowGroupElement;
					if (child.parentRelativeStart != endStart)			
					{
						_mementoList.push(ModelEdit.splitElement(textFlow,child,endStart-child.parentRelativeStart));
						endChildIndex++;
					}
				}
			}
			else
				endChildIndex = begChildIndex+1;
			
			_listElement = new ListElement;
			_listElement.format = listFormat;
			
			var listItem:ListItemElement;
			
			if (begChildIndex == target.numChildren)
			{
				// new list at the end of target
				child = target.getChildAt(target.numChildren-1) as FlowGroupElement;
				
				_mementoList.push(ModelEdit.splitElement(textFlow,child,child.textLength));
				_mementoList.push(ModelEdit.addElement(textFlow,_listElement,target,target.numChildren));

				if (!(child is ListItemElement))
				{
					listItem = new ListItemElement();	// NO PMD
					_mementoList.push(ModelEdit.addElement(textFlow,listItem,_listElement,_listElement.numChildren));
					_mementoList.push(ModelEdit.moveElement(textFlow,child,listItem,listItem.numChildren));
					// normalize does this
					if (listItem.normalizeNeedsInitialParagraph())
						_mementoList.push(ModelEdit.addElement(textFlow,new ParagraphElement,listItem,0));
				}
				else
					_mementoList.push(ModelEdit.moveElement(textFlow,child,_listElement,_listElement.numChildren));
			}
			else
			{
				_mementoList.push(ModelEdit.addElement(textFlow,_listElement,target,endChildIndex));
				
				// normalize does this
				if ((target is ListItemElement) && (target as ListItemElement).normalizeNeedsInitialParagraph())
				{
					_mementoList.push(ModelEdit.addElement(textFlow,new ParagraphElement,target,0));
					begChildIndex++;
					endChildIndex++;
				}

				if (begChildIndex == endChildIndex)
				{
					listItem = new ListItemElement();	// No PMD
					_mementoList.push(ModelEdit.addElement(textFlow,listItem,_listElement,0));
					_mementoList.push(ModelEdit.addElement(textFlow,new ParagraphElement,listItem,0));					
				}
				else
				{
					while (begChildIndex < endChildIndex)
					{
						child = target.getChildAt(begChildIndex) as FlowGroupElement;
						if (child is ListItemElement)
						{
							listItem = child as ListItemElement;
							_mementoList.push(ModelEdit.moveElement(textFlow,listItem,_listElement,_listElement.numChildren));
							if (!(listItem.getChildAt(0) is ParagraphElement))
								_mementoList.push(ModelEdit.addElement(textFlow,new ParagraphElement,listItem,0));
						}
						else
						{
							listItem = new ListItemElement();	// No PMD
							_mementoList.push(ModelEdit.addElement(textFlow,listItem,_listElement,_listElement.numChildren));
							_mementoList.push(ModelEdit.moveElement(textFlow,child,listItem,listItem.numChildren));
							// normalize does this
							if (listItem.normalizeNeedsInitialParagraph())
								_mementoList.push(ModelEdit.addElement(textFlow,new ParagraphElement,listItem,0));
	
							child = listItem;
						}
						child.normalizeRange(0,child.textLength);
						endChildIndex--;
					}
				}
				// normalize does this
				var testListItem:ListItemElement = target as ListItemElement;
				if (testListItem && testListItem.normalizeNeedsInitialParagraph())
					_mementoList.push(ModelEdit.addElement(textFlow,new ParagraphElement,testListItem,0));
				testListItem = target.parent as ListItemElement;
				if (testListItem && testListItem.normalizeNeedsInitialParagraph())
					_mementoList.push(ModelEdit.addElement(textFlow,new ParagraphElement,testListItem,0));
			}
			
			if (originalSelectionState.selectionManagerOperationState && textFlow.interactionManager)
			{
				textFlow.normalize();
				_postOpSelectionState = new SelectionState(textFlow,_listElement.getAbsoluteStart(),_listElement.getAbsoluteStart()+_listElement.textLength-1);
				textFlow.interactionManager.setSelectionState(_postOpSelectionState);
			}
			
			return true;
		}

		/** @private */
		public override function undo():SelectionState
		{
			_mementoList.undo();
			return originalSelectionState; 
		}
		
		/** @private */
		public override function redo():SelectionState
		{
			_mementoList.redo();
			return _postOpSelectionState; 
			
		}
	}
}
