////////////////////////////////////////////////////////////////////////////////
//
//  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.managers
{

import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.events.Event;
import flash.events.IEventDispatcher;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import mx.core.FlexSprite;
import mx.core.IFlexModuleFactory;
import mx.core.ISWFBridgeGroup;
import mx.core.ISWFBridgeProvider;
import mx.core.mx_internal;
import mx.events.SWFBridgeEvent;
import mx.utils.NameUtil;
import mx.utils.SecurityUtil;
import mx.events.SWFBridgeRequest;
import mx.managers.systemClasses.MarshallingSupport;
import mx.managers.systemClasses.ChildManager;

use namespace mx_internal;

[ExcludeClass]

/**
 *  @private
 *  This class acts as the SystemManager for a popup window that is 
 *  added to a parent SystemManager from a compatible application.
 *  Instead of the popup window being a child of the host
 *  SystemManager as is normally done, the popup is a child of a
 *  SystemManagerProxy, created in the same application domain. 
 *  The SystemManagerProxy is the actual display object
 *  added to the host SystemManager.
 *  The scheme is done to give the popup window a SystemManager,
 *  with the same version of Flex and created in the same application domain,
 *  that the pop up window will be able to talk to. 
 */
public class SystemManagerProxy extends SystemManager
{
    include "../core/Version.as";

    /**
     *  Constructor.
     * 
     *  @param systemManager The system manager that this class is a proxy for.
     *  This is the system manager in the same application domain as the popup.
         *  
         *  @langversion 3.0
         *  @playerversion Flash 9
         *  @playerversion AIR 1.1
         *  @productversion Flex 3
     */
    public function SystemManagerProxy(systemManager:ISystemManager)
    {
        super();

        _systemManager = systemManager;

		mp = MarshallingSupport(systemManager.getImplementation("mx.managers::IMarshalSystemManager"));

        // We are a proxy for a popup - we are the hightest system manager.
        topLevel = true; 
                
        // Capture mouseDown so we can switch top level windows and activate
        // the right focus manager before the components inside start
        // processing the event.
        super.addEventListener(MouseEvent.MOUSE_DOWN, proxyMouseDownHandler, true);

        registerImplementation("mx.managers::IActiveWindowManager", new SystemManagerProxyActivePopUpManager(this));

        childManager = new ChildManager(this);
    }
        
	private var mp:MarshallingSupport;

    //--------------------------------------------------------------------------
    //
    //  Overridden properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  screen
    //----------------------------------
    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    override public function get isProxy():Boolean
    {
        return true;
    }

    //----------------------------------
    //  screen
    //----------------------------------
    /**
     *  @inheritDoc
     */
    override public function get screen():Rectangle
    {
        // This is called to center an Alert over the systemManager
        // this proxy represents.
        return _systemManager.screen;
    }

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    override public function get topLevelSystemManager():ISystemManager
    {
        // The document of this proxy is its pop up.
        return systemManager.topLevelSystemManager;
    }

    /**
     *  @inheritDoc
     */
    override public function get document():Object
    {
        // The document of this proxy is its pop up.
        return mp.findFocusManagerContainer(this);
    }

    /**
     *  @private
     */
    override public function set document(value:Object):void
    {
    }

    //----------------------------------
    //  systemManager
    //----------------------------------
    
    /**
     *  @private
     */
    private var _systemManager:ISystemManager;

    /**
     *  The SystemManager that is being proxied.
     *  This is the SystemManager of the application that created this proxy
     *  and the pop up window that is a child of this proxy.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */ 
    public function get systemManager():ISystemManager
    {
        return _systemManager;
    }
        
    //--------------------------------------------------------------------------
    //
    //  Overridden methods: SystemManager
    //
    //--------------------------------------------------------------------------

    /**
     *  @inheritDoc
         *  
         *  @langversion 3.0
         *  @playerversion Flash 9
         *  @playerversion AIR 1.1
         *  @productversion Flex 3
     */
    override public function getDefinitionByName(name:String):Object
    {
        return _systemManager.getDefinitionByName(name);
    }

    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    override public function create(... params):Object
    {
        return IFlexModuleFactory(_systemManager).create.apply(this, params);
    }

	override public function getImplementation(interfaceName:String):Object
	{
        var obj:Object = super.getImplementation(interfaceName);
        if (obj) return obj;

		return _systemManager.getImplementation(interfaceName);
	}

    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    override public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, 
                                            priority:int=0, useWeakReference:Boolean=false):void
    {
        super.addEventListener(type, listener, useCapture, priority, useWeakReference);
        _systemManager.addEventListener(type, listener, useCapture, priority, useWeakReference);
    }
    
    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    override public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void 
    {
        super.removeEventListener(type, listener, useCapture);
        _systemManager.removeEventListener(type, listener, useCapture);     
    }
    
	/**
	 *  @private
         *  
         *  @langversion 3.0
         *  @playerversion Flash 9
         *  @playerversion AIR 1.1
         *  @productversion Flex 3
	 */
	override public function isTopLevel():Boolean
	{
		return systemManager.isTopLevel();
	}

       
    /**
     *  @inheritdoc
     * 
     *  proxy to real system manager.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */  
    override public function getVisibleApplicationRect(bounds:Rectangle = null, skipToSandboxRoot:Boolean = false):Rectangle
    {
        return _systemManager.getVisibleApplicationRect(bounds, skipToSandboxRoot);    
    }

    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

    /**
     *  Activates the FocusManager in an IFocusManagerContainer for the 
     *  popup window parented by this proxy.
     * 
     *  @param f The top-level window whose FocusManager should be activated.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function activateByProxy(f:IFocusManagerContainer):void
    {
		var awm:IActiveWindowManager = 
			IActiveWindowManager(systemManager.getImplementation("mx.managers::IActiveWindowManager"));
        awm.activate(f);      
    }

    /**
     *  Deactivates the focus manager for the popup window
     *  parented by this proxy.
     * 
     *  @param f The top-level window whose FocusManager should be deactivated.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function deactivateByProxy(f:IFocusManagerContainer):void
    {
        if (f)
	        f.focusManager.deactivate();
    }

    //--------------------------------------------------------------------------
    //
    //  Event handlers
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  Handles mouse downs on the pop up window.
     */
    private function proxyMouseDownHandler(event:MouseEvent):void
    {
        // Tell our parent system manager we are active if our child
        // is a focus container. If our child is not a focus manager
        // container we will not be able to activate pop up in this proxy. 
        if (mp.findFocusManagerContainer(this))
            mp.dispatchActivatedWindowEvent(this);
    }


}

}


import flash.display.DisplayObject;
import flash.events.IEventDispatcher;
import mx.core.ISWFBridgeProvider;
import mx.events.SWFBridgeEvent;
import mx.managers.IActiveWindowManager;
import mx.managers.IFocusManagerContainer;
import mx.managers.IMarshalSystemManager;
import mx.managers.ISystemManager;
import mx.managers.SystemManagerProxy;
import mx.utils.NameUtil;
import mx.utils.SecurityUtil;

class SystemManagerProxyActivePopUpManager implements IActiveWindowManager
{

	private var systemManager:ISystemManager;

	public function SystemManagerProxyActivePopUpManager(systemManager:ISystemManager)
	{
		this.systemManager = systemManager;
	}

    /**
     *  @inheritDoc
     */
    public function activate(f:Object):void
    {
        // trace("SM Proxy: activate " + f );
        
        // Activate the proxied SystemManager.
		var mp:IMarshalSystemManager = 
			IMarshalSystemManager(systemManager.getImplementation("mx.managers::IMarshalSystemManager"));

        var bridge:IEventDispatcher =
	        mp.swfBridgeGroup ? mp.swfBridgeGroup.parentBridge : null;

        if (bridge)
        {
            var mutualTrust:Boolean =
		        SecurityUtil.hasMutualTrustBetweenParentAndChild(ISWFBridgeProvider(mp));

            var bridgeEvent:SWFBridgeEvent = new SWFBridgeEvent(
		        SWFBridgeEvent.BRIDGE_WINDOW_ACTIVATE,
				false, false,
				{ notifier: bridge,
					window: mutualTrust ? systemManager : NameUtil.displayObjectToString(DisplayObject(systemManager))
				});
                    
			systemManager.getSandboxRoot().dispatchEvent(bridgeEvent);
        }
    }

	/**
	 *  @inheritDoc
	 */
    public function deactivate(f:Object):void
    {
        // trace("SM Proxy: deactivate " + f );

	    // Deactivate the proxied SystemManager.

		var mp:IMarshalSystemManager = 
			IMarshalSystemManager (systemManager.getImplementation("mx.managers::IMarshalSystemManager"));
            
		var bridge:IEventDispatcher =
			mp.swfBridgeGroup ? mp.swfBridgeGroup.parentBridge : null;
            
	    if (bridge)
        {
            var mutualTrust:Boolean =
		        SecurityUtil.hasMutualTrustBetweenParentAndChild(ISWFBridgeProvider(mp));
                    
			var bridgeEvent:SWFBridgeEvent = new SWFBridgeEvent(
				SWFBridgeEvent.BRIDGE_WINDOW_DEACTIVATE,
                false, false,
				{ notifier: bridge,
				    window: mutualTrust ? systemManager : NameUtil.displayObjectToString(DisplayObject(systemManager))
				});

             systemManager.getSandboxRoot().dispatchEvent(bridgeEvent);
         }
    }

	public function get numModalWindows():int
	{
		return systemManager.numModalWindows;
	}

	/**
	 *  @private
	 */
	public function set numModalWindows(value:int):void
	{
        systemManager.numModalWindows = value;
	}

	/**
	 *  @inheritDoc
	 */
	public function addFocusManager(f:IFocusManagerContainer):void
	{
	}

	/**
	 *  @inheritDoc
	 */
	public function removeFocusManager(f:IFocusManagerContainer):void
	{
        deactivate(f);        
    }

}
