working (though incomplete) 900913;
[potlatch2.git] / net / systemeD / halcyon / Elastic.as
1 package net.systemeD.halcyon {
2
3         import flash.display.*;
4         import flash.geom.Matrix;
5         import flash.geom.Point;
6         import flash.geom.Rectangle;
7         import flash.text.AntiAliasType;
8         import flash.text.GridFitType;
9         import flash.text.TextField;
10         import flash.text.TextFormat;
11         import flash.events.*;
12         import net.systemeD.halcyon.styleparser.*;
13     import net.systemeD.halcyon.connection.*;
14
15         public class Elastic {
16
17                 public var map:Map;                                                     // reference to parent map
18                 public var sprites:Array=new Array();           // instances in display list
19         private var _start:Point;
20         private var _end:Point;
21
22                 public function Elastic(map:Map, start:Point, end:Point) {
23                         this.map = map;
24                         this._start = start;
25                         this._end = end;
26                         redraw();
27                 }
28                 
29                 public function set start(start:Point):void {
30                     this._start = start;
31                     redraw();
32                 }
33
34                 public function set end(end:Point):void {
35                     this._end = end;
36                     redraw();
37                 }
38                 
39                 public function get start():Point {
40                     return _start;
41                 }
42                 
43                 public function get end():Point {
44                     return _end;
45                 }
46                 
47                 public function removeSprites():void {
48                         // Remove all currently existing sprites
49                         while (sprites.length>0) {
50                                 var d:DisplayObject=sprites.pop(); d.parent.removeChild(d);
51                         }
52         }
53         
54                 public function redraw():void {
55                     removeSprites();
56
57                         // Iterate through each sublayer, drawing any styles on that layer
58                         var p0:Point = start;
59                         var p1:Point = end;
60
61                         // Create stroke object
62                         var stroke:Shape = new Shape();
63             stroke.graphics.lineStyle(1, 0xff0000, 1, false, "normal", CapsStyle.ROUND, JointStyle.ROUND);
64                         addToLayer(stroke,3);
65                         dashedLine(stroke.graphics, [2,2]);
66                         
67                         var nodes:Sprite = new Sprite();
68             drawNodes(nodes.graphics);
69             addToLayer(nodes, 3);
70
71                 }
72                 
73                 // ------------------------------------------------------------------------------------------
74                 // Drawing support functions
75
76                 private function drawNodes(g:Graphics):void {
77             g.lineStyle(1, 0xff0000, 1, false, "normal", CapsStyle.ROUND, JointStyle.ROUND);
78                         for (var i:uint = 0; i < 1; i++) {
79                 var p:Point = i == 0 ? start : end;
80                 var x:Number = map.lon2coord(p.x);
81                 var y:Number = map.latp2coord(p.y);
82                 g.moveTo(x-2, y-2);
83                 g.lineTo(x+2, y-2);
84                 g.lineTo(x+2, y+2);
85                 g.lineTo(x-2, y+2);
86                 g.lineTo(x-2, y-2);
87                         }
88                 }
89
90                 // Draw dashed polyline
91                 
92                 private function dashedLine(g:Graphics,dashes:Array):void {
93                         var draw:Boolean=false, dashleft:Number=0, dc:Array=new Array();
94                         var a:Number, xc:Number, yc:Number;
95                         var curx:Number, cury:Number;
96                         var dx:Number, dy:Number, segleft:Number=0;
97                         var i:int=0;
98
99             var p0:Point = start;
100             var p1:Point = end;
101                         g.moveTo(map.lon2coord(p0.x), map.latp2coord(p0.y));
102                         while (i < 1 || segleft>0) {
103                                 if (dashleft<=0) {      // should be ==0
104                                         if (dc.length==0) { dc=dashes.slice(0); }
105                                         dashleft=dc.shift();
106                                         draw=!draw;
107                                 }
108                                 if (segleft<=0) {       // should be ==0
109                                         curx=map.lon2coord(p0.x);
110                     dx=map.lon2coord(p1.x)-curx;
111                                         cury=map.latp2coord(p0.y);
112                     dy=map.latp2coord(p1.y)-cury;
113                                         a=Math.atan2(dy,dx); xc=Math.cos(a); yc=Math.sin(a);
114                                         segleft=Math.sqrt(dx*dx+dy*dy);
115                                         i++;
116                                 }
117
118                                 if (segleft<=dashleft) {
119                                         // the path segment is shorter than the dash
120                                         curx+=dx; cury+=dy;
121                                         moveLine(g,curx,cury,draw);
122                                         dashleft-=segleft; segleft=0;
123                                 } else {
124                                         // the path segment is longer than the dash
125                                         curx+=dashleft*xc; dx-=dashleft*xc;
126                                         cury+=dashleft*yc; dy-=dashleft*yc;
127                                         moveLine(g,curx,cury,draw);
128                                         segleft-=dashleft; dashleft=0;
129                                 }
130                         }
131                 }
132
133                 private function moveLine(g:Graphics,x:Number,y:Number,draw:Boolean):void {
134                         if (draw) { g.lineTo(x,y); }
135                                  else { g.moveTo(x,y); }
136                 }
137
138                 
139                 // Add object (stroke/fill/roadname) to layer sprite
140                 
141                 private function addToLayer(s:DisplayObject,t:uint,sublayer:int=-1):void {
142                         var l:DisplayObject=Map(map).getChildAt(map.WAYSPRITE+5);
143                         var o:DisplayObject=Sprite(l).getChildAt(t);
144                         if (sublayer!=-1) { o=Sprite(o).getChildAt(sublayer); }
145                         Sprite(o).addChild(s);
146                         sprites.push(s);
147             if ( s is Sprite ) {
148                 Sprite(s).mouseEnabled = false;
149                 Sprite(s).mouseChildren = false;
150             }
151                 }
152         }
153 }