e67d2901e09c2ad9a177011936f0146b29e4907f
[potlatch2.git] / net / systemeD / halcyon / MapPaint.as
1 package net.systemeD.halcyon {
2
3         import flash.display.Sprite;
4         import flash.display.DisplayObject;
5         import net.systemeD.halcyon.NodeUI;
6         import net.systemeD.halcyon.WayUI;
7         import net.systemeD.halcyon.connection.Node;
8         import net.systemeD.halcyon.connection.Way;
9         import net.systemeD.halcyon.styleparser.RuleSet;
10         import net.systemeD.halcyon.vectorlayers.VectorLayer;
11         import net.systemeD.halcyon.Globals;
12
13     public class MapPaint extends Sprite {
14
15                 public var map:Map;
16                 public var minlayer:int;
17                 public var maxlayer:int;
18                 public var ruleset:RuleSet;                                             // rules
19                 public var wayuis:Object=new Object();                  // sprites for ways and (POI/tagged) nodes
20                 public var nodeuis:Object=new Object();                 //  |
21                 public var isBackground:Boolean = true;                 // is it a background layer or the core paint object?
22                 private var sublayerIndex:Object={};                    // hash of index->position
23
24                 private const VERYBIG:Number=Math.pow(2,16);
25
26                 // Set up layering
27                 // [layer][3]                   - names
28                 // [layer][2][sublayer] - stroke
29                 // [layer][1]                   - casing
30                 // [layer][0]                   - fill
31
32                 public function MapPaint(map:Map,minlayer:int,maxlayer:int) {
33                         this.map=map;
34                         this.minlayer=minlayer;
35                         this.maxlayer=maxlayer;
36                         sublayerIndex[1]=0;
37
38                         for (var l:int=minlayer; l<=maxlayer; l++) {    // each layer (10 is +5, 0 is -5)
39                                 var s:Sprite = getHitSprite();                  //  |
40                                 s.addChild(getPaintSprite());                           //      | 0 fill
41                                 s.addChild(getPaintSprite());                           //      | 1 casing
42                                 var t:Sprite = getPaintSprite();                        //  | 2 stroke
43                                 t.addChild(getPaintSprite());                           //  |  | sublayer
44                                 s.addChild(t);                                                          //  |  |
45                                 s.addChild(getPaintSprite());                           //      | 3 names
46                                 s.addChild(getPaintSprite());                           //      | 4 nodes
47                                 s.addChild(getHitSprite());                                 //  | 5 entity hit tests
48                                 addChild(s);                                                            //  |
49                         }
50                         addChild(getPaintSprite());                                     // name sprite
51                 }
52                 
53                 public function get ready():Boolean {
54                         if (!ruleset) { return false; }
55                         if (!ruleset.loaded) { return false; }
56                         return true;
57                 }
58
59                 public function sublayer(layer:int,sublayer:Number):Sprite {
60                         var l:DisplayObject;
61                         var o:DisplayObject;
62                         var index:String, ix:Number;
63                         if (!sublayerIndex[sublayer]) {
64                                 // work out which position to add at
65                                 var lowestAbove:Number=VERYBIG;
66                                 var lowestAbovePos:int=-1;
67                                 var indexLength:uint=0;
68                                 for (index in sublayerIndex) {
69                                         ix=Number(index);
70                                         if (ix>sublayer && ix<lowestAbove) {
71                                                 lowestAbove=ix;
72                                                 lowestAbovePos=sublayerIndex[index];
73                                         }
74                                         indexLength++;
75                                 }
76                                 if (lowestAbovePos==-1) { lowestAbovePos=indexLength; }
77                         
78                                 // add sprites
79                                 for (var i:int=minlayer; i<=maxlayer; i++) {
80                                         l=getChildAt(i-minlayer);
81                                         o=(l as Sprite).getChildAt(2);
82                                         (o as Sprite).addChildAt(getPaintSprite(),lowestAbovePos);
83                                 }
84                         
85                                 // update index
86                                 for (index in sublayerIndex) {
87                                         ix=Number(index);
88                                         if (ix>sublayer) { sublayerIndex[index]++; }
89                                 }
90                                 sublayerIndex[sublayer]=lowestAbovePos;
91                         }
92
93                         l=getChildAt(layer-minlayer);
94                         o=(l as Sprite).getChildAt(2);
95                         return ((o as Sprite).getChildAt(sublayerIndex[sublayer]) as Sprite);
96                 }
97
98                 public function updateEntityUIs(o:Object, redraw:Boolean, remove:Boolean):void {
99                         var way:Way, node:Node;
100
101                         for each (way in o.waysInside) {
102                                 if (!wayuis[way.id]) { createWayUI(way); }
103                                 else if (redraw) { wayuis[way.id].recalculate(); wayuis[way.id].redraw(); }
104                         }
105                         if (remove) {
106                                 for each (way in o.waysOutside) { deleteWayUI(way); }
107                         }
108
109                         for each (node in o.poisInside) {
110                                 if (!nodeuis[node.id]) { createNodeUI(node); }
111                                 else if (redraw) { nodeuis[node.id].redraw(); }
112                         }
113                         if (remove) {
114                                 for each (node in o.poisOutside) { deleteNodeUI(node); }
115                         }
116                 }
117
118                 public function createWayUI(way:Way):WayUI {
119                         if (!wayuis[way.id]) { wayuis[way.id]=new WayUI(way,this,false); }
120                         return wayuis[way.id];
121                 }
122
123                 public function createNodeUI(node:Node):NodeUI {
124                         if (!nodeuis[node.id]) { nodeuis[node.id]=new NodeUI(node,this,0,false); }
125                         return nodeuis[node.id];
126                 }
127
128                 public function deleteWayUI(way:Way):void {
129                         if (!wayuis[way.id]) { return; }
130                         wayuis[way.id].removeSprites();
131                         delete wayuis[way.id];
132                 }
133
134                 public function deleteNodeUI(node:Node):void {
135                         if (!nodeuis[node.id]) { return; }
136                         nodeuis[node.id].removeSprites();
137                         delete nodeuis[node.id];
138                 }
139                 
140                 public function renumberWayUI(way:Way,oldID:Number):void {
141                         if (!wayuis[oldID]) { return; }
142                         wayuis[way.id]=wayuis[oldID];
143                         delete wayuis[oldID];
144                 }
145
146                 public function renumberNodeUI(node:Node,oldID:Number):void {
147                         if (!nodeuis[oldID]) { return; }
148                         nodeuis[node.id]=nodeuis[oldID];
149                         delete nodeuis[oldID];
150                 }
151
152         private function getPaintSprite():Sprite {
153             var s:Sprite = new Sprite();
154             s.mouseEnabled = false;
155             s.mouseChildren = false;
156             return s;
157         }
158
159         private function getHitSprite():Sprite {
160             var s:Sprite = new Sprite();
161             return s;
162         }
163
164                 public function redraw():void {
165                         for each (var w:WayUI in wayuis) { w.recalculate(); w.redraw(); }
166                         for each (var p:NodeUI in nodeuis) { p.redraw(); }
167                 }
168
169                 public function redrawPOIs():void {
170                         for each (var p:NodeUI in nodeuis) { p.redraw(); }
171                 }
172                 
173                 public function findSource():VectorLayer {
174                         var v:VectorLayer;
175                         for each (v in map.vectorlayers) {
176                                 if (v.paint==this) { return v; }
177                         }
178                         return null;
179                 }
180         }
181 }