<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:comp="components.*"
    xmlns:degrafa="com.degrafa.*"
    xmlns:paint="com.degrafa.paint.*"
    xmlns:geom="com.degrafa.geometry.*"
    xmlns:splines="com.degrafa.geometry.splines.*"
    layout="absolute"
    width="600" height="500" 
    pageTitle="Catmull-Rom Spline"
    applicationComplete="test()" viewSourceURL="srcview/index.html">
    
  <mx:Style source="assets/style/style.css"/>
  <mx:Canvas id="background" x="50" y="90" width="500" height="320" backgroundColor="#FFFFFF" />
  <mx:Label text="Catmull-Rom Spline" x="250" y="30" width="300" styleName="title"/>
  <mx:TextArea x="50" y="417" width="500" id="__explanation__" height="35" fontSize="12" color="#000000" wordWrap="true" editable="false" enabled="true" borderStyle="none">
       <mx:text><![CDATA[Click to define at least three points.  Degrafa spline is drawn segment by segment in red.  Click the space bar to draw the spline (in blue) point-to-point using only the utility class.]]></mx:text>
        </mx:TextArea>
     
  <paint:SolidFill id="blue" color="#62ABCD" alpha=".6"/>
  <paint:SolidStroke id="redstroke" weight="2" color="#FF0000"/>
     
     <mx:Canvas id="knotLayer" />
     <mx:Canvas id="splineLayer" />
     <mx:Canvas id="splineLayer1" />
     <mx:Canvas id="knotOverlay" />
     
     <splines:CatmullRomSpline id="crspline" graphicsTarget="{[splineLayer1]}" stroke="{redstroke}" />
  <comp:CrossHair id="marker" width="20" height="20"/>
  
  <mx:Script>
    <![CDATA[
      import flash.events.MouseEvent;
      import com.degrafa.utilities.math.CatmullRom;
        
      private static const RAD_TO_DEG:Number = 180/Math.PI;
      
      private var __count:uint        = 0;                 // count the number of knots
      private var __spline:CatmullRom = new CatmullRom();  // uniform-parameterized C-R spline
      
      private function test():void
      { 
        activateCrossHair()
      }
        
      // activate the crosshair
      private function activateCrossHair():void
      {
        marker.visible = true;
        marker.x       = stage.mouseX;
        marker.y       = stage.mouseY;
           
        stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
        stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
        stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
      }
        
      // deactivate crosshair
      private function deactivateCrosshair():void
      {
        marker.visible = false;
          
        stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
        stage.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
      }
     
      // listen for any keypress
      private function onKeyDown(_e:KeyboardEvent):void
      {
        deactivateCrosshair();
        stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
        
        // one plot is old-school point-to-point, the other done entirely by Degrafa, but both keyed off the *exact* same utility function
        var g:Graphics = splineLayer.graphics;
        g.clear();
        g.lineStyle(2,0x0000ff);
        
        var myX:Number = __spline.getX(0);
        var myY:Number = __spline.getY(0);
        g.moveTo(myX, myY);
        
        var delta:Number = 0.02;  // this may not be enough granularity for curves with very long arc length
        for( var t:Number=delta; t<1.0; t+=delta )
        {
          myX = __spline.getX(t);
          myY = __spline.getY(t);
          g.lineTo(myX, myY);
        }
        
        myX = __spline.getX(1.0);
        myY = __spline.getY(1.0);
        g.lineTo(myX,myY);
      }
        
      private function onMouseMove(_e:MouseEvent):void
      {
        marker.x = stage.mouseX;
        marker.y = stage.mouseY;
      }
        
      private function onMouseDown(_e:MouseEvent):void
      {
        var pX:Number = stage.mouseX;
        var pY:Number = stage.mouseY;
       
        addPoint(pX, pY);
      }
      
      private function addPoint(pX:Number, pY:Number):void
      { 
        crspline.addControlPoint(pX, pY);
        
        var g:Graphics = knotLayer.graphics;
        g.lineStyle(1, 0x000000);
        if( __count == 0 )
        {
          g.moveTo(pX,pY);
        }
        else
        {
          g.lineTo(pX,pY);
        }
       
        g = knotOverlay.graphics;
           g.lineStyle(1,0x000000);
           g.beginFill(0x00ff00);
           g.drawCircle(pX, pY, 4);
           g.endFill();
           
        __count++;
        __spline.addControlPoint(pX, pY);
      }
        
     ]]>
   </mx:Script>
    
</mx:Application>