////////////////////////////////////////////////////////////////////////////////
//
//  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.ElementRange;
	import flashx.textLayout.edit.ParaEdit;
	import flashx.textLayout.edit.SelectionState;
	import flashx.textLayout.elements.TextFlow;
	import flashx.textLayout.formats.Category;
	import flashx.textLayout.formats.ITextLayoutFormat;
	import flashx.textLayout.formats.TextLayoutFormat;
	import flashx.textLayout.formats.TextLayoutFormatValueHolder;
	import flashx.textLayout.property.Property;
	import flashx.textLayout.tlf_internal;
	use namespace tlf_internal;
		
	/**
	 * The ApplyFormatOperation class encapsulates a style change.
	 * 
	 * <p>An ApplyFormatOperation applies the leaf format to the text in the 
	 * specified range (no change is made if the specified range is a single point). 
	 * It applies the paragraph format to any paragraphs at least partially within the range 
	 * (or a single paragraph if the range is a single point). 
	 * And it applies the container format to any containers at least partially within the range 
	 * (or a single container if the range is a single point).</p>
	 *
	 * @see flashx.textLayout.edit.EditManager
	 * @see flashx.textLayout.events.FlowOperationEvent
	 * 
	 * @includeExample examples\ApplyFormatOperation_example.as -noswf
	 * 
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0 
	 */
	public class ApplyFormatOperation extends FlowTextOperation
	{
		private var applyLeafFormat:ITextLayoutFormat;
		private var applyParagraphFormat:ITextLayoutFormat;
		private var applyContainerFormat:ITextLayoutFormat;

		// helper array of styles to revert
		// each entry has a begIdx, endIdx, ContainerFormat
		private var undoLeafArray:Array;	
		private var undoParagraphArray:Array;	
		private var undoContainerArray:Array;	
		
		/** 
		 * Creates an ApplyFormatOperation object.
		 *
		 *  @param operationState	Defines the text range to which the format is applied.
		 *  @param leafFormat	 The format to apply to LeafFlowElement objects in the selected range.
		 *  @param paragraphFormat The format to apply to ParagraphElement objects in the selected range.
		 *  @param containerFormat The format to apply to containers in the selected range.
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0 
		 */		
		public function ApplyFormatOperation(operationState:SelectionState, leafFormat:ITextLayoutFormat, paragraphFormat:ITextLayoutFormat, containerFormat:ITextLayoutFormat = null)
		{
			super(operationState);
			this.leafFormat = leafFormat;
			this.paragraphFormat = paragraphFormat;
			this.containerFormat = containerFormat;
		}

		/** 
		 * The format properties to apply to the leaf elements in the range.
		 * 
		 * <p>If the range of this operation is a point, or if <code>leafFormat</code> is <code>null</code>,
		 * then no leaf element formats are changed.</p>
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0 
		*/
		public function get leafFormat():ITextLayoutFormat
		{
			return applyLeafFormat;
		}
		public function set leafFormat(value:ITextLayoutFormat):void
		{
			applyLeafFormat = value ? new TextLayoutFormat(value) : null;
		}
		
		/** 
		 * The format properties to apply to the paragraphs in the range.
		 * 
		 * <p>The formats of any paragraphs at least partially within the range are updated. 
		 * If the range of this operation is a point, then a single paragraph is updated.
		 * If <code>paragraphFormat</code> is <code>null</code>, then no paragraph formats are changed.</p>
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0 
		*/
		public function get paragraphFormat():ITextLayoutFormat
		{
			return applyParagraphFormat;
		}
		public function set paragraphFormat(value:ITextLayoutFormat):void
		{
			applyParagraphFormat = value ? new TextLayoutFormat(value) : null;
		}
		
		/** 
		 * The format properties to apply to the containers in the range.
		 * 
		 * <p>The formats of any containers at least partially within the range are updated. 
		 * If the range of this operation is a point, then a single container is updated.
		 * If <code>containerFormat</code> is <code>null</code>, then no container formats are changed.</p>
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
	 	 * @langversion 3.0 
		*/
		public function get containerFormat():ITextLayoutFormat
		{
			return applyContainerFormat;
		}
		public function set containerFormat(value:ITextLayoutFormat):void
		{
			applyContainerFormat = value ? new TextLayoutFormat(value) : null;
		}
		
		private function doInternal():SelectionState
		{
			var anyNewSelectionState:SelectionState;
			
			// Apply character format
			if (applyLeafFormat)
			{
				if (absoluteStart != absoluteEnd)
				{
					var range:ElementRange = ElementRange.createElementRange(textFlow, absoluteStart,absoluteEnd);
					
					var begSel:int = range.absoluteStart;
					var endSel:int = range.absoluteEnd;
					if(endSel == textFlow.textLength - 1)
						++endSel;
						
				//	CONFIG::debug { if (begSel != absoluteStart || endSel != absoluteEnd) trace("found mismatch ApplyFormatOperation"); }
					if (!undoLeafArray)
					{
						undoLeafArray = new Array();
						ParaEdit.cacheStyleInformation(textFlow,begSel,endSel,undoLeafArray);
					}
					ParaEdit.applyTextStyleChange(textFlow,begSel,endSel,applyLeafFormat,null);
				}
				else if (originalSelectionState.selectionManagerOperationState && textFlow.interactionManager)
				{
					// on point selection remember pendling leaf formats for next char typed
					
					anyNewSelectionState = originalSelectionState.clone();
					var newFormat:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder(anyNewSelectionState.pointFormat);
					newFormat.apply(applyLeafFormat);
					anyNewSelectionState.pointFormat = newFormat;
				}
			}

			if (applyParagraphFormat)
			{
				if (!undoParagraphArray)
				{
					undoParagraphArray = new Array();
					ParaEdit.cacheParagraphStyleInformation(textFlow,absoluteStart, absoluteEnd,undoParagraphArray);
				}
				ParaEdit.applyParagraphStyleChange(textFlow,absoluteStart, absoluteEnd,applyParagraphFormat,null);
			}
			if (applyContainerFormat)
			{
				if (!undoContainerArray)
				{
					undoContainerArray = new Array();
					ParaEdit.cacheContainerStyleInformation(textFlow,absoluteStart,absoluteEnd,undoContainerArray);
				}
				ParaEdit.applyContainerStyleChange(textFlow,absoluteStart,absoluteEnd,applyContainerFormat,null);
			}
			return anyNewSelectionState;
		}
		
		/** @private */
		public override function doOperation():Boolean
		{ 
			var newSelectionState:SelectionState = doInternal();
			if (newSelectionState && textFlow.interactionManager)
				textFlow.interactionManager.setSelectionState(newSelectionState);
			return true;
		}	
		
		/** @private */
		override public function redo():SelectionState
		{
			var newSelectionState:SelectionState = doInternal();
			return newSelectionState? newSelectionState : originalSelectionState;
		}
		
		/** @private */
		public override function undo():SelectionState
		{ 
			var obj:Object;
			
			// Undo character format changes
			for each (obj in undoLeafArray)
				ParaEdit.setTextStyleChange(textFlow,obj.begIdx,obj.endIdx,obj.style);

			// Undo paragraph format changes
			for each (obj in undoParagraphArray)
				ParaEdit.setParagraphStyleChange(textFlow,obj.begIdx,obj.endIdx,obj.attributes);

			// Undo container format changes
			for each (obj in undoContainerArray)
				ParaEdit.setContainerStyleChange(textFlow,obj);

			return originalSelectionState;
		}
		
	}
}