package components 
{
    import flash.display.DisplayObject;
    import flash.events.Event;
    
    import mx.containers.Canvas;
    import mx.controls.Image;
    import mx.controls.Button;
    
    public class Connector extends Canvas  {
        
        private var _obj1:mx.controls.Button;
        private var _obj2:mx.controls.Button;
        private var _obj1X:Number;
        private var _obj2X:Number;
        private var _obj1Y:Number;
        private var _obj2Y:Number;
        private var  ARROW_SPACE:Number=8;
        private var _lineColor:uint;
        private var _lineThickness:uint;
        
        
        
        public function Connector(obj1:mx.controls.Button, obj2:mx.controls.Button):void {
            super();
            _obj1 = obj1;
            _obj2 = obj2;
            init();
        }
        
        private function init():void {
            _obj1X = _obj1.x;
            _obj1Y = _obj1.y;
            _obj2X = _obj2.x;
            _obj2Y = _obj2.y;
            _lineColor = 0x1978e3;
            _lineThickness = 2;
            drawConnector();
             //constantly checking to see if either display objects have moved
            _obj1.addEventListener(Event.ENTER_FRAME, checkForMove);
            _obj2.addEventListener(Event.ENTER_FRAME, checkForMove);
        }
        
        private function checkForMove(event:Event):void {
            if((_obj1X!=_obj1.x)||(_obj1Y!=_obj1.y)||(_obj2X!=_obj2.x)||(_obj2Y!=_obj2.y)){
                drawConnector();
                _obj1X = _obj1.x;
                _obj1Y = _obj1.y;
                _obj2X = _obj2.x;
                _obj2Y = _obj2.y;
            }
        }
        
        public function drawConnector():void{
            graphics.clear();
            graphics.lineStyle(_lineThickness, _lineColor, 1);
            
            if(isFullyLeftOf(_obj1, _obj2)){
                if(isFullyAbove(_obj1, _obj2)){
                    bottomToTop();
                }
                else if(isFullyBelow(_obj1, _obj2)){
                    topToBottom();
                }
                else{
                    rightToLeft();
                }
            }
            else if(isFullyRightOf(_obj1, _obj2)){
                if(isFullyAbove(_obj1, _obj2)){
                    bottomToTop();
                }
                else if(isFullyBelow(_obj1, _obj2)){
                    topToBottom();
                }
                else{
                    leftToRight();
                }            
            }
            else if(isFullyAbove(_obj1, _obj2)){
                bottomToTop();
            }
            else if(isFullyBelow(_obj1, _obj2)){
                topToBottom();
            }
            else{
                centerToCenter();
            }
        }
    
        public function reverse():void {
            var temp:mx.controls.Button = _obj1;
            _obj1 = _obj2;
            _obj2 = temp;
        }
        
        public function set lineThickness(value:uint):void {
            _lineThickness = value;
            drawConnector();
        }
        
        public function get lineThickness():uint {
            return _lineThickness;
        }
        
        public function set lineColor(value:uint):void {
            _lineColor = value;
            drawConnector();
            
        }
        
        public function get lineColor():uint {
            return _lineColor;
        }
        
        public function getParent():mx.controls.Button {
            return _obj1;
        }
        
        public function setParent(value:mx.controls.Button):void {
            _obj1 = value;
            drawConnector();
        }
        
        public function getChild():mx.controls.Button {
            return _obj2;
        }
        
        public function setChild(value:mx.controls.Button):void {
            _obj2 = value;
            //drawTriangle();
            drawConnector();
        }
        
        
        
        
        //from the right side of obj1 to the left side of obj2
        private function rightToLeft():void {
                graphics.moveTo(_obj1.x + _obj1.width, _obj1.y + (_obj1.height/2));
            graphics.lineTo((_obj1.x + _obj1.width) + .5*(_obj2.x - (_obj1.x + _obj1.width)), _obj1.y + (_obj1.height/2));
                graphics.lineTo((_obj1.x + _obj1.width) + .5*(_obj2.x - (_obj1.x + _obj1.width)), _obj2.y + (_obj2.height/2));
                graphics.lineTo(_obj2.x, _obj2.y + (_obj2.height/2));  
                var x=_obj1.x + _obj1.width ;
                var y=_obj1.y + (_obj1.height/2);
                graphics.moveTo(x,y);
                graphics.lineTo(x+10,y+10);
                graphics.moveTo(x,y);
                graphics.lineTo(x+10,y-10);
                
        }
        
        //from the left side of obj1 to the right side of obj2
        private function leftToRight():void {
                graphics.moveTo(_obj1.x, _obj1.y + (_obj1.height/2));
                graphics.lineTo((_obj2.x + _obj2.width) + .5*(_obj1.x - (_obj2.x + _obj2.width)), _obj1.y + (_obj1.height/2));
                graphics.lineTo((_obj2.x + _obj2.width) + .5*(_obj1.x - (_obj2.x + _obj2.width)), _obj2.y + (_obj2.height/2));
                graphics.lineTo((_obj2.x + _obj2.width), _obj2.y + _obj2.height/2);
                var x=_obj1.x ;
                var y=_obj1.y + (_obj1.height/2);
                graphics.moveTo(x,y);
                graphics.lineTo(x-10,y+10);
                graphics.moveTo(x,y);
                graphics.lineTo(x-10,y-10);
                
        }
        
        //from the top of obj1 to the bottom of obj2
        private function topToBottom():void {
                graphics.moveTo(_obj1.x + (_obj1.width/2), _obj1.y);
                graphics.lineTo(_obj1.x + (_obj1.width/2), _obj1.y + .5*((_obj2.y + _obj2.height) - _obj1.y));
                graphics.lineTo(_obj2.x+(_obj2.width/2), _obj1.y + .5*((_obj2.y + _obj2.height) - _obj1.y));
                graphics.lineTo(_obj2.x+(_obj2.width/2), (_obj2.y + _obj2.height));
                var x=_obj1.x + (_obj1.width/2);
                var y=_obj1.y;
                graphics.moveTo(x,y);
                graphics.lineTo(x+10,y-10);
                graphics.moveTo(x,y);
                graphics.lineTo(x-10,y-10);
                
                
                
                
            
        }
        
        //from the bottom of obj1 to the top of obj2
        private function bottomToTop():void {
                graphics.moveTo(_obj1.x + (_obj1.width/2), _obj1.y + _obj1.height);
                graphics.lineTo(_obj1.x + (_obj1.width/2), (_obj1.y + _obj1.height) + .5*(_obj2.y - (_obj1.y + _obj1.height)));
                graphics.lineTo(_obj2.x + (_obj2.width/2), (_obj1.y + _obj1.height) + .5*(_obj2.y - (_obj1.y + _obj1.height)));
                graphics.lineTo(_obj2.x + (_obj2.width/2), _obj2.y);
                var x=_obj1.x + (_obj1.width/2) ;
                var y=_obj1.y + _obj1.height;
                graphics.moveTo(x,y);
                graphics.lineTo(x+10,y+10);
                graphics.moveTo(x,y);
                graphics.lineTo(x-10,y+10);
                
        }
        
        //from the center of _obj1 to the center of _obj2
        private function centerToCenter():void {
            graphics.moveTo(_obj1.x + (_obj1.width/2), _obj1.y + (_obj1.height/2));
            graphics.lineTo(_obj2.x + (_obj2.width/2), _obj2.y + (_obj2.height/2));
        }
        
        //checks if obj1 is fully above obj2 (this includes the space for the arrow)
        private function isFullyAbove(obj1:mx.controls.Button, obj2:mx.controls.Button):Boolean {
            return (obj1.y + obj1.height + ARROW_SPACE) < obj2.y;
        }
        
        //checks if obj1 is fully below obj2 (this includes the space for the arrow)
        private function isFullyBelow(obj1:mx.controls.Button, obj2:mx.controls.Button):Boolean {
            return obj1.y > (obj2.y + obj2.height + ARROW_SPACE);
        }
        
        //checks if obj1 is fully to the left of obj2 (this includes the space for the arrow)
        private function isFullyLeftOf(obj1:mx.controls.Button, obj2:mx.controls.Button):Boolean {
            return (obj1.x + obj1.width + ARROW_SPACE) < obj2.x;
        }
        
        //checks if obj1 is fully to the right of obj2 (this includes the space for the arrow)
        private function isFullyRightOf(obj1:mx.controls.Button, obj2:mx.controls.Button):Boolean {
            return obj1.x > (obj2.x + obj2.width + ARROW_SPACE);
        } 
        
        
    }
}