////////////////////////////////////////////////////////////////////////////////
//
//  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 mx.utils
{
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Stage;
import flash.display.StageDisplayState;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;

import mx.core.IFlexDisplayObject;
import mx.core.ILayoutElement;
import mx.core.mx_internal;
import mx.managers.ISystemManager;

use namespace mx_internal;

[ExcludeClass]

/**
 *  Helper functionality for working with pop-ups. 
 */
public class PopUpUtil
{
    
    /**
     *  Calculates the position for a pop-up in sanboxRoot coordinates (the pop-up coordinate space).
     * 
     *  @param component       The component that defines the component coordinate space.
     *  
     *  @param systemManager   The systemManager that defines the SandboxRoot.  Typically component.systemManager.
     * 
     *  @param popUpWidth      The width of the popup, in SandboxRoot coordinates (i.e. popUp.width).
     * 
     *  @param popUpHeight     The height of the popup, in SandboxRoot coordinates (i.e. popUp.height).
     * 
     *  @param verticalCenter  The desired distance from the center of the popUp to the top edge of the
     *                         component.  In component coordinates. For example, to center relative to the 
     *                         component, pass component.heihgt / 2.  To disable centering, pass NaN.
     * 
     *  @param popUpPosition   The position of the pop-up, specified in SandboxRoot coordinates (i.e. pupUp.x, popUp.y)
     * 
     *  @param regPoint        The position of the popUp, specified in the component's coordinate space.  This is ignored if 
     *                         popUpPosition is specified.
     * 
     *  @param ensureOnScreen  When true, will check against the visible screen of the application and adjust the position
     *                         if necessary. 
     *
     *  @return  The position of the pop-up in SandboxRoot coordinates.
     */
    public static function positionOverComponent(component:DisplayObject,
                                                 systemManager:ISystemManager, // The component's systemManager
                                                 popUpWidth:Number,            // in sandboxRoot coordinates
                                                 popUpHeight:Number,           // in sandboxRoot coordinates
                                                 verticalCenter:Number = NaN,  // in component coordinates, if NaN, it's ignored
                                                 popUpPosition:Point = null,   // in sandboxRoot coordinates, if specified, regPoint is ignored
                                                 regPoint:Point = null,        // in component coordinates, if not specified defaults to (0,0)
                                                 ensureOnScreen:Boolean = true):Point
    {
        // Original code:
        //        var toolTip:IToolTip = event.toolTip;
        //        
        //        // Calculate global position of label.
        //        var sm:ISystemManager = systemManager.topLevelSystemManager;
        //        var sbRoot:DisplayObject = sm.getSandboxRoot();
        //        var screen:Rectangle = sm.getVisibleApplicationRect(null, true);;
        //        var pt:Point = new Point(0, 0);
        //        pt = label.localToGlobal(pt);
        //        pt = sbRoot.globalToLocal(pt);
        //        
        //        toolTip.move(pt.x, pt.y + (height - toolTip.height) / 2);
        //        
        //        var screenRight:Number = screen.x + screen.width;
        //        pt.x = toolTip.x;
        //        pt.y = toolTip.y;
        //        pt = sbRoot.localToGlobal(pt);
        //        if (pt.x + toolTip.width > screenRight)
        //            toolTip.move(toolTip.x - (pt.x + toolTip.width - screenRight), toolTip.y);
        
        // Refactored for correctness when there's scale in play:
        
        //        var sm:ISystemManager = systemManager.topLevelSystemManager;
        //        var sbRoot:DisplayObject = sm.getSandboxRoot();
        //        
        //        // Calculate sbRoot position of label.
        //        var pt:Point = new Point(0, 0);
        //        pt = sbRoot.globalToLocal(localToGlobal(pt)); // point in sbRoot coordinates
        //
        //        // Screen in sbRoot cooridnates
        //        var screen:Rectangle = sm.getVisibleApplicationRect(null, true);
        //        var screenRight:Number = sbRoot.globalToLocal(screen.bottomRight).x; 
        //        
        //        // Height in sbRoot coordinates
        //        var h:Number = sbRoot.globalToLocal(localToGlobal(new Point(0, height))).y;
        //
        //        // Center vertically, make sure tooltip doesn't overlap right edge of the screen
        //        var x:Number = Math.min(pt.x, screenRight - toolTip.width);
        //        var y:Number = pt.y + (h - toolTip.height) / 2;
        //        toolTip.move(x, y);
        
        // Would translate to:
        
        //        var toolTip:IToolTip = event.toolTip;
        //        var pt:Point = PopUpUtil.positionOverComponent(DisplayObject(label),
        //                                                       systemManager,
        //                                                       toolTip.width, 
        //                                                       toolTip.height,
        //                                                       height / 2); 
        //        toolTip.move(pt.x, pt.y);
        
        
        var sm:ISystemManager = systemManager.topLevelSystemManager;
        var sbRoot:DisplayObject = sm.getSandboxRoot();
        
        // Find the position of the popup in sandboxRoot coordinates
        var x:Number = 0;
        var y:Number = 0;
        
        if (popUpPosition)
        {
            // Already in sandboxRoot coordinates
            x = popUpPosition.x;
            y = popUpPosition.y;
        }
        else
        {
            // If not specified, regPoint defaults to component's (0,0).
            if (!regPoint)
                regPoint = new Point(0, 0);
            
            // Convert to sandboxRoot coordinates
            var position:Point = sbRoot.globalToLocal(component.localToGlobal(regPoint));
            x = position.x;
            y = position.y;
        }
        
        // Do we need to center vertically?
        if (!isNaN(verticalCenter))
        {
            // verticalCenter is in component coordinates, convert to sandboxRoot
            var vc:Number = sbRoot.globalToLocal(component.localToGlobal(new Point(0, verticalCenter))).y;
            y = vc - popUpHeight / 2;
        }
        
        if (ensureOnScreen)
        {
            // Convert screen to sandboxRoot cooridnates
            var screen:Rectangle  = sm.getVisibleApplicationRect(null, true);
            var topLeft:Point     = sbRoot.globalToLocal(screen.topLeft);
            var bottomRight:Point = sbRoot.globalToLocal(screen.bottomRight); 
            
            // clamp position, don't round
            x = Math.max(topLeft.x, Math.min(bottomRight.x - popUpWidth, x));
            y = Math.max(topLeft.y, Math.min(bottomRight.y - popUpHeight, y));
        }
        
        return new Point(x, y);
    }
    
    /**
     *  Apply transforms from a popUp owner to the popUp.
     * 
     *  @param owner Pop-up owner
     *  @param systemManager The systemManager that defines the SandboxRoot. Typically component.systemManager.
     *  @param popUp The pop-up to apply the owner's transform to.
     *  @param popUpPoint Absolute position of the pop-up in the global coordinate space.
     *  @param colorTransform The owner's color transform
     */
    public static function applyPopUpTransform(owner:DisplayObjectContainer,
                                               colorTransform:ColorTransform,
                                               systemManager:ISystemManager,
                                               popUp:IFlexDisplayObject,
                                               popUpPoint:Point):void
    {
        var m:Matrix = MatrixUtil.getConcatenatedMatrix(owner, systemManager.getSandboxRoot());
        
        // the transformation doesn't take the fullScreenRect in to account
        // if we are in fulLScreen mode. This code will throw a RTE if run from inside of a sandbox. 
        try
        {
            var smStage:Stage = systemManager.stage;
            if (smStage && smStage.displayState != StageDisplayState.NORMAL && smStage.fullScreenSourceRect)
            {
                popUpPoint.x += smStage.fullScreenSourceRect.x;
                popUpPoint.y += smStage.fullScreenSourceRect.y;
            }
        }
        catch (e:Error)
        {
            // Ignore the RTE
        }
        
        // Position the popUp. 
        m.tx = Math.round(popUpPoint.x);
        m.ty = Math.round(popUpPoint.y);
        if (popUp is ILayoutElement)
            ILayoutElement(popUp).setLayoutMatrix(m,false);
        else if (popUp is DisplayObject)
            DisplayObject(popUp).transform.matrix = m;
        
        // apply the color transformation, but restore alpha value of popup
        var oldAlpha:Number = DisplayObject(popUp).alpha;
        var tmpColorTransform:ColorTransform = colorTransform;
        if (tmpColorTransform != null)
        {
            tmpColorTransform.alphaMultiplier = oldAlpha;
            tmpColorTransform.alphaOffset = 0;
            DisplayObject(popUp).transform.colorTransform = tmpColorTransform;
        }

    }
}
}

