Load map features images into cache rather than have Image components load them each...
[potlatch2.git] / net / systemeD / potlatch2 / mapfeatures / Feature.as
1 package net.systemeD.potlatch2.mapfeatures {
2
3     import flash.events.EventDispatcher;
4     import flash.events.Event;
5     import flash.net.*;
6     import flash.utils.ByteArray;
7     
8     import net.systemeD.halcyon.connection.Entity;
9     import net.systemeD.potlatch2.utils.CachedDataLoader;
10
11         public class Feature extends EventDispatcher {
12         private var mapFeatures:MapFeatures;
13         private var _xml:XML;
14         private static var variablesPattern:RegExp = /[$][{]([^}]+)[}]/g;
15         private var _tags:Array;
16         private var _editors:Array;
17
18         public function Feature(mapFeatures:MapFeatures, _xml:XML) {
19             this.mapFeatures = mapFeatures;
20             this._xml = _xml;
21             parseTags();
22             parseEditors();
23         }
24         
25         private function parseTags():void {
26             _tags = new Array();
27             
28             for each(var tag:XML in definition.tag) {
29                 var tagObj:Object = new Object();
30                 tagObj["k"] = tag.@k;
31                 tagObj["v"] = tag.@v;
32                 _tags.push(tagObj);
33             }
34         }
35         
36         private function parseEditors():void {
37             _editors = new Array();
38             
39             addEditors(definition);
40             
41             _editors.sortOn(["sortOrder", "name"], [Array.DESCENDING | Array.NUMERIC, Array.CASEINSENSITIVE]);
42         }
43         
44         private function addEditors(xml:XML):void {
45             var inputXML:XML;
46             
47             for each(var inputSetRef:XML in xml.inputSet) {
48                 var setName:String = String(inputSetRef.@ref);
49                 for each (inputXML in mapFeatures.definition.inputSet.(@id==setName)) {
50                     addEditors(inputXML);
51                 }
52             }
53             
54             for each(inputXML in xml.input) {
55                 addEditor(inputXML);
56             }
57         }
58         
59         private function addEditor(inputXML:XML):void {
60             var inputType:String = inputXML.@type;
61             var presenceStr:String = inputXML.@presence;
62             var sortOrderStr:String = inputXML.@priority;
63             var editor:EditorFactory = EditorFactory.createFactory(inputType, inputXML);
64             if ( editor != null ) {
65                 editor.presence = Presence.getPresence(presenceStr);
66                 editor.sortOrder = EditorFactory.getPriority(sortOrderStr);
67                 _editors.push(editor);
68             }
69         }
70         
71         public function get editors():Array {
72             return _editors;
73         }
74         
75         public function get definition():XML {
76             return _xml;
77         }
78     
79         [Bindable(event="nameChanged")]
80         public function get name():String {
81             return _xml.@name;
82         }
83     
84         [Bindable(event="imageChanged")]
85         public function get image():ByteArray {
86             var icon:XMLList = _xml.icon;
87             var imageURL:String = null;
88
89             if ( icon.length() > 0 && icon[0].hasOwnProperty("@image") )
90                 imageURL = icon[0].@image;
91             
92             if ( imageURL != null ) {
93                 return CachedDataLoader.loadData(imageURL, imageLoaded);
94             }
95             return null;
96         }
97         
98         private function imageLoaded(url:String, data:ByteArray):void {
99             dispatchEvent(new Event("imageChanged"));
100         }
101         
102         public function htmlDetails(entity:Entity):String {
103             var icon:XMLList = _xml.icon;
104             return makeHTMLIcon(icon, entity);
105         }   
106
107         public static function makeHTMLIcon(icon:XMLList, entity:Entity):String {
108             if ( icon == null )
109                 return "";
110             
111             var txt:String = icon.children().toXMLString();
112             var replaceTag:Function = function():String {
113                 var value:String = entity.getTag(arguments[1]);
114                 return value == null ? "" : htmlEscape(value);
115             };
116             txt = txt.replace(variablesPattern, replaceTag);
117             return txt;
118         }
119         
120         public static function htmlEscape(str:String):String {
121             var newStr:String = str.replace(/&/g, "&");
122             newStr = newStr.replace(/</g, "&lt;");
123             newStr = newStr.replace(/>/g, "&gt;");
124             newStr = newStr.replace(/"/g, "&quot;");
125             newStr = newStr.replace(/'/g, "&apos;");
126             return newStr;
127         }
128       
129
130         public function isInCategory(category:String):Boolean {
131             var cats:XMLList = _xml.category;
132             if ( cats.length() == 0 )
133                 return false;
134                 
135             for each( var cat:XML in cats )
136                 if ( cat.text()[0] == category )
137                     return true;
138             return false;
139         }
140         
141         public function get tags():Array {
142             return _tags;
143         }
144         
145         public function findFirstCategory():Category {
146             for each( var cat:Category in mapFeatures.categories ) {
147                 if ( isInCategory(cat.id) )
148                     return cat;
149             }
150             return null;
151         }
152         
153         public function isType(type:String):Boolean {
154             return _xml.elements(type).length() > 0;
155         }
156         
157         public function hasHelpURL():Boolean {
158             return _xml.help.length() > 0;
159         }
160         
161         public function get helpURL():String {
162             return _xml.help;
163         }
164     }
165 }
166