////////////////////////////////////////////////////////////////////////////////
//
// ADOBE SYSTEMS INCORPORATED
// Copyright 2007-2010 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE:  Adobe permits you to use, modify, and distribute this file 
// in accordance with the terms of the license agreement accompanying it.
//
////////////////////////////////////////////////////////////////////////////////
package flashx.textLayout.utils
{
	import flash.geom.Rectangle;
	import flash.text.engine.TextLine;
	import flash.text.engine.TextLineValidity
	
	import flashx.textLayout.debug.assert;
	import flashx.textLayout.compose.IFlowComposer;
	import flashx.textLayout.compose.TextFlowLine;
	import flashx.textLayout.elements.TextRange;
	import flashx.textLayout.tlf_internal;
	
	use namespace tlf_internal;
	/** 
	 * Utilities for getting information about text geometry and bounds.
	 * The methods of this class are static and must be called using
	 * the syntax <code>GeometryUtil.method(<em>parameter</em>)</code>.
	 *
	 * @playerversion Flash 10
	 * @playerversion AIR 1.5
	 * @langversion 3.0
	 */
	 [ExcludeClass]
	public final class GeometryUtil
	{
		/**
		 * Returns an array of line/rectangle object pairs describing the highlight area of the text 
		 * based on the content bounded within the indicies. The rectangles are the same as those which would be 
		 * created if the text were selected. May return one or more pair per line.
		 * 
		 * 
		 * @param range	- a TextRange describing the TextFlow as well as the beginning and end indicies
		 * @return Array - An array of TextLine and Rectangle pairs. The objects can be referenced as:
		 * 		obj.textLine - to access the TextLine object
		 *		obj.rect - to access the rectangle describing the selection in TextLine coordinates
		 * 
		 * @playerversion Flash 10
		 * @playerversion AIR 1.5
		 * @langversion 3.0
		 * 
		 * Example Usage:
		 *  var theRect:Rectangle = returnArray[0].rect.clone(); 
		 *  var textLine:TextLine = returnArray[0].textLine; 
		 * 	var globalStart:Point = new Point(theRect.x, theRect.y);
		 *  globalStart = textLine.localToGlobal(globalStart);
		 *  globalStart = textLine.parent.globalToLocal(globalStart);
		 *  theRect.x = globalStart.x;
		 *  theRect.y = globalStart.y;
		 * 
		 *  [Make a new shape and draw the path into it. See flash.display.graphics]
		 *  textLine.parent.addChild(newShape);
		 */
		public static function getHighlightBounds(range:TextRange):Array
		{
			var flowComposer:IFlowComposer = range.textFlow.flowComposer;
			if (!flowComposer)
				return null;
			
			
			var resultShapes:Array = new Array();
			
			var begLine:int = flowComposer.findLineIndexAtPosition(range.absoluteStart);
			var endLine:int = range.absoluteStart == range.absoluteEnd ? begLine : flowComposer.findLineIndexAtPosition(range.absoluteEnd);
			
			// watch for going past the end
			if (endLine >= flowComposer.numLines)
				endLine = flowComposer.numLines-1;
					
			var prevLine:TextFlowLine = begLine > 0 ? flowComposer.getLineAt(begLine-1) : null;
			var nextLine:TextFlowLine;

			var line:TextFlowLine = flowComposer.getLineAt(begLine); 			
			
			var mainRects:Array = [];
			
			for (var curLineIndex:int = begLine; curLineIndex <= endLine; curLineIndex++)
			{
				nextLine = curLineIndex != (flowComposer.numLines - 1) ? flowComposer.getLineAt(curLineIndex + 1) : null;
				
				
				var heightAndAdj:Array = line.getRomanSelectionHeightAndVerticalAdjustment(prevLine, nextLine);
				
				var textLine:TextLine = line.getTextLine(true);

				line.calculateSelectionBounds(textLine, mainRects, 
					range.absoluteStart < line.absoluteStart ? line.absoluteStart - line.paragraph.getAbsoluteStart()
 															 : range.absoluteStart - line.paragraph.getAbsoluteStart(), 
					range.absoluteEnd > (line.absoluteStart + line.textLength) ? line.absoluteStart + line.textLength - line.paragraph.getAbsoluteStart()
																			   : range.absoluteEnd - line.paragraph.getAbsoluteStart(), 
					range.textFlow.computedFormat.blockProgression, heightAndAdj);
				
					
				for each(var rect:Rectangle in mainRects)
				{
					var obj:Object = new Object();	// NO PMD
					obj.textLine = textLine;
					obj.rect = rect.clone();
					
					resultShapes.push(obj);
				}
				mainRects.length = 0;
				
				var temp:TextFlowLine = line;
				line = nextLine;
				prevLine = temp;
			}
			
			return resultShapes;
		}
	}
	
}