 	 *  or when updatePopUpTransform() is called. Override this function to 
 	 *  alter the position of the popUp.  
 	 * 
-	 *  @langversion 3.0
-	 *  @playerversion Flash 10
-	 *  @playerversion AIR 1.5
-	 *  @productversion Flex 4
-	 */
-	protected function positionPopUp():void
-	{
-		
+	 *  @return The absolute position of the popUp in the global coordinate system  
+	 * 
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	protected function positionPopUp():Point
+	{
+		// This implementation doesn't handle rotation
+		var matrix:Matrix = $transform.concatenatedMatrix;
+		var regPoint:Point = new Point();
+		
+		var popUpBounds:Rectangle = new Rectangle(); 
+		determinePosition(popUpPosition, popUp.width, popUp.height,
+						  matrix, regPoint, popUpBounds);
+		
+		var adjustedPosition:String;
+		
+		// Position the popUp in the opposite direction if it 
+		// does not fit on the screen. 
+		if (screen)
+		{
+			switch(popUpPosition)
+			{
+				case "below" :
+					if (popUpBounds.bottom > screen.bottom)
+						adjustedPosition = "above"; 
+					break;
+				case "above" :
+					if (popUpBounds.top < screen.top)
+						adjustedPosition = "below"; 
+					break;
+				case "left" :
+					if (popUpBounds.left < screen.left)
+						adjustedPosition = "right"; 
+					break;
+				case "right" :
+					if (popUpBounds.right > screen.right)
+						adjustedPosition = "left"; 
+					break;
+			}
+		}
+		
+		// Get the new registration point based on the adjusted position
+		if(adjustedPosition != null)
+		{
+			var adjustedRegPoint:Point = new Point();
+			var adjustedBounds:Rectangle = new Rectangle(); 
+			determinePosition(adjustedPosition, popUp.width, popUp.height,
+							  matrix, adjustedRegPoint, adjustedBounds);
+		 
+			if (screen)
+			{
+				// If we adjusted the position but the popUp still doesn't fit, 
+				// then revert to the original position. 
+				switch(adjustedPosition)
+				{
+					case "below" :
+						if (popUpBounds.bottom > screen.bottom)
+							adjustedPosition = null; 
+						break;
+					case "above" :
+						if (popUpBounds.top < screen.top)
+							adjustedPosition = null; 
+						break;
+					case "left" :
+						if (popUpBounds.left < screen.left)
+							adjustedPosition = null; 
+						break;
+					case "right" :
+						if (popUpBounds.right > screen.right)
+							adjustedPosition = null;  
+						break;
+				}	
+			}
+			
+			if (adjustedPosition != null)
+			{
+				regPoint = adjustedRegPoint;
+				popUpBounds = adjustedBounds;
+			}
+		}
+		
+		MatrixUtil.decomposeMatrix(decomposition, matrix, 0, 0);
+		var concatScaleX:Number = decomposition[3];
+		var concatScaleY:Number = decomposition[4]; 
+		
+		// If the popUp still doesn't fit, then nudge it
+		// so it is completely on the screen. Make sure to include scale.
+
+		if (popUpBounds.top < screen.top)
+			regPoint.y += (screen.top - popUpBounds.top) / concatScaleY;
+		else if (popUpBounds.bottom > screen.bottom)
+			regPoint.y -= (popUpBounds.bottom - screen.bottom) / concatScaleY;
+		
+		if (popUpBounds.left < screen.left)
+			regPoint.x += (screen.left - popUpBounds.left) / concatScaleX;	
+		else if (popUpBounds.right > screen.right)
+			regPoint.x -= (popUpBounds.right - screen.right) / concatScaleX;
+		
+		return matrix.transformPoint(regPoint);
 	}
 	
 	//--------------------------------------------------------------------------

		addedToStage = false;
		// TODO (jszeto) Remove popup from PopUpManager
	}
}
}


import mx.core.IFlexDisplayObject;
import mx.core.IFactory;

import flash.geom.Rectangle;
import mx.utils.MatrixUtil;

use namespace mx_internal;

