fix POI-adding boog
[potlatch2.git] / net / systemeD / halcyon / connection / Entity.as
1 package net.systemeD.halcyon.connection {
2
3     import flash.events.EventDispatcher;
4     import flash.utils.Dictionary;
5     
6     import net.systemeD.halcyon.connection.actions.*;
7
8     public class Entity extends EventDispatcher {
9         private var _id:Number;
10         private var _version:uint;
11         private var tags:Object = {};
12         private var modified:Boolean = false;
13                 private var _loaded:Boolean = true;
14                 private var parents:Dictionary = new Dictionary();
15                 private var locked:Boolean = false;
16                 public var deleted:Boolean = false;
17
18         public function Entity(id:Number, version:uint, tags:Object, loaded:Boolean) {
19             this._id = id;
20             this._version = version;
21             this.tags = tags;
22                         this._loaded = loaded;
23             modified = id < 0;
24         }
25
26         public function get id():Number {
27             return _id;
28         }
29
30         public function get version():uint {
31             return _version;
32         }
33
34         public function get loaded():Boolean {
35             return _loaded;
36         }
37
38                 public function updateEntityProperties(version:uint, tags:Object, loaded:Boolean):void {
39                         _version=version; this.tags=tags; _loaded=loaded;
40                 }
41
42                 // Tag-handling methods
43
44         public function hasTags():Boolean {
45             for (var key:String in tags)
46                 return true;
47             return false;
48         }
49
50                 // ** we could do with hasInterestingTags - don't bother with source, created_by, any TIGER tags, etc.
51
52         public function getTag(key:String):String {
53             return tags[key];
54         }
55         
56         public function setTag(key:String, value:String, performAction:Function):void {
57             performAction(new SetTagAction(this, key, value));
58         }
59
60         public function renameTag(oldKey:String, newKey:String, performAction:Function):void {
61             performAction(new SetTagKeyAction(this, oldKey, newKey));
62         }
63
64         public function getTagList():TagList {
65             return new TagList(tags);
66         }
67
68         public function getTagsCopy():Object {
69             var copy:Object = {};
70             for (var key:String in tags )
71                 copy[key] = tags[key];
72             return copy;
73         }
74
75                 public function getTagsHash():Object {
76                         // hm, not sure we should be doing this, but for read-only purposes
77                         // it's faster than using getTagsCopy
78                         return tags;
79                 }
80
81         public function getTagArray():Array {
82             var copy:Array = [];
83             for (var key:String in tags )
84                 copy.push(new Tag(this, key, tags[key]));
85             return copy;
86         }
87
88                 // Clean/dirty methods
89
90         public function get isDirty():Boolean {
91             return modified;
92         }
93
94         public function markClean(newID:Number, newVersion:uint):void {
95             this._id = newID;
96             this._version = newVersion;
97             modified = false;
98         }
99
100         internal function markDirty():void {
101             modified = true;
102         }
103
104                 // Delete entity
105                 
106                 public function remove(performAction:Function):void {
107                         // to be overridden
108                 }
109                 
110                 public function isDeleted():Boolean {
111                     return deleted;
112                 }
113                 
114                 public function setDeletedState(isDeleted:Boolean):void {
115                     deleted = isDeleted;
116                 }
117                 
118                 internal function isEmpty():Boolean {
119                         return false;   // to be overridden
120                 }
121                 
122                 public function within(left:Number,right:Number,top:Number,bottom:Number):Boolean {
123                         return true;    // to be overridden
124                 }
125
126                 public function removeFromParents(performAction:Function):void {
127                         for (var o:Object in parents) {
128                                 if (o is Relation) { Relation(o).removeMember(this, performAction); }
129                                 else if (o is Way) { Way(o).removeNode(Node(this), performAction); }
130                                 if (o.isEmpty()) { o.remove(performAction); }
131                         }
132                 }
133
134                 // Parent handling
135                 
136                 public function addParent(parent:Entity):void {
137                         parents[parent]=true;
138                         
139                         if ( parent is Relation )
140                             dispatchEvent(new RelationMemberEvent(Connection.ADDED_TO_RELATION, this, parent as Relation, -1));
141                 }
142
143                 public function removeParent(parent:Entity):void {
144                         delete parents[parent];
145
146                         if ( parent is Relation )
147                             dispatchEvent(new RelationMemberEvent(Connection.REMOVED_FROM_RELATION, this, parent as Relation, -1));
148                 }
149                 
150                 public function get parentWays():Array {
151                         var a:Array=[];
152                         for (var o:Object in parents) {
153                                 if (o is Way) { a.push(o); }
154                         }
155                         return a;
156                 }
157
158                 public function get hasParents():Boolean {
159                         for (var o:Object in parents) { return true; }
160                         return false;
161                 }
162                 
163                 public function get hasParentWays():Boolean {
164                         for (var o:Object in parents) {
165                                 if (o is Way) { return true; }
166                         }
167                         return false;
168                 }
169                 
170                 public function get numParentWays():uint {
171                         var i:uint=0;
172                         for (var o:Object in parents) {
173                                 if (o is Way) { i++; }
174                         }
175                         return i;
176                 }
177                 
178                 public function get parentRelations():Array {
179                         var a:Array=[];
180                         for (var o:Object in parents) {
181                                 if (o is Relation) { a.push(o); }
182                         }
183                         return a;
184                 }
185                 
186                 public function get parentObjects():Array {
187                         var a:Array=[];
188                         for (var o:Object in parents) { a.push(o); }
189                         return a;
190                 }
191                 
192                 public function hasParent(entity:Entity):Boolean {
193             return parents[entity] == true;
194         }
195
196                 public function get memberships():Array {
197                         var list:Array=[];
198                         for (var o:Object in parents) {
199                                 if (o is Relation) {
200                                         for (var i:uint=0; i<o.length; i++) {
201                                                 if (o.getMember(i).entity==this) {
202                                                         list.push( { relation:o, position:i, role: o.getMember(i).role } );
203                                                 }
204                                         }
205                                 }
206                         }
207             // it's useful to return in a sorted order, even if the relations are interleaved
208             // e.g. [{r0 p1},{r1 p1},{r0 p4}]
209                         return list.sortOn("position"); 
210                 }
211
212                 // Resume/suspend redraw
213                 
214                 public function suspend():void {
215                         dispatchEvent(new EntityEvent(Connection.SUSPEND_REDRAW, this));
216                 }
217                 
218                 public function resume():void {
219                         dispatchEvent(new EntityEvent(Connection.RESUME_REDRAW, this));
220                 }
221
222                 // To be overridden
223
224         public function getType():String {
225             return '';
226         }
227
228     }
229
230 }
231