Draw multiple strokes, label POIs, and much much more fun.
[potlatch2.git] / net / systemeD / halcyon / styleparser / RuleSet.as
1 package net.systemeD.halcyon.styleparser {
2
3         import org.as3yaml.*;
4         import flash.events.*;
5         import flash.net.*;
6         import net.systemeD.halcyon.Globals;
7
8         public class RuleSet {
9
10                 public var rules:Array=new Array();             // list of rules
11                 public var images:Object=new Object();  // loaded images
12                 private var iconCallback:Function=null; // function to call when all icons loaded
13                 private var iconsToLoad:uint=0;                 // number of icons left to load (fire callback when ==0)
14
15                 // variables for name, author etc.
16
17                 public function RuleSet(f:Function=null):void {
18                         iconCallback=f;
19                 }
20
21                 // returns array of styles
22                 public function getStyles(isPoint:Boolean,tags:Object,scale:uint):Array {
23                         var rt:Object=tags; var rtused:Boolean=false;                   // new tag object to be returned
24                         var i:String;
25                         var styles:Array=[];
26                         for each (var rule:* in rules) {
27                                 if ( isPoint && rule is ShapeRule) { continue; }
28                                 if (!isPoint && rule is PointRule) { continue; }
29                                 if (scale>rule.minScale) { continue; }
30                                 if (scale<rule.maxScale) { continue; }
31                                 if (rule.test(rt)) {
32                                         if (rule is ShapeRule && rule.shapeStyle)  { styles.push(rule.shapeStyle); }
33                                         if (rule is PointRule && rule.pointStyle)  { styles.push(rule.pointStyle); }
34                                         if (                     rule.textStyle )  { styles.push(rule.textStyle); }
35                                         if (rule is ShapeRule && rule.shieldStyle) { styles.push(rule.shieldStyle); }
36                                         if (rule.breaker) { break; }
37                                         if (rule.hasTags) {
38                                                 // deep copy tag object so we're not modifying in situ
39                                                 if (!rtused) { for (i in tags) { rt[i]=tags[i]; }; rtused=true; }
40                                                 // and apply new tags
41                                                 for (i in rule.setTags) { rt[i]=rule.setTags[i]; }
42                                         }
43                                 }
44                         }
45                         return styles;
46                 }
47
48                 // Save and load rulesets
49
50                 public function save(url:String,name:String):void {
51
52                         var request:URLRequest=new URLRequest(url);
53                         var requestVars:URLVariables=new URLVariables();
54                         var loader:URLLoader=new URLLoader();
55                         
56                         // send to server
57                         requestVars['name']=name;
58                         requestVars['data']=YAML.encode(rules);
59                         request.data=requestVars;
60                         request.method = URLRequestMethod.POST;  
61                         loader.dataFormat = URLLoaderDataFormat.TEXT;
62                         loader.addEventListener(Event.COMPLETE,                                         savedRuleSet,                   false, 0, true);
63                         loader.addEventListener(HTTPStatusEvent.HTTP_STATUS,            httpStatusHandler,              false, 0, true);
64                         loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,      securityErrorHandler,   false, 0, true);
65                         loader.addEventListener(IOErrorEvent.IO_ERROR,                          ioErrorHandler,                 false, 0, true);
66                         loader.load(request);
67                 }
68
69                 public function load(url:String):void {
70
71                         var request:URLRequest=new URLRequest(url);
72                         var loader:URLLoader=new URLLoader();
73
74                         request.method=URLRequestMethod.GET;
75                         loader.dataFormat = URLLoaderDataFormat.TEXT;
76                         loader.addEventListener(Event.COMPLETE,                                         loadedRuleSet,                  false, 0, true);
77                         loader.addEventListener(HTTPStatusEvent.HTTP_STATUS,            httpStatusHandler,              false, 0, true);
78                         loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,      securityErrorHandler,   false, 0, true);
79                         loader.addEventListener(IOErrorEvent.IO_ERROR,                          ioErrorHandler,                 false, 0, true);
80                         loader.load(request);
81                 }
82
83                 // data handlers
84                 private function savedRuleSet(event:Event):void {
85                         var loader:URLLoader = URLLoader(event.target);  
86                         // do something with loader.data
87                 }
88                 
89                 private function loadedRuleSet(event:Event):void {
90                         var loader:URLLoader = URLLoader(event.target);  
91                         rules=YAML.decode(event.target.data) as Array;
92                         // ** fire some event or other to tell map to redraw
93                         loadImages();
94                 }
95
96                 private function httpStatusHandler( event:HTTPStatusEvent ):void { }
97                 private function securityErrorHandler( event:SecurityErrorEvent ):void { }
98                 private function ioErrorHandler( event:IOErrorEvent ):void { }
99                 
100                 // serialise/deserialise methods
101
102
103                 // ------------------------------------------------------------------------------------------------
104                 // Load all referenced images
105                 // ** currently only looks in PointRules
106                 // ** will duplicate if referenced twice, shouldn't
107                 
108                 public function loadImages():void {
109                         var ps:PointStyle;
110
111                         for each (var rule:* in rules) {
112                                 if (!(rule is PointRule)) { continue; }
113                                 if (!(rule.pointStyle)) { continue; }
114                                 if (!(rule.pointStyle.icon)) { continue; }
115                                 
116                                 iconsToLoad++;
117                                 var request:URLRequest=new URLRequest(rule.pointStyle.icon);
118                                 var loader:ImageLoader=new ImageLoader();
119                                 loader.dataFormat=URLLoaderDataFormat.BINARY;
120                                 loader.filename=rule.pointStyle.icon;
121                                 loader.addEventListener(Event.COMPLETE,                                         loadedImage,                    false, 0, true);
122                                 loader.addEventListener(HTTPStatusEvent.HTTP_STATUS,            httpStatusHandler,              false, 0, true);
123                                 loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,      securityErrorHandler,   false, 0, true);
124                                 loader.addEventListener(IOErrorEvent.IO_ERROR,                          ioErrorHandler,                 false, 0, true);
125                                 loader.load(request);
126                         }
127                 }
128
129                 // data handler
130
131                 private function loadedImage(event:Event):void {
132                         images[event.target.filename]=event.target.data;
133                         iconsToLoad--;
134                         if (iconsToLoad==0 && iconCallback!=null) { iconCallback(); }
135                 }
136         }
137 }