////////////////////////////////////////////////////////////////////////////////
//
//  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.desktop.Clipboard;
import flash.desktop.NativeDragManager;
import flash.desktop.NativeDragOptions;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.InteractiveObject;
import flash.events.Event;
import flash.events.IEventDispatcher;
import flash.events.MouseEvent;
import flash.events.NativeDragEvent;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.system.Capabilities;
import flash.utils.getDefinitionByName;

import mx.core.DragSource;
import mx.core.IFlexDisplayObject;
import mx.core.IFlexModule;
import mx.core.IFlexModuleFactory;
import mx.core.IUIComponent;
import mx.core.UIComponentGlobals;
import mx.core.mx_internal;
import mx.events.DragEvent;
import mx.events.FlexEvent;
import mx.events.InterDragManagerEvent;
import mx.events.InterManagerRequest;
import mx.managers.dragClasses.DragProxy;
import mx.styles.CSSStyleDeclaration;
import mx.styles.IStyleManager2;
import mx.styles.StyleManager;
import mx.utils.Platform;

use namespace mx_internal;

[ExcludeClass]

/**
 *  @private
 * 
 *  @playerversion AIR 1.1
 */
public class NativeDragManagerImpl implements IDragManager
{
 
    //--------------------------------------------------------------------------
    //
    //  Class variables
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    private static var sm:ISystemManager;

    /**
     *  @private
     */
    private static var instance:IDragManager;

    //--------------------------------------------------------------------------
    //
    //  Class methods
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    public static function getInstance():IDragManager
    {
        if (!instance)
        {
            sm = SystemManagerGlobals.topLevelSystemManagers[0];
            instance = new NativeDragManagerImpl();
        }

        return instance;
    }

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    public function NativeDragManagerImpl()
    {
        super();

        if (instance)
            throw new Error("Instance already exists.");
            
        registerSystemManager(sm);
        sandboxRoot = sm.getSandboxRoot();
        sandboxRoot.addEventListener(InterDragManagerEvent.DISPATCH_DRAG_EVENT, marshalDispatchEventHandler, false, 0, true);

        // trace("creating DragManagerImpl", sm);
        sandboxRoot.addEventListener(InterManagerRequest.DRAG_MANAGER_REQUEST, marshalDragManagerHandler, false, 0, true);
        var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.DRAG_MANAGER_REQUEST);
        me.name = "update";
        // trace("--->update request for DragManagerImpl", sm);
        sandboxRoot.dispatchEvent(me);
        // trace("<---update request for DragManagerImpl", sm);
    }

    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  Object being dragged around.
     */
    public var dragProxy:DragProxy;

    /**
     *  @private
     */
    private var mouseIsDown:Boolean = false;

    private var _action:String;

    /**
     *  @private
     */
    private var _dragInitiator:IUIComponent;
    
    /**
     *  @private
     */
    private var _clipboard:Clipboard;
    
    /**
     *  @private
     */
    private var _dragImage:IFlexDisplayObject;
    
    private var _offset:Point;
    
    private var _allowedActions:NativeDragOptions;
    
    private var _allowMove:Boolean;
    
    private var _relatedObject:InteractiveObject;
    
    private var _imageAlpha:Number;
    
    /**
     *  @private
     *  The highest place we can listen for events in our DOM
     */
    private var sandboxRoot:IEventDispatcher;

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------
        
    /**
     *  Read-only property that returns <code>true</code>
     *  if a drag is in progress.
     *  
     *  @langversion 3.0
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get isDragging():Boolean
    {
        return flash.desktop.NativeDragManager.isDragging;// || bDoingDrag;
    }
    
    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------
    

    /**
     *  Initiates a drag and drop operation.
     *
     *  @param dragInitiator IUIComponent that specifies the component initiating
     *  the drag.
     *
     *  @param dragSource DragSource object that contains the data
     *  being dragged.
     *
     *  @param mouseEvent The MouseEvent that contains the mouse information
     *  for the start of the drag.
     *
     *  @param dragImage The image to drag. This argument is optional.
     *  If omitted, a standard drag rectangle is used during the drag and
     *  drop operation. If you specify an image, you must explicitly set a 
     *  height and width of the image or else it will not appear.
     *
     *  @param xOffset Number that specifies the x offset, in pixels, for the
     *  <code>dragImage</code>. This argument is optional. If omitted, the drag proxy
     *  is shown at the upper-left corner of the drag initiator. The offset is expressed
     *  in pixels from the left edge of the drag proxy to the left edge of the drag
     *  initiator, and is usually a negative number.
     *
     *  @param yOffset Number that specifies the y offset, in pixels, for the
     *  <code>dragImage</code>. This argument is optional. If omitted, the drag proxy
     *  is shown at the upper-left corner of the drag initiator. The offset is expressed
     *  in pixels from the top edge of the drag proxy to the top edge of the drag
     *  initiator, and is usually a negative number.
     *
     *  @param imageAlpha Number that specifies the alpha value used for the
     *  drag image. This argument is optional. If omitted, the default alpha
     *  value is 0.5. A value of 0.0 indicates that the image is transparent;
     *  a value of 1.0 indicates it is fully opaque. 
     *  
     *  @langversion 3.0
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function doDrag(
            dragInitiator:IUIComponent, 
            dragSource:DragSource, 
            mouseEvent:MouseEvent,
            dragImage:IFlexDisplayObject = null, // instance of dragged item(s)
            xOffset:Number = 0,
            yOffset:Number = 0,
            imageAlpha:Number = 0.5,
            allowMove:Boolean = true):void
    {
        if (dragAutomationHandlerClass)
        {
            dragAutomationHandlerClass["storeAIRDragSourceDetails"](dragSource);
        }
        
        var proxyWidth:Number;
        var proxyHeight:Number;
        
        // Can't start a new drag if we're already in the middle of one...
        if (isDragging)
            return; 
        
        // Can't do a drag if the mouse isn't down
        if (!(mouseEvent.type == MouseEvent.MOUSE_DOWN ||
              mouseEvent.type == MouseEvent.CLICK ||
              mouseIsDown ||
              mouseEvent.buttonDown)) 
        { 
            return;
        }
        
        var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.DRAG_MANAGER_REQUEST);
        me.name = "isDragging";
        me.value = true;
        // trace("-->dispatch isDragging for DragManagerImpl", sm, true);
        sandboxRoot.dispatchEvent(me);
        // trace("<--dispatch isDragging for DragManagerImpl", sm, true);
        
        me = new InterManagerRequest(InterManagerRequest.DRAG_MANAGER_REQUEST);
        me.name = "mouseShield";
        me.value = true;
        // trace("-->dispatch add mouseShield.for DragManagerImpl", sm);
        sandboxRoot.dispatchEvent(me);

        _clipboard = new Clipboard();
        _dragInitiator = dragInitiator;
        _offset = new Point(xOffset, yOffset);
        _allowMove = allowMove;
        _imageAlpha = imageAlpha;
        
        //adjust offsets for imagePlacement.
        _offset.y -= InteractiveObject(dragInitiator).mouseY;
        _offset.x -= InteractiveObject(dragInitiator).mouseX;
        
        // TODO!!! We need to pass in these values as a function parameter
        _allowedActions = new NativeDragOptions();
        _allowedActions.allowCopy = true;
        _allowedActions.allowLink = true;
        _allowedActions.allowMove = allowMove;
        
        // Transfer the dragSource into a Clipboard
        for (var i:int = 0; i < dragSource.formats.length; i++)
        {
            var format:String = dragSource.formats[i] as String;
            
            // Create an object to store a reference to the format and dragSource.
            // This delays copying over the drag data until it is needed
            var dataFetcher:DragDataFormatFetcher = new DragDataFormatFetcher();
            dataFetcher.dragSource = dragSource;
            dataFetcher.format = format;
                        
            _clipboard.setDataHandler(format, dataFetcher.getDragSourceData, false);
        }    
        
        if (!dragImage)
        {
            // No drag image specified, use default
			var dragManagerStyleDeclaration:CSSStyleDeclaration =
				getStyleManager(dragInitiator).getStyleDeclaration("mx.managers.DragManager");
            var dragImageClass:Class =
                dragManagerStyleDeclaration.getStyle("defaultDragImageSkin");
            dragImage = new dragImageClass();
            proxyWidth = dragInitiator ? dragInitiator.width : 0;
            proxyHeight = dragInitiator ? dragInitiator.height : 0;
            if (dragImage is IFlexDisplayObject)
                IFlexDisplayObject(dragImage).setActualSize(proxyWidth, proxyHeight);
        }
        else
        {
            proxyWidth = dragImage.width;
            proxyHeight = dragImage.height;
        }

        _dragImage = dragImage;     
                     
        if (dragAutomationHandlerClass)
        {
            dragAutomationHandlerClass["recordAutomatableDragStart1"](dragInitiator as IUIComponent, mouseEvent);
        }
                        
        if (dragImage is IUIComponent && dragImage is ILayoutManagerClient && 
            !ILayoutManagerClient(dragImage).initialized && dragInitiator)
        {
            dragImage.addEventListener(FlexEvent.UPDATE_COMPLETE,initiateDrag);
            dragInitiator.systemManager.popUpChildren.addChild(DisplayObject(dragImage));
                        
            if (dragImage is ILayoutManagerClient )
            {
                UIComponentGlobals.layoutManager.validateClient(ILayoutManagerClient(dragImage), true);
            }
            
            if(dragImage is IUIComponent)
            {
                dragImage.setActualSize(proxyWidth, proxyHeight);
                proxyWidth = (dragImage as IUIComponent).getExplicitOrMeasuredWidth();
                proxyHeight = (dragImage as IUIComponent).getExplicitOrMeasuredHeight();
            }
            else
            {
                proxyWidth = dragImage.measuredWidth;
                proxyHeight = dragImage.measuredHeight;
            }
            
            if (dragImage is ILayoutManagerClient )
            {
                UIComponentGlobals.layoutManager.validateClient(ILayoutManagerClient(dragImage));
            }
        }
        else
        { 
            initiateDrag(null, false);
            return;
        }
    }
    
    /**
     *  Finish up the doDrag once the dragImage has been drawn
     *  
     *  @langversion 3.0
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */ 
    private function initiateDrag(event:FlexEvent, removeImage:Boolean = true):void
    {
        if (removeImage)
            _dragImage.removeEventListener(FlexEvent.UPDATE_COMPLETE, initiateDrag);
        var dragBitmap:BitmapData;
        if (_dragImage.width && _dragImage.height)
            dragBitmap = new BitmapData(_dragImage.width, _dragImage.height, true, 0x000000);
        else
            dragBitmap = new BitmapData(1, 1, true, 0x000000);
        
        // Adjust the alpha while copying the image into the dragBitmap.
        var colorTransform:ColorTransform = new ColorTransform();
        colorTransform.alphaMultiplier = _imageAlpha;
        
        dragBitmap.draw(_dragImage, new Matrix(), colorTransform);
        
        if (removeImage && _dragImage is IUIComponent && _dragInitiator)        
        {
            _dragInitiator.systemManager.popUpChildren.removeChild(DisplayObject(_dragImage));
        }
        
        // TODO!!! include _dragActions as the last param
        flash.desktop.NativeDragManager.doDrag(InteractiveObject(_dragInitiator), _clipboard, dragBitmap, _offset, _allowedActions); 
        //NativeDragManager.dropAction = _allowMove ? DragManager.MOVE : DragManager.COPY;
    }
    
    /**
     *  Call this method from your <code>dragEnter</code> event handler if you accept
     *  the drag/drop data.
     *  For example: 
     *
     *  <pre>DragManager.acceptDragDrop(event.target);</pre>
     *
     *    @param target The drop target accepting the drag.
     *  
     *  @langversion 3.0
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function acceptDragDrop(target:IUIComponent):void
    {
        if (isDragging)
        {
            // trace("NativeDragMgr.acceptDragDrop targ",target);
            var dispObj:InteractiveObject = target as InteractiveObject;
            if (dispObj)
                flash.desktop.NativeDragManager.acceptDragDrop(dispObj);
        }
        else
        {
            var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.DRAG_MANAGER_REQUEST);
            me.name = "acceptDragDrop";
            me.value = target;
            // trace("-->dispatch acceptDragDrop for DragManagerImpl", sm, target);
            sandboxRoot.dispatchEvent(me);
            // trace("<--dispatch acceptDragDrop for DragManagerImpl", sm, target);
        }
    }
    
    /**
     *  Sets the feedback indicator for the drag and drop operation.
     *  Possible values are <code>DragManager.COPY</code>, <code>DragManager.MOVE</code>,
     *  <code>DragManager.LINK</code>, or <code>DragManager.NONE</code>.
     *
     *  @param feedback The type of feedback indicator to display.
     *  
     *  @langversion 3.0
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function showFeedback(feedback:String):void
    {
        if (isDragging)
        {
            if (feedback == DragManager.MOVE && !_allowedActions.allowMove)
                return;
            else if (feedback == DragManager.COPY && !_allowedActions.allowCopy)
                return;
            else if (feedback == DragManager.LINK && !_allowedActions.allowLink)
                return;
            flash.desktop.NativeDragManager.dropAction = feedback;
        }
        else
        {
            var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.DRAG_MANAGER_REQUEST);
            me.name = "showFeedback";
            me.value = feedback;
            // trace("-->dispatch showFeedback for DragManagerImpl", sm, feedback);
            sandboxRoot.dispatchEvent(me);
            // trace("<--dispatch showFeedback for DragManagerImpl", sm, feedback);
        }
    }
    
    /**
     *  Returns the current drag and drop feedback.
     *
     *  @return  Possible return values are <code>DragManager.COPY</code>, 
     *  <code>DragManager.MOVE</code>,
     *  <code>DragManager.LINK</code>, or <code>DragManager.NONE</code>.
     *  
     *  @langversion 3.0
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getFeedback():String
    {
        if (!isDragging)
        {
            var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.DRAG_MANAGER_REQUEST);
            me.name = "getFeedback";
            // trace("-->dispatch getFeedback for DragManagerImpl", sm);
            sandboxRoot.dispatchEvent(me);
            // trace("<--dispatch getFeedback for DragManagerImpl", sm);
            return me.value as String;
        }

        return flash.desktop.NativeDragManager.dropAction;
    }
    
    /**
     *  @Review
     *  Not Supported by NativeDragManagerImpl
     *  
     *  @langversion 3.0
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function endDrag():void
    {
        var me:InterManagerRequest;

        me = new InterManagerRequest(InterManagerRequest.DRAG_MANAGER_REQUEST);
        me.name = "mouseShield";
        me.value = false;
        // trace("-->dispatch remove mouseShield.for DragManagerImpl", sm);
        sandboxRoot.dispatchEvent(me);
        
        me = new InterManagerRequest(InterManagerRequest.DRAG_MANAGER_REQUEST);
        me.name = "isDragging";
        me.value = false;
        // trace("-->dispatch isDragging for DragManagerImpl", sm, false);
        sandboxRoot.dispatchEvent(me);
        // trace("<--dispatch isDragging for DragManagerImpl", sm, false);
        // trace("<--endDrag for DragManagerImpl", sm);

    }
            
    /**
     *  @private
     *  register ISystemManagers that will listen for events 
     *  (such as those for additional windows)
     */
    mx_internal function registerSystemManager(sm:ISystemManager):void
    {
        if (sm.isTopLevel())
        {
            sm.addEventListener(MouseEvent.MOUSE_DOWN, sm_mouseDownHandler);
            sm.addEventListener(MouseEvent.MOUSE_UP, sm_mouseUpHandler);
        }

        sm.stage.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, nativeDragEventHandler, true);
        sm.stage.addEventListener(NativeDragEvent.NATIVE_DRAG_COMPLETE, nativeDragEventHandler, true);
        sm.stage.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP, nativeDragEventHandler, true);
        sm.stage.addEventListener(NativeDragEvent.NATIVE_DRAG_EXIT, nativeDragEventHandler, true);
        sm.stage.addEventListener(NativeDragEvent.NATIVE_DRAG_OVER, nativeDragEventHandler, true);
        sm.stage.addEventListener(NativeDragEvent.NATIVE_DRAG_START, nativeDragEventHandler, true); 

    }
    
    /**
     *  @private
     *  unregister ISystemManagers that will listen for events 
     *  (such as those for additional windows)
     */
    mx_internal function unregisterSystemManager(sm:ISystemManager):void
    {
        if (sm.isTopLevel())
        {
            sm.removeEventListener(MouseEvent.MOUSE_DOWN, sm_mouseDownHandler);
            sm.removeEventListener(MouseEvent.MOUSE_UP, sm_mouseUpHandler);
        }

        sm.stage.removeEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, nativeDragEventHandler, true);
        sm.stage.removeEventListener(NativeDragEvent.NATIVE_DRAG_COMPLETE, nativeDragEventHandler, true);
        sm.stage.removeEventListener(NativeDragEvent.NATIVE_DRAG_DROP, nativeDragEventHandler, true);
        sm.stage.removeEventListener(NativeDragEvent.NATIVE_DRAG_EXIT, nativeDragEventHandler, true);
        sm.stage.removeEventListener(NativeDragEvent.NATIVE_DRAG_OVER, nativeDragEventHandler, true);
        sm.stage.removeEventListener(NativeDragEvent.NATIVE_DRAG_START, nativeDragEventHandler, true); 

    }
    
    /**
     *  @private
     */
    static private function getStyleManager(dragInitiator:IUIComponent):IStyleManager2
    {
        // If the dragInitiator has a styleManager, use that one.
        // In a situation where a main application that loads a module with drag initiator,
        // the main application may not link in the DragManager and appropriate styles.
        // We want to use the styles of the module of the dragInitiator. See SDK-24324.
        if (dragInitiator is IFlexModule)
            return StyleManager.getStyleManager(IFlexModule(dragInitiator).moduleFactory);
        
        return StyleManager.getStyleManager(sm as IFlexModuleFactory);
    }
    
    
    //--------------------------------------------------------------------------
    //
    //  Automation
    //
    //--------------------------------------------------------------------------
    /**
     * @private
     * This function gets the class which is responsible for getting the 
     * drag automation handler class.
     */
          
     private var _dragAutomationHandlerClass:Class;
     
     /**
      *  @private
      */  
     private function get dragAutomationHandlerClass():Class
     {
         if (!_dragAutomationHandlerClass)
         {     
              try
             {
                 if (sm)
                 {
                     _dragAutomationHandlerClass = 
                         Class(sm.getDefinitionByName("mx.automation.delegates.DragManagerAutomationImpl"));
                 }
                 else
                 {
                     _dragAutomationHandlerClass = 
                         Class(getDefinitionByName("mx.automation.delegates.DragManagerAutomationImpl"));
                 }
             }
             catch (e:Error)
             {
                 trace(e.message);
             }
         }     
         return _dragAutomationHandlerClass;
     }
    
    //--------------------------------------------------------------------------
    //
    //  Event handlers
    //
    //--------------------------------------------------------------------------
    private function sm_mouseDownHandler(event:MouseEvent):void
    {
        mouseIsDown = true;
    }

    private function sm_mouseUpHandler(event:MouseEvent):void
    {
        mouseIsDown = false;
    }
    
    /**
     *  Listens for all NativeDragEvents and then redispatches them as DragEvents 
     *  
     *  @langversion 3.0
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    private function nativeDragEventHandler(event:NativeDragEvent):void
    {
        var newType:String = event.type.charAt(6).toLowerCase() + event.type.substr(7);
        var dragSource:DragSource = new DragSource();
        var target:DisplayObject = event.target as DisplayObject;        
        var clipboard:Clipboard = event.clipboard;
        var origFormats:Array = clipboard.formats;
        var len:int = origFormats.length;
        var format:String;
        var data:Object;
        var me:InterManagerRequest;
        
        _allowedActions = event.allowedActions;
        
        //translate either commandKey or controlKey to old-style ctrlKey 
        var ctrlKey:Boolean = false;
        if (Platform.isMac)
            ctrlKey = event.commandKey;
        else
            ctrlKey = event.controlKey;    
        
        //default to move if drag is from same app
                if (NativeDragManager.dragInitiator && event.type == NativeDragEvent.NATIVE_DRAG_START)
                {
                    flash.desktop.NativeDragManager.dropAction =  
                        (ctrlKey || !_allowMove) ? DragManager.COPY : DragManager.MOVE;
                }
    
        // Transfer clipboard data to dragSource    
        if (event.type != NativeDragEvent.NATIVE_DRAG_EXIT)
        {
            for (var i:int = 0; i < len; i++)
            { 
                format = origFormats[i];
                if (clipboard.hasFormat(format))
                {
                    // Create an object to store a reference to the format and clipboard.
                    // This delays copying over the drag data until it is needed                    
                    var dataFetcher:DragDataFormatFetcher = new DragDataFormatFetcher();
                    dataFetcher.clipboard = clipboard;
                    dataFetcher.format = format;
                        
                    dragSource.addHandler(dataFetcher.getClipboardData, format);    
                }
            }
        } 
        if (event.type == NativeDragEvent.NATIVE_DRAG_DROP)
            _relatedObject = event.target as InteractiveObject;
        


        // Need a dragInitiator in NativeDragEvent
        var dragEvent:DragEvent 
            = new DragEvent(newType, false, event.cancelable, 
                            NativeDragManager.dragInitiator as IUIComponent, 
                            dragSource, event.dropAction, ctrlKey, 
                            event.altKey, event.shiftKey);
        dragEvent.buttonDown = event.buttonDown;
        dragEvent.delta = event.delta;
        dragEvent.localX = event.localX;
        dragEvent.localY = event.localY;
        if (newType == DragEvent.DRAG_COMPLETE)
            dragEvent.relatedObject = _relatedObject;
        else
            dragEvent.relatedObject = event.relatedObject;
            
        if (dragAutomationHandlerClass)
        {
            if (newType == DragEvent.DRAG_DROP)
            {
                dragAutomationHandlerClass["recordAutomatableDragDrop1"](target,dragEvent);
            }
            else if (newType == DragEvent.DRAG_COMPLETE)
            {
                   dragAutomationHandlerClass["recordAutomatableDragCancel1"]
                       (NativeDragManager.dragInitiator as IUIComponent, dragEvent);
            }
        }    
            
        // Resend the event as a DragEvent.
        _dispatchDragEvent(target, dragEvent);
                 
        if (newType == DragEvent.DRAG_COMPLETE)
        {
            if (sm == sandboxRoot)
                endDrag();
            else 
            {
                me = new InterManagerRequest(InterManagerRequest.DRAG_MANAGER_REQUEST);
                me.name = "endDrag";
                // trace("-->dispatch endDrag for DragManagerImpl", sm);
                sandboxRoot.dispatchEvent(me);
                // trace("<--dispatch endDrag for DragManagerImpl", sm);
            }
        }
    }

    /**
     *  @private
     */
    private function _dispatchDragEvent(target:DisplayObject, event:DragEvent):void
    {
        // in trusted mode, the target could be in another application domain
        // in untrusted mode, the mouse events shouldn't work so we shouldn't be here

        // same domain
        if (isSameOrChildApplicationDomain(target))
            target.dispatchEvent(event);
        else
        {
            // wake up all the other DragManagers
            var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.INIT_MANAGER_REQUEST);
            me.name = "mx.managers.IDragManagerImpl";
            sandboxRoot.dispatchEvent(me);
            // bounce this message off the sandbox root and hope
            // another DragManager picks it up
            var mde:InterDragManagerEvent = new InterDragManagerEvent(InterDragManagerEvent.DISPATCH_DRAG_EVENT, false, false,
                                                    event.localX,
                                                    event.localY,
                                                    event.relatedObject,
                                                    event.ctrlKey,
                                                    event.altKey,
                                                    event.shiftKey,
                                                    event.buttonDown,
                                                    event.delta,
                                                    target,
                                                    event.type,
                                                    event.dragInitiator,
                                                    event.dragSource,
                                                    event.action,
                                                    event.draggedItem
                                                    );
            sandboxRoot.dispatchEvent(mde);
        }
    }

    private function isSameOrChildApplicationDomain(target:Object):Boolean
    {
        var swfRoot:DisplayObject = SystemManager.getSWFRoot(target);
        if (swfRoot)
            return true;

        var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.SYSTEM_MANAGER_REQUEST);
        me.name = "hasSWFBridges";
        sandboxRoot.dispatchEvent(me);
        
        // if no bridges, it might be a private/internal class so return true and hope we're right
        if (!me.value) return true;

        return false;
    }

    /**
     *  Marshal dispatchEvents
     *  
     *  @langversion 3.0
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    private function marshalDispatchEventHandler(event:Event):void
    {
        if (event is InterDragManagerEvent)
            return;

        var marshalEvent:Object = event;

        var swfRoot:DisplayObject = SystemManager.getSWFRoot(marshalEvent.dropTarget);
        if (!swfRoot)
            return;    // doesn't belong to this appdomain

        var dragEvent:DragEvent = new DragEvent(marshalEvent.dragEventType, marshalEvent.bubbles, marshalEvent.cancelable);
        dragEvent.localX = marshalEvent.localX;
        dragEvent.localY = marshalEvent.localY;
        dragEvent.action = marshalEvent.action;
        dragEvent.ctrlKey = marshalEvent.ctrlKey;
        dragEvent.altKey = marshalEvent.altKey;
        dragEvent.shiftKey = marshalEvent.shiftKey;
        dragEvent.draggedItem = marshalEvent.draggedItem;
        dragEvent.dragSource = new DragSource();
        var formats:Array = marshalEvent.dragSource.formats;
        var n:int = formats.length;
        for (var i:int = 0; i < n; i++)
        {
            // this will call handlers right away, so deferred clipboard will be costly
            dragEvent.dragSource.addData(marshalEvent.dragSource.dataForFormat(formats[i]), formats[i]);
        }
        if (!marshalEvent.dropTarget.dispatchEvent(dragEvent))
        {
            event.preventDefault();
        }
    }

    /**
     *  Marshal dragManager
     *  
     *  @langversion 3.0
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    private function marshalDragManagerHandler(event:Event):void
    {
        if (event is InterManagerRequest)
            return;

        var marshalEvent:Object = event;
        switch (marshalEvent.name)
        {
        case "isDragging":
            // trace("--marshaled isDragging for DragManagerImpl", sm, marshalEvent.value);
            // bDoingDrag = marshalEvent.value; // not supported in AIR right now, we'd need more info
            break;
        case "acceptDragDrop":
            if (isDragging)
            {
                // trace("NativeDragMgr.acceptDragDrop targ",target);
                var dispObj:InteractiveObject = marshalEvent.value as InteractiveObject;
                if (dispObj)
                    flash.desktop.NativeDragManager.acceptDragDrop(dispObj);
            }
            break;
        case "showFeedback":
            if (isDragging)    // it is our drag
            {
                // trace("--marshaled showFeedback for DragManagerImpl", sm, marshalEvent.value);
                showFeedback(marshalEvent.value);
            }
            break;
        case "getFeedback":
            if (isDragging)    // it is our drag
            {
                marshalEvent.value = getFeedback();
                // trace("--marshaled getFeedback for DragManagerImpl", sm, marshalEvent.value);
            }
            break;
        case "endDrag":
            // trace("--marshaled endDrag for DragManagerImpl", sm, marshalEvent.value);
            endDrag();
            break;
        case "update":
            // if we own the drag, then redispatch to tell the new guy
            if (isDragging)
            {
                // trace("-->marshaled update for DragManagerImpl", sm);
                var me:InterManagerRequest = new InterManagerRequest(InterManagerRequest.DRAG_MANAGER_REQUEST);
                me.name = "isDragging";
                me.value = true;
                // trace("-->dispatched isDragging for DragManagerImpl", sm, true);
                sandboxRoot.dispatchEvent(me);
                // trace("<--dispatched isDragging for DragManagerImpl", sm, true);
                // trace("<--marshaled update for DragManagerImpl", sm);
            }
        }
    }
}

}

////////////////////////////////////////////////////////////////////////////////
//
//  Helper class: DragDataFormatFetcher
//
////////////////////////////////////////////////////////////////////////////////

import flash.desktop.Clipboard;
import mx.core.DragSource;


/**
 *  @private
 *  Helper class used to provide a way to access the clipboard or dragSource data
 *  at a later time. 
 */
class DragDataFormatFetcher
{

    include "../core/Version.as";

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------
    
    /**
     *  Constructor.
     */
    public function DragDataFormatFetcher()
    {
        super();
    }
    
    /**
     *  @private
     */
    public var clipboard:Clipboard;
    
    /**
     *  @private
     */
    public var dragSource:DragSource;
    
    /**
     *  @private
     */
    public var format:String;
    
    /**
     *  @private
     */
    public function getClipboardData():Object
    {
        if (clipboard)
            return clipboard.getData(format);
        else
            return null;
    }
    
    /**
     *  @private
     */
    public function getDragSourceData():Object
    {
        if (dragSource)
            return dragSource.dataForFormat(format);
        else
            return null;
    }
}

