package flare.vis.controls
{
    import flare.vis.events.SelectionEvent;
    
    import flash.display.DisplayObject;
    import flash.display.DisplayObjectContainer;
    import flash.display.Graphics;
    import flash.display.InteractiveObject;
    import flash.display.Shape;
    import flash.display.Stage;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Rectangle;
    import flash.utils.Dictionary;

    [Event("select",   type="flare.vis.events.SelectionEvent")]
    [Event("deselect", type="flare.vis.events.SelectionEvent")]
    
    /**
     * Interactive control for selecting a group of objects by "rubber-banding"
     * them with a rectangular section region.
     */
    public class SelectionControl extends Control
    {
        private var _r:Rectangle = new Rectangle();
        private var _drag:Boolean = false;
        private var _shape:Shape = new Shape();
        private var _hit:InteractiveObject;
        private var _stage:Stage;
        private var _sel:Dictionary = new Dictionary();
        
        private var _add0:DisplayObject = null;
        private var _rem0:DisplayObject = null;
        private var _add:Array = null;
        private var _rem:Array = null;
        
        /** The active hit area over which selection
         *  interactions can be performed. */
        public function get hitArea():InteractiveObject { return _hit; }
        public function set hitArea(hitArea:InteractiveObject):void {
            if (_hit != null) onRemove();
            _hit = hitArea;
            if (_object && _object.stage != null) onAdd();
        }
        
        /** Indicates if a selection events should be fired immediately upon a
         *  chane of selection status (true) or after the mouse is released
         * (false). The default is true. Set this to false if immediate
         * selections are causing any performance issues. */
        public var fireImmediately:Boolean = true;
        
        /** Line color of the selection region border. */
        public var lineColor:uint = 0x8888FF;
        /** Line alpha of the selection region border. */
        public var lineAlpha:Number = 0.4;
        /** Line width of the selection region border. */
        public var lineWidth:Number = 2;
        /** Fill color of the selection region. */
        public var fillColor:uint = 0x8888FF;
        /** Fill alpha of the selection region. */
        public var fillAlpha:Number = 0.2;
        
        // --------------------------------------------------------------------
        
        /**
         * Creates a new SelectionControl.
         * @param filter an optional Boolean-valued filter determining which
         *  items are eligible for selection.
         * @param hitArea a display object to use as the hit area for mouse
         *  events. For example, this could be a background region over which
         *  the selection can done. If this argument is null,
         *  the stage will be used.
         * @param select an optional SelectionEvent listener for selections
         * @param deselect an optional SelectionEvent listener for deselections
         */
        public function SelectionControl(filter:*=n