<?xml version="1.0" encoding="UTF-8" ?>
<!--
  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.
  
-->
<library>
    
<class name="baseDrawArrow" extends="baseDrawULine" >
    
    <!-- for drawing drawarrow -->
    <attribute name="currentdrawarrowlinestroke" value="0x000000" />
    <attribute name="currentdrawarrowlinestrokeDis" value="1" type="number" />
    <attribute name="currentdrawarrowlinestrokeFill" value="0xFF6600" />
    <attribute name="currentdrawarrowlinestrokeFillDis" value="1" type="number" />
    
    <attribute name="currentdrawarrowlinelineWidth" value="4" type="number" />   
    <attribute name="currentdrawarrowOpacity" value="1" type="number" />
      
    <!-- ###########################
    drawarrow
     -->
     
    
    <method name="startDrawarrowline" args="oid_name">
        <![CDATA[
	        if (oid_name == null) {
	            oid_name = 'drawarrow'+this.getCounter();
	        }
	        
	        this.currentlayer = new lz.drawViewNew(this,{
		            name:oid_name,width:this.width,height:this.height,
		            opacity:this.currentdrawarrowOpacity});
            
            var pArrowStart = new flash.geom.Point(this.startx,this.starty);
            var pArrowEnd = new flash.geom.Point(this.endx,this.endy);
            
            //if ($debug) Debug.write("start,end,line",pArrowStart,pArrowEnd,this.currentdrawarrowlinelineWidth);
            this.drawArrow(this.currentlayer,pArrowStart,pArrowEnd,this.currentdrawarrowlinelineWidth,
                    this.currentdrawarrowlinestrokeDis,this.currentdrawarrowlinestroke,
                    this.currentdrawarrowlinestrokeFill,this.currentdrawarrowlinestrokeFillDis);
        ]]>
    </method> 
    
    <method name="endDrawarrowline">
        <![CDATA[
            //if ($debug) Debug.write("endDrawarrowline",this.startx,this.starty,this.endx,this.endy);
	        var tempName = this.currentlayer.name;
	        //Debug.write("tempName: ",tempName);
	        this.currentlayer.destroy();
	        
	        //GetBounds of that Object
	        var minx = this.width+2000;
	        var miny = this.height+2000;
	        var maxx = -2;
	        var maxy = -2;
	
	        if (this.startx<minx) minx=this.startx;
	        if (this.endx<minx) minx=this.endx;
	        
	        if (this.startx>maxx) maxx=this.startx;
	        if (this.endx>maxx) maxx=this.endx;
	        
	        if (this.starty<miny) miny=this.starty;
	        if (this.endy<miny) miny=this.endy;
	        
	        if (this.starty>maxy) maxy=this.starty;
	        if (this.endy>maxy) maxy=this.endy;
	        
	        var width = maxx-minx;
	        var height = maxy-miny;
	        
	        //if ($debug) Debug.write("minx,miny,width,height: ",minx,miny,width,height);
            //if ($debug) Debug.write("endDrawarrowline",this.startx,this.starty,this.endx,this.endy);
            	                
	        
            if (minx == this.startx) {
                var x1 = 0;
                var x2 = width;
            } else {
                var x1 = width;
                var x2 = 0;
            }
            if (miny == this.starty) {
                var y1 = 0;
                var y2 = height;
            } else {
                var y1 = height;
                var y2 = 0;
            }
            
            if(this.isSnapToGrid){        	
	        	minx = Math.round(minx/this.gridWidth)*this.gridWidth;
			    miny = Math.round(miny/this.gridWidth)*this.gridWidth;
			    
			    //x1 = Math.round(x1/this.gridWidth)*this.gridWidth;
			    //y1 = Math.round(y1/this.gridWidth)*this.gridWidth;
			    
			    //x2 = Math.round(x2/this.gridWidth)*this.gridWidth;
			    //y2 = Math.round(y2/this.gridWidth)*this.gridWidth;
	        		        	
        	}
			                        
	        this.currentlayer = new lz.drawViewNew(this,{
	            name:tempName,x:minx,y:miny,width:width,height:height,
	            opacity:this.currentdrawarrowOpacity});
	            
	        var pArrowStart = new flash.geom.Point(x1,y1);
            var pArrowEnd = new flash.geom.Point(x2,y2);
            
            //if ($debug) Debug.write("start,end,line",pArrowStart,pArrowEnd,this.currentdrawarrowlinelineWidth);
            this.drawArrow(this.currentlayer,pArrowStart,pArrowEnd,this.currentdrawarrowlinelineWidth,
                    this.currentdrawarrowlinestrokeDis,this.currentdrawarrowlinestroke,
                    this.currentdrawarrowlinestrokeFill,this.currentdrawarrowlinestrokeFillDis);
	            
	        //Add Layer to global Layer     
	        this.layers.push(this.currentlayer);
	        this.drawarrowlineregisterFinal(this.currentlayer.name,
                this.currentdrawarrowlinestroke,this.currentdrawarrowlinelineWidth,
                this.currentdrawarrowlinestrokeFill,this.currentdrawarrowlinestrokeDis,
                this.currentdrawarrowlinestrokeFillDis,this.currentdrawarrowOpacity,
                minx,miny,width,height,
                x1,y1,x2,y2,true,this.getSWFDocumentStatus(),
                this.getZIndex());
	        //Debug.write("t: ",t);
        ]]>
    </method> 
       
    <method name="drawarrowlineregisterFinal" args="newName,stroke,line,fill,strokeDis,fillDis,opacity,x,y,width,height,x1,y1,x2,y2,doCall,swfObj,zIndex">
        var actionObject = new Array();
        actionObject[0] = 'drawarrow';
        actionObject[1] = stroke;
        actionObject[2] = line;
        actionObject[3] = fill;
        actionObject[4] = strokeDis;
        actionObject[5] = fillDis;
        actionObject[6] = opacity;
        actionObject[7] = x1;  
        actionObject[8] = y1;  
        actionObject[9] = x2;    
        actionObject[10] = y2;
        actionObject[11] = zIndex;//-8
        actionObject[12] = swfObj;//-7
        actionObject[13] = this.counter;//-6 
        actionObject[14] = x;//-5
        actionObject[15] = y;//-4
        actionObject[16] = width;//-3
        actionObject[17] = height;//-2
        actionObject[18] = newName;//-1
        this.baseactionobjectList.push(actionObject);       
        if (doCall) this.onsharedMessage('draw',actionObject);
    </method>  
    
    <method name="drawarrowlineactionHistory" args="lastActionObject,parentView">
        <![CDATA[
            //Debug.write("## lineactionHistory",parentView," 2 ## NEW x,y ",lastActionObject[lastActionObject.length-5],lastActionObject[lastActionObject.length-4]," width,height: ",lastActionObject[lastActionObject.length-3],lastActionObject[lastActionObject.length-2]);
            
            var tmpCurrentlayer = new lz.drawViewNew(parentView,{
                name:lastActionObject[lastActionObject.length-1],
                x:lastActionObject[lastActionObject.length-5],
                y:lastActionObject[lastActionObject.length-4],
                width:lastActionObject[lastActionObject.length-3],
                height:lastActionObject[lastActionObject.length-2],
                opacity:lastActionObject[6]});
            
            var pArrowStart = new flash.geom.Point(lastActionObject[7],lastActionObject[8]);
            var pArrowEnd = new flash.geom.Point(lastActionObject[9],lastActionObject[10]);
            
            //if ($debug) Debug.write("start,end,line",pArrowStart,pArrowEnd,this.currentdrawarrowlinelineWidth);
            this.drawArrow(tmpCurrentlayer,pArrowStart,pArrowEnd,lastActionObject[2],
                    lastActionObject[4],lastActionObject[1],
                    lastActionObject[3],lastActionObject[5]);
                
            //Add Layer to global Layer     
            this.layers.push(tmpCurrentlayer);

            this.doSWFDocumentStatus(tmpCurrentlayer,lastActionObject[lastActionObject.length-7]);
        ]]>
    </method>
    
    <method name="drawArrow" args="graphics,start,end,thickness,strokeDis,stroke,fill,fillDis">
        <![CDATA[
    //(graphics:Graphics,
    //            start:Point,end:Point,
    //            style:Object=null):void {
            
            if (start.equals(end)) return;
            
            
            var arrowStyle = {'shaftControlPosition':0.5,
                    'shaftControlSize':0.5,
                    'headLength':thickness*5, //Pixel Length of arrow head
                    'headWidth':thickness*5,//Relative width of arrow head
                    'edgeControlPosition':0.5,
                    'edgeControlSize':0.5,
                    'shaftPosition':0,
                    'shaftThickness':thickness
                    };
            
            var fullVect:Point = end.subtract(start);
            var halfWidth:Number = (arrowStyle.headWidth != -1) ? arrowStyle.headWidth/2 : arrowStyle.headLength/2; 
            
            //Figure out the line start/end points
            var startNorm = new flash.geom.Point(fullVect.y,-fullVect.x);
            startNorm.normalize(arrowStyle.shaftThickness/2);
            var start1 = start.add(startNorm);
            var start2 = start.subtract(startNorm);
            var end1 = end.add(startNorm);
            var end2 = end.subtract(startNorm);
            
            //if ($debug) Debug.write("startNorm: ",startNorm.toString());
            //if ($debug) Debug.write("start1: ",start1.toString());
            //if ($debug) Debug.write("start2: ",start2.toString());
            //if ($debug) Debug.write("end1: ",end1.toString());
            //if ($debug) Debug.write("end2: ",end2.toString());
            
            //figure out where the arrow head starts
            var headPnt = fullVect.clone();
            //if ($debug) Debug.write("headPnt 1: ",headPnt.toString());
            //if ($debug) Debug.write("headPnt.length 1: ",headPnt.length);
            //if ($debug) Debug.write("arrowStyle.headLength 1: ",arrowStyle.headLength);
            headPnt.normalize(headPnt.length-arrowStyle.headLength);
            //if ($debug) Debug.write("headPnt 2: ",headPnt.toString());
            headPnt = headPnt.add(start);
            //if ($debug) Debug.write("headPnt 3: ",headPnt.toString());
            
            //calculate the arrowhead corners
            var headPntNorm = startNorm.clone();
            //if ($debug) Debug.write("headPntNorm ^^: ",headPntNorm.toString());
            //if ($debug) Debug.write("halfWidth ^^: ",halfWidth);
            headPntNorm.normalize(halfWidth);
            //if ($debug) Debug.write("headPntNorm: ",headPntNorm.toString());
            var edge1 = headPnt.add(headPntNorm);
            var edge2 = headPnt.subtract(headPntNorm);
            
            //if ($debug) Debug.write("edge1: ",edge1.toString());
            //if ($debug) Debug.write("edge2: ",edge2.toString());
            
            //Figure out where the arrow connects the the shaft, then calc the intersections
            var shaftCenter = flash.geom.Point.interpolate(end,headPnt,arrowStyle.shaftPosition);
            //if ($debug) Debug.write("end: ",end.toString());
            //if ($debug) Debug.write("headPnt",headPnt.toString());
            //if ($debug) Debug.write("arrowStyle.shaftPosition: ",arrowStyle.shaftPosition);
            //if ($debug) Debug.write("shaftCenter",shaftCenter.toString());
            var inter1 = this.getLineIntersection(start1,end1,shaftCenter,edge1);
            var inter2 = this.getLineIntersection(start2,end2,shaftCenter,edge2);
            
            //if ($debug) Debug.write("inter1: ",inter1.toString());
            //if ($debug) Debug.write("inter2: ",inter2.toString());
            
            //Figure out the control points
            var edgeCenter = flash.geom.Point.interpolate(end,headPnt,arrowStyle.edgeControlPosition);
            var edgeNorm = startNorm.clone();
            edgeNorm.normalize(halfWidth*arrowStyle.edgeControlSize);
            //if ($debug) Debug.write("halfWidth*arrowStyle.edgeControlSize: "+(halfWidth*arrowStyle.edgeControlSize));
            //if ($debug) Debug.write("edgeNorm: "+edgeNorm.toString());
            var edgeCntrl1 = edgeCenter.add(edgeNorm);
            var edgeCntrl2 = edgeCenter.subtract(edgeNorm);

            //if ($debug) Debug.write("edgeCntrl1: ",edgeCntrl1.toString());
            //if ($debug) Debug.write("edgeCntrl2: ",edgeCntrl2.toString());

            //if ($debug) Debug.write("moveTo: ",start1.x,start1.y);
            //if ($debug) Debug.write("lineTo",inter1.x,inter1.y);
            //if ($debug) Debug.write("lineTo",edge1.x,edge1.y);
            //if ($debug) Debug.write("quadraticCurveTo",edgeCntrl1.x,edgeCntrl1.y,end.x,end.y);
            //if ($debug) Debug.write("quadraticCurveTo",edgeCntrl2.x,edgeCntrl2.y,edge2.x,edge2.y);
            //if ($debug) Debug.write("lineTo",inter2.x,inter2.y);
            //if ($debug) Debug.write("lineTo",start2.x,start2.y);
            //if ($debug) Debug.write("lineTo",start1.x,start1.y);
            
            graphics.moveTo(start1.x,start1.y);
            graphics.lineTo(inter1.x,inter1.y);
            graphics.lineTo(edge1.x,edge1.y);
            graphics.quadraticCurveTo(edgeCntrl1.x,edgeCntrl1.y,end.x,end.y);
            graphics.quadraticCurveTo(edgeCntrl2.x,edgeCntrl2.y,edge2.x,edge2.y);
            graphics.lineTo(inter2.x,inter2.y);
            graphics.lineTo(start2.x,start2.y);
            graphics.lineTo(start1.x,start1.y);
            
            if (strokeDis!=-1){
                graphics.strokeStyle = stroke;
                graphics.stroke();
            }

            if (fillDis!=-1){
                graphics.fillStyle = fill;
                graphics.fill();
            }
        ]]>
    </method>
    
    <method name="getLineIntersection" args="a1,a2,b1,b2">
        <![CDATA[ 
        
            //calculate directional constants
            var k1 = (a2.y-a1.y) / (a2.x-a1.x);
            var k2 = (b2.y-b1.y) / (b2.x-b1.x);
            
            // if the directional constants are equal, the lines are parallel,
            // meaning there is no intersection point.
            if( k1 == k2 ) return null;
            
            var x = 0;
            var y = 0;
            var m1 = 0;
            var m2 = 0;
            
            //if ($debug) Debug.write("k1",k1);
            //if ($debug) Debug.write("k2",k2);
            
            // an infinite directional constant means the line is vertical
            if( !isFinite(k1) ) {
                
                //if ($debug) Debug.write("k1 ^^ 0");
                //if ($debug) Debug.write("k2",k2,(b2.y-b1.y));
                //if ($debug) Debug.write("b1.getY(): "+b1.y);
                //if ($debug) Debug.write("b2.getY(): "+b2.y);
                // so the intersection must be at the x coordinate of the line
                x = a1.x;
                m2 = b1.y - k2 * b1.x;
                //if ($debug) Debug.write("m2",m2);
                y = k2 * x + m2;
                //if ($debug) Debug.write("y",y);
                
            // same as above for line 2
            } else if ( !isFinite(k2) ) {
                
                //if ($debug) Debug.write("k2 ^ 0");
                
                m1 = a1.y - k1 * a1.x;
                x = b1.x;
                y = k1 * x + m1;

            // if neither of the lines are vertical
            } else {
                
                //if ($debug) Debug.write("neither");
            
                m1 = a1.y - k1 * a1.x;
                m2 = b1.y - k2 * b1.x;              
                x = (m1-m2) / (k2-k1);
                y = k1 * x + m1;
                
            }
            
            return new flash.geom.Point(x,y);
        ]]>
    </method>    
    
</class>

</library>
