////////////////////////////////////////////////////////////////////////////////
//
//  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.compose
{
	import flash.geom.Rectangle;
	import flash.text.engine.TextLine;
	
	import flashx.textLayout.debug.assert;
	import flashx.textLayout.container.ContainerController;
	import flashx.textLayout.formats.ClearFloats;
	import flashx.textLayout.formats.Direction;
	import flashx.textLayout.tlf_internal;

	use namespace tlf_internal;
		
	[ExcludeClass]
	/** Helper class for implementations of IParcelList
	 * 
	 * @private
	 */
	public class Parcel 
	{
		public var x:Number;
		public var y:Number;
		public var width:Number;
		public var height:Number;
		public var logicalWidth:Number;

		private var _controller:ContainerController;
		private var _columnIndex:int;
		private var _fitAny:Boolean;
		private var _composeToPosition:Boolean;

		private var _left:Edge;
		private var _right:Edge;
		private var _maxWidth:Number;
		
		private var _verticalText:Boolean;
		
		/** Constructor. */
		public function Parcel(verticalText:Boolean, x:Number, y:Number, width:Number, height:Number, controller:ContainerController, columnIndex:int)
		{
			initialize(verticalText, x, y, width, height, controller, columnIndex);
		}
		
		public function initialize(verticalText:Boolean, x:Number, y:Number, width:Number, height:Number, controller:ContainerController, columnIndex:int):Parcel
		{
			this.x = x;
			this.y = y;
			this.width = width;
			this.height = height;
			this.logicalWidth = verticalText ? height : width;
			this._verticalText = verticalText; 
			
			_controller   = controller;
			_columnIndex       =  columnIndex;
			_fitAny	  = false;
			_composeToPosition = false;
			
			var xmin:Number;
			var xmax:Number;
			if (verticalText)
			{
				xmin = y;
				_maxWidth = height;
			}
			else
			{
				xmin = x;
				_maxWidth = width;
			}
			if (_maxWidth <= 0)
				throw new Error("Malformed column");

			_left = new Edge(xmin);
			_right = new Edge(xmin + _maxWidth);
			return this;
		}
		
		
		/** prevent any leaks. @private */
		tlf_internal function releaseAnyReferences():void
		{
			_controller = null;
		}
		
		public function get bottom():Number	{ return (y + height); }
		public function get right():Number	{ return (x + width); }
		
		public function get controller():ContainerController
		{ return _controller; }

		/** column number in the container */
		public function get columnIndex():int
		{ return _columnIndex; }
		public function get fitAny():Boolean
		{ return _fitAny; }
		public function set fitAny(value:Boolean):void
		{ _fitAny = value; }
		public function get composeToPosition():Boolean
		{ return _composeToPosition; }
		public function set composeToPosition(value:Boolean):void
		{ _composeToPosition = value; }
		/** Do explicit line breaking (no wrapping) */

		private function getLogicalHeight():Number
		{
			if (_verticalText)
			{
				return _controller.measureWidth ? TextLine.MAX_LINE_WIDTH : width;
			}
			else
			{
				return _controller.measureHeight ? TextLine.MAX_LINE_WIDTH : height;
			}
		}
		
		// Returns the amount to move down to apply clear past any floats
		public function applyClear(clear:String, depth:Number, direction:String):Number
		{
			var leftMargin:Number;
			var rightMargin:Number;
			var adjustedDepth:Number = depth;
			
			if (clear == ClearFloats.START)
				clear = (direction == Direction.LTR) ? ClearFloats.LEFT : ClearFloats.RIGHT;
			else if (clear == ClearFloats.END)
				clear = (direction == Direction.RTL) ? ClearFloats.LEFT : ClearFloats.RIGHT;

			while (adjustedDepth < Number.MAX_VALUE)
			{
				leftMargin = _left.getMaxForSpan(adjustedDepth, adjustedDepth + 1);	// getLeftForSpan
				if (leftMargin > 0 && (clear == ClearFloats.BOTH || clear == ClearFloats.LEFT))
				{
					adjustedDepth = _left.findNextTransition(adjustedDepth);
					continue;
				}
				rightMargin = _right.getMaxForSpan(adjustedDepth, adjustedDepth + 1);	// getRightForSpan
				if (rightMargin > 0 && (clear == ClearFloats.BOTH || clear == ClearFloats.RIGHT))
				{
					adjustedDepth = _right.findNextTransition(adjustedDepth);
					continue;
				}
				
				return adjustedDepth - depth;
			} 
			
			return (_verticalText ? this.width : this.height);	
		}
		
		public function fitsInHeight(depth:Number, minimumHeight:Number):Boolean
		{
			return composeToPosition || depth + minimumHeight <= getLogicalHeight();
		}
		
		// Given a current location, what is the longest longest line of a given height that can be placed there,
		// that is at least as wide as the minimum width. Return false if there is no possible line in the parcel.
		// May shift the line down if thee is more space below.
		public function getLineSlug(slug:Slug, depth:Number, lineHeight:Number, minimumWidth:Number, minimumHeight:Number, leftMargin:Number, rightMargin:Number, textIndent:Number, directionLTR:Boolean, useExplicitLineBreaks:Boolean):Boolean
		{
			if (!fitsInHeight(depth, minimumHeight))
				return false;
			
			slug.height = lineHeight;			

			while (depth < Number.MAX_VALUE)
			{
				slug.depth = depth;

				slug.leftMargin = _left.getMaxForSpan(slug.depth, slug.depth + lineHeight);	// getLeftForSpan
				slug.wrapsKnockOut = slug.leftMargin != 0;
				if (leftMargin > 0)
					slug.leftMargin = Math.max(leftMargin, slug.leftMargin);
				else
					slug.leftMargin += leftMargin;		// negative indent, let it overlap
				slug.rightMargin = _right.getMaxForSpan(slug.depth, slug.depth + lineHeight);	// getRightForSpan
				slug.wrapsKnockOut = slug.wrapsKnockOut || (slug.rightMargin != 0);
				if (rightMargin > 0)
					slug.rightMargin = Math.max(rightMargin, slug.rightMargin);
				else
					slug.rightMargin += rightMargin;		// negative indent, let it overlap
				if (textIndent)
				{
					if (directionLTR)
						slug.leftMargin += textIndent;
					else
						slug.rightMargin += textIndent;
				}

				if (useExplicitLineBreaks || (_verticalText && _controller.measureHeight) || (!_verticalText && _controller.measureWidth))
					slug.width = TextLine.MAX_LINE_WIDTH;
				else
					slug.width = this.logicalWidth - (slug.leftMargin + slug.rightMargin);
				if (!minimumWidth || slug.width >= minimumWidth)
					break;
				depth = findNextTransition(depth);
			} 
			
			return (depth < Number.MAX_VALUE);
		}

		public function knockOut(knockOutWidth:Number, yMin:Number, yMax:Number, onLeft:Boolean):void
		{
			var edge:Edge = onLeft ? _left : _right;
			edge.addSpan(knockOutWidth, yMin, yMax);	
		}
		
		public function removeKnockOut(knockOutWidth:Number, yMin:Number, yMax:Number, onLeft:Boolean):void
		{
			var edge:Edge = onLeft ? _left : _right;
			edge.removeSpan(knockOutWidth, yMin, yMax);	
		}
		
		/** Returns true if the parcel has no knockouts */
		public function isRectangular():Boolean
		{
			return (_left.numSpans <= 0 && _right.numSpans <= 0);
		}
		
	/*	public function getLeftForSpan(ymin:Number, ymax:Number):Number
		{
			return _left.getMaxForSpan(ymin, ymax);
		}
		
		public function getRightForSpan(ymin:Number, ymax:Number):Number
		{
			return _right.getMinForSpan(ymin, ymax);
		} */
		
		public function findNextTransition(y:Number):Number
		{
			return Math.min(_left.findNextTransition(y), _right.findNextTransition(y));
		}
		
	}
}

class Span
{
	public var x:Number;
	public var ymin:Number;
	public var ymax:Number;
	
	public function Span(x:Number, ymin:Number, ymax:Number)
	{
		this.x = x;
		this.ymin = ymin;
		this.ymax = ymax;
	}
		
	public function overlapsInY(ymin:Number, ymax:Number):Boolean
	{
		return !(ymax < this.ymin || ymin >= this.ymax);
	}
	
	public function equals(x:Number, ymin:Number, ymax:Number):Boolean
	{
		return x == this.x && ymin == this.ymin && ymax == this.ymax;
	} 
}

import __AS3__.vec.Vector;
//import flashx.textLayout.utils.Twips;

class Edge
{
	private var _xbase:Number;
	private var _spanList:Vector.<Span>;
	
	public function Edge(xbase:Number)
	{
		_xbase = xbase;
		_spanList = new Vector.<Span>();
	}
	
	public function get base():Number
	{
		return _xbase;
	}
	
	public function addSpan(x:Number, ymin:Number, ymax:Number):void
	{
		_spanList.push(new Span(x, ymin, ymax));
	}
	
	public function removeSpan(x:Number, ymin:Number, ymax:Number):void
	{
		for (var i:int=0; i < _spanList.length; ++i)
		{
			if (_spanList[i].equals(x, ymin, ymax))
			{
				_spanList.splice(i,1);
				return;
			}
		}

		CONFIG::debug { flashx.textLayout.debug.assert(false, "Deleting a span not in list"); }			
	} 
	
	public function get numSpans():int
	{
		return _spanList.length;
	}
	
	public function getMaxForSpan(ymin:Number, ymax:Number):Number
	{
		var res:Number = 0;
		for each (var span:Span in _spanList)
		{
			if (span.x > res && span.overlapsInY(ymin, ymax))
				res = span.x;
		}
		return res;
	}
	
	/*public function getMinForSpan(ymin:Number, ymax:Number):Number
	{
		var res:Number = _xbase;
		for each (var span:Span in _spanList)
		{
			if (span.x < res && span.overlapsInY(ymin, ymax))
				res = span.x;
		}
		return res;
	} */
	
	public function findNextTransition(y:Number):Number
	{
		var res:Number = Number.MAX_VALUE;
		for each (var s:Span in _spanList)
		{
			if (s.ymin > y && s.ymin < res)
				res = s.ymin;
			if (s.ymax > y && s.ymax < res)
				res = s.ymax;
		}
		return res;
	}
}

