package {
    import caurina.transitions.Tweener;
    import caurina.transitions.properties.CurveModifiers;
    
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.geom.Point;

    [SWF(width="800", height="600", backgroundColor="#ffffff", frameRate="30")]
    public class TweenCurves extends Sprite
    {
        protected var displayPoint1:Sprite;
        protected var displayPoint2:Sprite;
        
        protected var controlPoint:Sprite;
        
        public function TweenCurves()
        {
            displayPoint1 = new Sprite();
            
            addCircleTo(displayPoint1);    
            
            displayPoint1.x    = 100;
            displayPoint1.y = 200;
            
            addChild(displayPoint1);
            
            displayPoint1.addEventListener(MouseEvent.CLICK, drawCurveFrom);
            displayPoint1.mouseChildren = false;
            
            displayPoint2 = new Sprite();
            
            addCircleTo(displayPoint2);    
            
            displayPoint2.x    = 450;
            displayPoint2.y = 200;
            
            addChild(displayPoint2);
            
            displayPoint2.addEventListener(MouseEvent.CLICK, drawCurveFrom);
            displayPoint2.addEventListener(MouseEvent.MOUSE_DOWN, startMovePoint);
            displayPoint2.addEventListener(MouseEvent.MOUSE_UP, stopMovePoint);
            
            displayPoint2.mouseChildren = false;
            
            controlPoint = new Sprite();
            
            addCircleTo(controlPoint,0x0000FF);    
            
            controlPoint.x    = 300;
            controlPoint.y = 100;
            
            addChild(controlPoint);
            
            controlPoint.addEventListener(MouseEvent.MOUSE_DOWN, startMovePoint);
            controlPoint.addEventListener(MouseEvent.MOUSE_UP, stopMovePoint);
            controlPoint.mouseChildren = false;
            
            // Initialize Bezier Curve Modifier
            CurveModifiers.init();
            
        }
        
        protected function startMovePoint(myEvent:MouseEvent):void
        {
            myEvent.target.startDrag();
        }
        
        protected function stopMovePoint(myEvent:MouseEvent):void
        {
            myEvent.target.stopDrag();
        }
        
        protected function addCircleTo(myDisplayObject:Sprite,color:uint = 0xFF0000):void
        {
            var s:Shape = new Shape();
            s.graphics.beginFill(color,1);
            s.graphics.drawRect(0,0,10,10);
            s.graphics.endFill();
            myDisplayObject.addChild(s);
        }
        
        protected function drawCurveFrom(myEvent:MouseEvent):void
        {
            var from:Sprite = myEvent.target as Sprite;
            var toObj:Sprite;
            
            if(from == displayPoint1)
                toObj = displayPoint2;
            else
                toObj = displayPoint1;
                

            var pt:Point = new Point(toObj.x - from.x,toObj.y - from.y);
            
            var line:Shape = new Shape();
            
            line.graphics.moveTo(0,0);
            line.graphics.lineStyle(1,Math.random()*0xFFFFFF);
            
            // Object that will hold x/y position for the line segment as it's tweening
            var lineObj:Object = {};
            lineObj["x"] = 0;
            lineObj["y"] = 0;
            
            // Tween properties
            var tweenObj:Object = {};
            tweenObj["x"] = pt.x;
            tweenObj["y"] = pt.y;
            tweenObj["onUpdate"] = drawPointOnLine;
            tweenObj["onUpdateParams"] = [lineObj,line];
            tweenObj["time"] = 3;
            
            var ctrlPoint:Point = new Point(controlPoint.x,controlPoint.y);
            
            ctrlPoint = from.globalToLocal(ctrlPoint);
            
            tweenObj["_bezier"] = {x:ctrlPoint.x,y:ctrlPoint.y};
            
            Tweener.addTween(lineObj,tweenObj);
            
            addChild(line);
            line.x = from.x;
            line.y = from.y;
            
            
        }
        
        protected function drawPointOnLine(lineObj:Object,line:Shape):void
        {
            line.graphics.lineTo(lineObj.x,lineObj.y);
        }
    }
}