source: subversion/applications/editors/potlatch/potlatch.as @ 14716

Last change on this file since 14716 was 14716, checked in by richard, 10 years ago

fix another way-node/Way-Node problem in amf_controller; add WinIE JS compatibility via ExternalInterface? (we can use this later to alert for a commit message if none is provided)

File size: 41.0 KB
Line 
1
2        System.security.loadPolicyFile("http://www.openstreetmap.org/api/crossdomain.xml");
3
4        // =====================================================================================
5        // Initialise
6
7        // Resizable window, disable right-click
8        Stage.showMenu = false;
9        Stage.align="TL";
10        Stage.scaleMode="noScale";
11        resizeListener=new Object();
12        resizeListener.onResize=function() { resizeWindow(); };
13        Stage.addListener(resizeListener);
14        var panelheight=110;
15       
16        // Master movieclip for map
17        _root.createEmptyMovieClip("map",10);
18        _root.map.setMask(_root.masksquare);
19
20        // Master movieclip for panel
21        _root.createEmptyMovieClip("panel",15);
22        _root.panel._x=0; _root.panel._y=500;
23        _root.panel.beginFill(0xF3F3F3,100);
24        _root.panel.moveTo(0,0); _root.panel.lineTo(3000,0);
25        _root.panel.lineTo(3000,panelheight); _root.panel.lineTo(0,panelheight);
26        _root.panel.lineTo(0,0);
27        _root.panel.endFill();
28        _root.panel.createEmptyMovieClip("advice",0xFFFFFC);
29
30        _root.createEmptyMovieClip("windows",0xFFFFFD);
31        var windowdepth=1;
32        var windowsopen=0;
33
34        // Sound
35        beep=new Sound();
36        beep.loadSound("/potlatch/beep.mp3",false);
37
38        // Co-ordinates
39        // London 51.5,0; Weybridge 51.4,-0.5; Worcester 52.2,-2.25; Woodstock 51.85,-1.35
40        var minscale=13;                                // don't zoom out past this
41        var maxscale=19;                                // don't zoom in past this
42        if (scale) {} else {scale=14;}  // default scale if not provided (e.g. GPX)
43        var scale=Math.max(Math.min(Math.floor(scale),maxscale),minscale);
44        var masterscale=5825.4222222222;// master map scale - how many Flash pixels in 1 degree longitude
45                                                                        // (for Landsat, 5120)
46        updateCoords();                                 // get radius, scale
47       
48        // Preselected way/node (from query string)
49        var preway=Number(way);
50        var prenode=Number(node);
51
52        // Preferences
53        preferences=SharedObject.getLocal("preferences");
54        var usertoken=token;
55        if (winie=='true' || winie==true) { winie=true; } else { winie=false; }
56
57        // Key listener - needs to be initialised before Yahoo
58        keyListener=new Object();
59        keyListener.onKeyDown=function() { keyPressed(); };
60        Key.addListener(keyListener);
61
62        // Initialise Yahoo
63        var ywidth=0;           var yheight=0;                  // current Yahoo state
64        var yzoom=8;            var lastyzoom=yzoom;    //  |
65        var bgxoffset=0;        var bgyoffset=0;                // manually correct Yahoo imagery
66        var yahooloaded=false;                                          // is Yahoo component loaded?
67        var yahooinited=false;                                          // is Yahoo component inited?
68        var yahoorightsize=true;                                        // do we need to resize Yahoo?
69        _root.createEmptyMovieClip("yahoo",7);
70
71//      var layernames=new Array("None","Aerial - OpenAerialMap","Aerial - Yahoo!","OSM - Mapnik","OSM - Osmarender","OSM - Maplint (errors)","OSM - cycle map");
72//      var layernums=new Array();
73//      var j=layernames.length; for (i in layernames) { j--; layernums[layernames[i]]=j; }
74
75        // Main initialisation
76        _root.map.createEmptyMovieClip("areas"    ,8);  var areadepth=1;
77        _root.map.createEmptyMovieClip("gpx"      ,9);
78        _root.map.createEmptyMovieClip("relations",10); var reldepth=1;
79        _root.map.createEmptyMovieClip("ways"     ,11); var waydepth=1;
80        _root.map.createEmptyMovieClip("pois"     ,12); var poidepth=1;
81        _root.map.createEmptyMovieClip("elastic"  ,5003); // elastic line
82        initTiles();                                    // create tile clips on layer 7
83
84        _root.masksquare.useHandCursor=false;
85        _root.masksquare.onPress   =function() { mapClick(); };
86        _root.masksquare.onRollOver=function() { mapRollOver(); };
87        _root.masksquare.onRollOut =function() { mapRollOut(); };
88        _root.masksquare.onRelease =function() { mapClickEnd(); };
89        _root.onMouseDown=function() { _root.lastkeypressed=-1; };
90
91        selectWay(0);                                   // way selected?    0 no, otherwise way id
92        var poiselected=0;                              // POI selected?    0 no, otherwise way id
93        var pointselected=-2;                   // point selected? -2 no, otherwise point order
94        var waycount=0;                                 // number of ways currently loaded
95        var waysrequested=0;                    // total number of ways requested
96        var waysreceived=0;                             // total number of ways received
97        var writesrequested=0;                  // number of outstanding write operations
98        var relcount=0;                                 // number of relations currently loaded
99        var relsrequested=0;                    // total number of relations requested
100        var relsreceived=0;                             // total number of relations received
101        var poicount=0;                                 // number of POIs currently loaded
102        var whichrequested=0;                   // total number of whichways requested
103        var whichreceived=0;                    // total number of whichways received
104        var redrawlist=new Array();             // list of ways to redraw (after zooming)
105        var redrawskip=true;                    // skip redrawing ways, just do POIs?
106        var lastresize=new Date();              // last time window was resized
107        var lastwhichways=new Date();   // last time whichways was requested
108        var mapdragged=false;                   // map being dragged?
109        var drawpoint=-1;                               // point being drawn? -1 no, 0+ yes (point order)
110        var lastpoint=0;                                // last value of drawpoint (triple-click detection)
111        var lastpointtime=null;                 // time of last double-click (triple-click detection)
112        var newrelid=-1;                                // new relation ID  (for those not yet saved)
113        var newwayid=-1;                                // new way ID           (for those not yet saved)
114        var newnodeid=-2;                               // new node ID          (for those not yet saved)
115        var newpoiid=-1;                                // new POI ID           (for those not yet saved)
116        var nodes=new Object();                 // hash of nodes
117        var currentproptype='';                 // type of property currently being edited
118        var pointertype='';                             // current mouse pointer
119        var redopropertywindow=null;    // need to redraw property window after deletion?
120        var lastkeypressed=null;                // code of last key pressed
121        var keytarget='';                               // send keys where? ('','key','value')
122        var tilesetloaded='';                   // which tileset is loaded?
123        var tolerance=4/Math.pow(2,_root.scale-13);
124        var bigedge_l=999999; var bigedge_r=-999999; // area of largest whichways
125        var bigedge_b=999999; var bigedge_t=-999999; //  |
126        var saved=new Array();                  // no saved presets yet
127        var sandbox=false;                              // we're doing proper editing
128        var lang=System.capabilities.language; // language (e.g. 'en', 'fr')
129        var signature="Potlatch 0.11";  // current version
130        var maximised=false;                    // minimised/maximised?
131        var sourcetags=new Array("","","","","NPE","OpenTopoMap");
132        var lastgroup='road';                   // last preset group used
133
134        var tileurls=new Array("http://tile.openstreetmap.org/!/!/!.png",
135                                                   "http://tah.openstreetmap.org/Tiles/tile/!/!/!.png",
136                                                   "http://tah.openstreetmap.org/Tiles/maplint/!/!/!.png",
137                                                   "http://andy.sandbox.cloudmade.com/tiles/cycle/!/!/!.png",
138                                                   "http://npe.openstreetmap.org/!/!/!.png",
139                                                   "http://tile.openaerialmap.org/tiles/1.0.0/opentopomap-900913/!/!/!.jpg");
140
141//      if (layernums[preferences.data.baselayer]==undefined) { preferences.data.baselayer="Aerial - Yahoo!"; }
142        if (preferences.data.bgtype       ==undefined) { preferences.data.bgtype       =2; }    // 1=tiles, 2=Yahoo, 3=custom, 4=none
143        if (preferences.data.tileset      ==undefined) { preferences.data.tileset      =3; }    // background layer
144        if (preferences.data.tilecustom   ==undefined) { preferences.data.tilecustom   =''; }   // custom background URL
145        if (preferences.data.dimbackground==undefined) { preferences.data.dimbackground=true; } // dim background?
146        if (preferences.data.custompointer==undefined) { preferences.data.custompointer=true; } // use custom pointers?
147        if (preferences.data.thinlines    ==undefined) { preferences.data.thinlines    =false;} // always use thin lines?
148        if (preferences.data.advice       ==undefined) { preferences.data.advice       =true; } // show floating advice?
149        if (preferences.data.nosplash     ==undefined) { preferences.data.nosplash     =false; }// hide splash screen?
150        if (preferences.data.noname       ==undefined) { preferences.data.noname       =false; }// highlight unnamed ways?
151
152        // =====================================================================================
153        // Icons
154
155        _root.attachMovie("zoomin","i_zoomin",30);
156        with (_root.i_zoomin) { _x=5; _y=5; };
157        _root.i_zoomin.onPress=function() { zoomIn(); };
158
159        _root.attachMovie("zoomout","i_zoomout",31);
160        with (_root.i_zoomout) { _x=5; _y=27; };
161        _root.i_zoomout.onPress=function() { zoomOut(); };
162        changeScaleTo(_root.scale);
163
164        // Way-specific
165
166        _root.panel.attachMovie("scissors","i_scissors",32);
167        with (_root.panel.i_scissors) { _x=15; _y=63; };
168        _root.panel.i_scissors.onPress   =function() { _root.ws.splitWay(_root.pointselected); };
169        _root.panel.i_scissors.onRollOver=function() { setFloater(iText("Split way at selected point (X)",'tip_splitway')); };
170        _root.panel.i_scissors.onRollOut =function() { clearFloater(); };
171
172        _root.panel.attachMovie("rotation","i_direction",39);
173        with (_root.panel.i_direction) { _x=40; _y=63; _rotation=-45; _visible=true; _alpha=50; };
174        _root.panel.i_direction.onPress=function() { _root.ws.reverseWay(); };
175        _root.panel.i_direction.onRollOver=function() { setFloater(iText("Direction of way - click to reverse",'tip_direction')); };
176        _root.panel.i_direction.onRollOut =function() { clearFloater(); };
177
178        _root.panel.attachMovie("clockwise","i_clockwise",40);
179        with (_root.panel.i_clockwise) { _x=40; _y=63; _visible=false; };
180        _root.panel.i_clockwise.onPress=function() { _root.ws.reverseWay(); };
181        _root.panel.i_clockwise.onRollOver=function() { setFloater(iText("Clockwise circular way - click to reverse",'tip_clockwise')); };
182        _root.panel.i_clockwise.onRollOut =function() { clearFloater(); };
183
184        _root.panel.attachMovie("anticlockwise","i_anticlockwise",42);
185        with (_root.panel.i_anticlockwise) { _x=40; _y=63; _visible=false; };
186        _root.panel.i_anticlockwise.onPress=function() { _root.ws.reverseWay(); };
187        _root.panel.i_anticlockwise.onRollOver=function() { setFloater(iText("Anti-clockwise circular way - click to reverse",'tip_anticlockwise')); };
188        _root.panel.i_anticlockwise.onRollOut =function() { clearFloater(); };
189
190        // General tools
191
192        _root.panel.lineStyle(1,0xCCCCCC,100);
193        _root.panel.moveTo(5,78); _root.panel.lineTo(75,78);
194
195        _root.panel.attachMovie("undo","i_undo",38);
196        with (_root.panel.i_undo) { _x=15; _y=93; _alpha=50; };
197        _root.panel.i_undo.onPress   =function() { _root.undo.rollback(); };
198        _root.panel.i_undo.onRollOver=function() { setFloater(iText("Nothing to undo",'tip_noundo')); };
199        _root.panel.i_undo.onRollOut =function() { clearFloater(); };
200
201        _root.panel.attachMovie("gps","i_gps",36);
202        with (_root.panel.i_gps) { _x=40; _y=93; };
203        _root.panel.i_gps.onPress   =function() { loadGPS(); };
204        _root.panel.i_gps.onRollOver=function() { setFloater(iText("Show GPS tracks (G)",'tip_gps')); };
205        _root.panel.i_gps.onRollOut =function() { clearFloater(); };
206
207        _root.panel.attachMovie("prefs","i_prefs",37);
208        with (_root.panel.i_prefs) { _x=65; _y=93; };
209        _root.panel.i_prefs.onPress   =function() { openOptionsWindow(); };
210        _root.panel.i_prefs.onRollOver=function() { setFloater(iText("Set options (choose the map background)",'tip_options')); };
211        _root.panel.i_prefs.onRollOut =function() { clearFloater(); };
212
213        _root.panel.attachMovie("newattr","i_newattr",33);
214        with (_root.panel.i_newattr) { _x=690; _y=95; };
215        _root.panel.i_newattr.onRelease =function() { _root.panel.properties.enterNewAttribute(); };
216        _root.panel.i_newattr.onRollOver=function() { setFloater(iText("Add a new tag",'tip_addtag')); };
217        _root.panel.i_newattr.onRollOut =function() { clearFloater(); };
218
219        _root.panel.attachMovie("newrel","i_newrel",44);
220        with (_root.panel.i_newrel) { _x=690; _y=75; backgroundColor=0xDDBBBB; background=true;};
221        _root.panel.i_newrel.onRelease =function() { if (Key.isDown(Key.SHIFT)) { _root.panel.properties.repeatAttributes(false);
222                                                                                                } else { addToRelation(); } };
223        _root.panel.i_newrel.onRollOver=function() { setFloater(iText("Add to a relation",'tip_addrelation')); };
224        _root.panel.i_newrel.onRollOut =function() { clearFloater(); };
225
226        _root.panel.attachMovie("repeatattr","i_repeatattr",34);
227        with (_root.panel.i_repeatattr) { _x=690; _y=55; };
228        _root.panel.i_repeatattr.onPress   =function() { _root.panel.properties.repeatAttributes(true); };
229        _root.panel.i_repeatattr.onRollOver=function() { setFloater(iText("Repeat tags from the previously selected way (R)",'tip_repeattag')); };
230        _root.panel.i_repeatattr.onRollOut =function() { clearFloater(); };
231
232        _root.panel.attachMovie("exclamation","i_warning",35);
233        with (_root.panel.i_warning) { _x=58; _y=50; _visible=false; };
234        _root.panel.i_warning.onPress=function() { handleWarning(); };
235        _root.panel.i_warning.onRollOver=function() { setFloater(iText("An error occurred - click for details",'tip_alert')); };
236        _root.panel.i_warning.onRollOut =function() { clearFloater(); };
237        wflashid=setInterval(function() { _root.panel.i_warning._alpha=150-_root.panel.i_warning._alpha; }, 750);
238
239        _root.panel.attachMovie("padlock","padlock",41);
240        with (_root.panel.padlock) { _y=32; _visible=false; };
241        _root.panel.padlock.onPress=function() { keyLock(); };
242
243        _root.createEmptyMovieClip("pointer",0xFFFFFF);
244
245        // =====================================================================================
246        // Initialise text areas
247
248        // Debug text fields
249
250        _root.createTextField('chat',20,130,315,400,80); // 515
251        with (_root.chat) {
252                multiline=true; wordWrap=true;  border=true; selectable = true; type = 'input';
253                _visible=false;//#debug
254        };
255
256        _root.createTextField('coordmonitor',21,130,400,400,60); // 515
257        with (_root.coordmonitor) {
258                multiline=true; wordWrap=true; border=true; selectable = true; type = 'input';
259                _visible=false;//#debug
260        };
261
262        _root.createTextField('floater',0xFFFFFE,15,30,200,18);
263        with (floater) {
264                background=true; backgroundColor=0xFFEEEE;
265                border=true; borderColor=0xAAAAAA;
266                selectable=false; _visible=false;
267        }
268        var floaterID=null;
269
270        // Centre cross-hair
271       
272        if (_root.chat._visible) {
273                _root.createEmptyMovieClip("crosshair",0xFFFFF0);
274                with (_root.crosshair) {
275                        _x=Stage.width/2;
276                        _y=(Stage.height-panelheight)/2;
277                        lineStyle(1,0xFFFFFF,100);
278                        moveTo(-2,0); lineTo(-10,0);
279                        moveTo( 2,0); lineTo( 10,0);
280                        moveTo(0,-2); lineTo(0,-10);
281                        moveTo(0, 2); lineTo(0, 10);
282                }
283        }
284
285// for (i in layernames) { _root.chat.text+=i+"="+layernames[i]+","; }
286// for (i in layernums ) { _root.chat.text+=i+"="+layernums[i]+","; }
287
288        // Text formats
289       
290        plainText =new TextFormat(); plainText.color =0x000000; plainText.size =14; plainText.font ="_sans";
291        plainSmall=new TextFormat(); plainSmall.color=0x000000; plainSmall.size=12; plainSmall.font="_sans";
292        plainDim  =new TextFormat(); plainDim.color  =0x777777; plainDim.size  =12; plainDim.font  ="_sans";
293        plainRight=new TextFormat(); plainRight.color=0x000000; plainRight.size=12; plainRight.font="_sans"; plainRight.align="right";
294        plainTiny =new TextFormat(); plainTiny.color =0x000000; plainTiny.size =11; plainTiny.font ="_sans";
295        plainWhite=new TextFormat(); plainWhite.color=0xFFFFFF; plainWhite.size=12; plainWhite.font="_sans";
296        greySmall =new TextFormat(); greySmall.color =0x888888; greySmall.size =12; greySmall.font ="_sans";
297        boldText  =new TextFormat(); boldText.color  =0x000000; boldText.size  =14; boldText.font  ="_sans"; boldText.bold =true;
298        boldSmall =new TextFormat(); boldSmall.color =0x000000; boldSmall.size =12; boldSmall.font ="_sans"; boldSmall.bold=true;
299        boldWhite =new TextFormat(); boldWhite.color =0xFFFFFF; boldWhite.size =12; boldWhite.font ="_sans"; boldWhite.bold=true;
300        menu_on   =new TextFormat(); menu_on.color   =0x000000; menu_on.size   =12; menu_on.font   ="_sans"; menu_on.bold  =true;
301        menu_off  =new TextFormat(); menu_off.color  =0xFFFFFF; menu_off.size  =12; menu_off.font  ="_sans"; menu_off.bold =true;
302        auto_on   =new TextFormat(); auto_on.color   =0x0000FF; auto_on.size   =12; auto_on.font   ="_sans"; auto_on.bold  =true;
303        auto_off  =new TextFormat(); auto_off.color  =0xFFFFFF; auto_off.size  =12; auto_off.font  ="_sans"; auto_off.bold =true;
304
305        // Colour transform
306       
307        to_black  =new Object(); to_black.ra=to_black.ga=to_black.ba=-100;
308        to_red    =new Object(); to_red.rb=255; to_red.gb=0;
309        to_normal =new Object(); to_normal.ra=to_normal.ga=to_normal.ba=100;
310                                                         to_normal.rb=to_normal.gb=to_normal.bb=0;
311
312        // Text fields
313
314        _root.createEmptyMovieClip('waysloading',22);
315        _root.waysloading._visible=false;
316
317        _root.createTextField('tooltip',46,480,30,215,100);
318        with (_root.tooltip  ) { text=""; setTextFormat(plainRight); selectable=false; type='dynamic'; };
319
320        _root.panel.createTextField('t_type',23,5,5,220,20);
321        with (_root.panel.t_type         ) { text=signature; setTextFormat(boldText); selectable=false; };
322       
323        _root.panel.createTextField('t_details',24,5,23,220,20);
324        with (_root.panel.t_details) { text=""; setTextFormat(plainText); selectable=false; };
325
326       
327        // MovieClip loader
328        var tileLoader=new MovieClipLoader();
329        tileListener=new Object();
330        tileLoader.addListener(tileListener);
331
332        // Interaction with responder script
333        var loaderWaiting=false;
334
335        remote_read=new NetConnection();
336        remote_read.connect(apiurl+'/read');
337        remote_read.onStatus=function(info) { _root.panel.i_warning._visible=true; };
338
339        remote_write=new NetConnection();
340        remote_write.connect(apiurl+'/write');
341        remote_write.onStatus=function(info) { _root.panel.i_warning._visible=true; };
342
343        #include 'node.as'
344        #include 'anchorpoint.as'
345        #include 'poi.as'
346        #include 'relation.as'
347        #include 'way.as'
348        #include 'history.as'
349        #include 'ui.as'
350        #include 'properties.as'
351        #include 'world.as'
352        #include 'tiles.as'
353        #include 'gps.as'
354        #include 'undo.as'
355        #include 'advice.as'
356        #include 'changeset.as'
357        #include 'start.as'
358
359        // =====================================================================================
360        // Start
361
362        var undo=new UndoStack();
363
364        _root.panel.attachMovie("propwindow","properties",50);
365        with (_root.panel.properties) { _x=110; _y=25; _visible=false; };
366
367        _root.panel.attachMovie("presetmenu","presets",60);
368        with (_root.panel.presets) { _x=110; _y=1; _visible=false; };
369
370        updateButtons();
371        updateScissors();
372        setSizes();
373        startChangeset('');
374        loadPresets();
375
376
377
378        // =====================================================================
379        // Map support functions
380        // mapRollOver/Out - user has rolled over/out the main map area
381       
382        function mapRollOver() {
383                removeMovieClip(_root.map.anchorhints);
384                if (_root.tooltip.text.substring(0,4)=='over') { clearTooltip(); }
385                if (_root.drawpoint>-1)     { setPointer('pen'); }
386                else if (_root.wayselected) { setPointer(''   ); }
387                                                       else { setPointer('pen'); }
388        }
389
390        function mapRollOut() {
391                if (_root.pointertype!='')  { setPointer(''   ); }
392        }
393       
394        // processMapDrag, moveMap - process map dragging
395
396        function processMapDrag() {
397                if (mapDragging() || Key.isDown(Key.SPACE)) {
398                        if (_root.pointertype!='hand') { setPointer('hand'); }
399
400                        if (preferences.data.bgtype==2) {
401                                var t=new Date();
402                                if ((t.getTime()-yahootime.getTime())<500) {
403                                        _root.yahoo._x+=Math.floor(_xmouse-lastxmouse); // less than 0.5s, so
404                                        _root.yahoo._y+=Math.floor(_ymouse-lastymouse); // just move offset
405                                } else {
406                                        redrawBackground();                                                             // 0.5s elapsed, so
407                                        _root.yahootime=new Date();                                             // request new tiles
408                                }
409                        } else if (preferences.data.bgtype!=4) {
410                                redrawBackground();
411                        }
412                        moveMap(Math.floor(_xmouse-lastxmouse),Math.floor(_ymouse-lastymouse));
413                }
414        }
415
416        function endMapDrag() {
417                delete _root.onMouseMove;
418                delete _root.onMouseUp;
419                if (mapDragging()) {
420                        redrawBackground();
421                        updateLinks();
422                        whichWays();
423                }
424                restartElastic();
425                if (_root.wayselected) { setPointer(''); }
426                                                  else { setPointer('pen'); }
427        }
428       
429        function moveMap(xdiff,ydiff) {
430                _root.lastxmouse=_root._xmouse;
431                _root.lastymouse=_root._ymouse;
432                if (Key.isDown(Key.SPACE)) {
433                        _root.bgxoffset+=xdiff; _root.map.tiles._x+=xdiff;
434                        _root.bgyoffset+=ydiff; _root.map.tiles._y+=ydiff;
435                        updateCoords(_root.map._x,_root.map._y);
436                } else {
437                        _root.map._x+=xdiff;
438                        _root.map._y+=ydiff;
439                        updateCoords(_root.map._x,_root.map._y);
440                }
441        }
442
443        // mapClick - user has clicked within map area, so start drag
444       
445        function mapClick() {
446                setPointer('pen');
447                clearTooltip();
448                _root.onMouseMove=function() { processMapDrag(); };
449                _root.onMouseUp  =function() { endMapDrag(); };
450                _root.mapdragged=false;
451                _root.lastxmouse=_root._xmouse;
452                _root.lastymouse=_root._ymouse;
453                _root.firstxmouse=_root._xmouse;
454                _root.firstymouse=_root._ymouse;
455                _root.clicktime=new Date();
456                _root.yahootime=new Date();
457        }
458
459        // mapDragging - test whether map was dragged or just clicked
460       
461        function mapDragging() {
462                var t=new Date();
463                var tol=Math.max(_root.tolerance,2);
464                var longclick=(t.getTime()-_root.clicktime)>300;
465                var xdist=Math.abs(_root.firstxmouse-_root._xmouse);
466                var ydist=Math.abs(_root.firstymouse-_root._ymouse);
467                if ((xdist<tol*4  && ydist<tol*4 ) ||
468                   ((xdist<tol*10 && ydist<tol*10) && !longclick)) {
469                } else {
470                        _root.mapdragged=true;
471                }
472                return _root.mapdragged;
473        }
474
475        // mapClickEnd - end of click within map area
476
477        function mapClickEnd() {
478                removeWelcome(true);
479                var t=new Date();
480                if (!mapdragged) {
481                // Clicked on map without dragging
482                        // Adding a point to the way being drawn
483                        if (_root.drawpoint>-1) {
484                                _root.newnodeid--;
485                                _root.nodes[newnodeid]=new Node(newnodeid,_root.map._xmouse,_root.map._ymouse,new Array(),0);
486                                if (_root.pointselected>-2) {
487                                        setTypeText(iText("Way",'way'),_root.wayselected);
488                                        _root.panel.properties.tidy();
489                                        _root.panel.properties.init('way',getPanelColumns(),4);
490                                        updateButtons();
491                                        updateScissors(false);
492                                }
493                                addEndPoint(_root.nodes[newnodeid]);
494                                restartElastic();
495
496                        // Deselecting a way
497                        } else if (_root.wayselected) {
498                                uploadSelected(); deselectAll();
499                                _root.lastpoint=-1;                             // Trap double-click to deselect
500                                _root.lastpointtime=new Date(); //  |
501
502                        // Deselecting a POI
503                        } else if (_root.poiselected) {
504                                uploadSelected(); deselectAll();
505
506                        // Starting a new way
507                        // ** double-click trap should probably also check distance moved
508                        } else if (_root.lastpoint!=-1 || (t.getTime()-_root.lastpointtime)>300) {
509                                _root.newnodeid--; 
510                                _root.nodes[newnodeid]=new Node(newnodeid,_root.map._xmouse,_root.map._ymouse,new Array(),0);
511                                startNewWay(newnodeid);
512                        }
513                }
514                _root.mapdragged=false;
515        }
516
517
518
519        // =====================================================================
520        // Tooltip and pointer functions
521
522        function setTooltip(txt,delay) {
523                _root.tooltip.text=txt;
524                _root.tooltip.setTextFormat(plainRight);
525                _root.createEmptyMovieClip('ttbackground',45);
526                with (_root.ttbackground) {
527                        _x=Stage.width-5; _y=30;
528                        beginFill(0xFFFFFF,75);
529                        moveTo(0,0); lineTo(-_root.tooltip.textWidth-10,0);
530                        lineTo(-_root.tooltip.textWidth-10,_root.tooltip.textHeight+5);
531                        lineTo(0,_root.tooltip.textHeight+5); lineTo(0,0);
532                        endFill();
533                }
534        }
535
536        function clearTooltip() {
537                _root.tooltip.text='';
538                removeMovieClip(_root.ttbackground);
539        }
540       
541        function setFloater(txt) {
542                with (_root.floater) {
543                        text=txt;
544                        setTextFormat(plainSmall); 
545                        _width=textWidth+4;
546
547                        if (_root._ymouse+25<Stage.height      ) { _y=_root._ymouse+4;                   }
548                                                                                                else { _y=_root._ymouse-16;          }
549                        if (_root._xmouse+textWidth<Stage.width) { _x=_root._xmouse+4;                   }
550                                                                                                else { _x=_root._xmouse-textWidth-8; }
551                        _visible=false;
552                }
553                clearInterval(floaterID);
554                floaterID=setInterval(unveilFloater,1000);
555        }
556
557        function unveilFloater(txt) {
558                _root.floater._visible=true;
559                clearInterval(floaterID);
560        }
561       
562        function clearFloater(txt) {
563                clearInterval(floaterID);
564                _root.floater._visible=false;
565        }
566
567        function setPointer(ptype) {
568                if (_root.pointertype==ptype) { return; }
569                if ((ptype) && preferences.data.custompointer) {
570                        _root.attachMovie(ptype,"pointer",0xFFFFFF);
571                        _root.pointer.cacheAsBitmap=true;
572                        _root.pointer._x=_root._xmouse;
573                        _root.pointer._y=_root._ymouse;
574                        _root.pointer.startDrag(true);
575                        Mouse.hide();
576                } else {
577                        _root.pointer._visible=false;
578                        _root.pointer.stopDrag();
579                        Mouse.show();
580                        removeMovieClip(_root.pointer);
581                }
582                _root.pointertype=ptype;
583        }
584
585       
586
587
588
589        // =====================================================================================
590        // Keypress functions
591
592        // keyPressed                           - key listener
593
594        function keyPressed() {
595                clearAdvice();
596                var k=Key.getCode();
597                var c=Key.getAscii(); if (c>=97 && c<=122) { c=c-32; }
598                var s=String.fromCharCode(c);
599                _root.lastkeypressed=k;
600
601                if (keytarget=='keyname' || keytarget=='value') {
602                        if (_root.auto!=undefined) { _root.auto.keyRespond(k); }
603                                           else if (k==13) { autoEnter(); }
604                        return;
605                } else if (_root.windowsopen) {
606                        if (k==187 && _root.windows.relation.box.properties!=undefined) {
607                                _root.windows.relation.box.properties.enterNewAttribute();
608                        };
609                        return;
610                } else if (keytarget!='') { return; }
611
612                if (c>48 && c<58 && (wayselected!=0 || poiselected!=0)) {
613                        if (presetnames[_root.panel.properties.proptype][_root.panel.presets.group][c-48]!=null) {
614                                _root.panel.presets.setAttributes(c-48);
615                                _root.panel.presets.reflect();
616                                if (_root.panel.properties.proptype=='way') { _root.ws.redraw(); }
617                        }
618                        return;
619                } else if (k>=112 && k<=120) {
620                        preferences.data.dimbackground=Key.isDown(Key.SHIFT); 
621                        switch (k) {
622                                case 112:       preferences.data.bgtype=4; break;
623                                case 113:       preferences.data.bgtype=2; break;
624                                default:        preferences.data.bgtype=1; preferences.data.tileset=k-114; break;
625                        }
626                        initBackground(); return;
627                }
628
629                switch (k) {
630                        case 46:                ;                                                                                                       // DELETE/backspace - delete way/node
631                        case 8:                 if (Key.isDown(Key.SHIFT)) {                                            //  |
632                                                                if (_root.wayselected!=0) { _root.ws.removeWithConfirm(); }
633                                                        } else { keyDelete(1); }; break;                                        //  |
634                        case 13:                _root.junction=false; stopDrawing(); break;                     // ENTER - stop drawing line
635                        case 27:                keyRevert(); break;                                                                     // ESCAPE - revert current way
636                        case Key.PGUP:  zoomIn(); break;                                                                        // Page Up - zoom in
637                        case Key.PGDN:  zoomOut(); break;                                                                       // Page Down - zoom out
638                        case Key.LEFT:  moveMap( 140,0); updateLinks(); redrawBackground(); whichWays(); break; // cursor keys
639                        case Key.RIGHT: moveMap(-140,0); updateLinks(); redrawBackground(); whichWays(); break; //  |
640                        case Key.DOWN:  moveMap(0,-100); updateLinks(); redrawBackground(); whichWays(); break; //  |
641                        case Key.UP:    moveMap(0, 100); updateLinks(); redrawBackground(); whichWays(); break; //  |
642                        case Key.CAPSLOCK: dimMap(); break;                                                                     // CAPS LOCK - dim map
643                        case 167:               _root.panel.presets.cycleIcon(); break;                         // cycle presets
644                }
645               
646                switch (s) {
647                        case 'C':               closeChangeset(); break;                                                        // C - close current changeset
648                        case 'G':               loadGPS(); break;                                                                       // G - load GPS
649                        case 'H':               getHistory(); break;                                                            // H - history
650                        case 'L':               showPosition(); break;                                                          // L - show latitude/longitude
651                        case 'P':               askOffset(); break;                                                                     // O - parallel path
652                        case 'R':               _root.panel.properties.repeatAttributes(true);break;// R - repeat attributes
653                        case 'U':               getDeleted(); break;                                                            // U - undelete
654                        case 'X':               _root.ws.splitWay(_root.pointselected); break;          // X - split way
655                        case 'Z':               _root.undo.rollback(); break;                                           // Z - undo
656                        case '`':               _root.panel.presets.cycleIcon(); break;                         // '`' - cycle presets
657                        case '+':               _root.panel.properties.enterNewAttribute(); break;      // '+' - add new attribute (107/187)
658                        case '-':               keyDelete(0); break;                                                            // '-' - delete node from this way only (189)
659                        case '/':               cycleStacked(); break;                                                          // '/' - cycle between stacked ways (191)
660                        case 'M':               maximiseSWF(); break;                                                           // 'M' - maximise/minimise Potlatch
661                        case 'K':               keyLock(); break;                                                                       // 'K' - lock item
662                        case 'S':               var s=''; switch (preferences.data.bgtype) {            // 'S' - set source tag
663                                                                case 1: s=sourcetags[preferences.data.tileset]; break;
664                                                                case 2: s='Yahoo'; break;
665                                                                case 3: s=preferences.data.tilecustom; break;
666                                                        }
667                                                        _root.panel.properties.setTag("source",s); break;
668//                      default:                _root.chat.text=Key.getCode()+" pressed";
669                };
670        }
671
672        function showPosition() { setTooltip("lat "+Math.floor(coord2lat (_root.map._ymouse)*10000)/10000
673                                                                          +"\nlon "+Math.floor(coord2long(_root.map._xmouse)*10000)/10000,0); }
674        function startCount()   { z=new Date(); _root.startTime=z.getTime(); }
675        function endCount(id)   { z=new Date(); zz=Math.floor((z.getTime()-_root.startTime)*100);
676                                                        if (zz>100) { _root.chat.text+=id+":"+zz+";"; } }
677
678        function showObjects(z,indnt) {
679                for (var i in z) {
680                        _root.chat.text+=indnt+i+" ("+typeof(z[i])+")\n";
681                        if (typeof(z[i])=='movieclip' || typeof(z[i])=='object') {
682                                showObjects(z[i],indnt+" ");
683                        }
684                }
685        }
686       
687        function showWaysForNode() {
688                var z=_root.ws.path[pointselected].ways;
689                _root.coordmonitor.text="";
690                for (i in z) { _root.coordmonitor.text+=i+","; }
691        }
692
693        function keyLock() {
694                _root.panel.padlock._x=_root.panel.t_details.textWidth+15;
695                if (_root.wayselected && _root.ws.locked && _root.ws.path.length>200 && !_root.ws.historic) {
696                        setAdvice(true,iText("Too long to unlock - please split into shorter ways",'advice_toolong'));
697                } else if (_root.wayselected) {
698                        _root.ws.locked=!_root.ws.locked;
699                        _root.ws.redraw();
700                        _root.panel.padlock._visible=_root.ws.locked;
701                        if (!_root.ws.locked) { markWayRelationsDirty(_root.wayselected); }
702                } else if (_root.poiselected) {
703                        _root.map.pois[poiselected].locked=!_root.map.pois[poiselected].locked;
704                        _root.map.pois[poiselected].recolour();
705                        _root.panel.padlock._visible=_root.map.pois[poiselected].locked;
706                        if (!_root.map.pois[poiselected].locked) { markNodeRelationsDirty(poiselected); }
707                }
708        }
709
710        function keyDelete(doall) {
711                if (_root.poiselected) {
712                        // delete POI
713                        _root.map.pois[poiselected].saveUndo(iText("deleting",'deleting'));
714                        _root.map.pois[poiselected].remove();
715                } else if (_root.drawpoint>-1) {
716                        // 'backspace' most recently drawn point
717                        _root.undo.append(UndoStack.prototype.undo_deletepoint,
718                                                          new Array(deepCopy(_root.ws.path[drawpoint]),
719                                                                                [wayselected],[drawpoint]),
720                                                          iText("deleting a point",'action_deletepoint'));
721                        _root.ws.path[drawpoint].removeWay(_root.wayselected);
722                        if (_root.drawpoint==0) { _root.ws.path.shift(); }
723                                                           else { _root.ws.path.pop(); _root.drawpoint-=1; }
724                        if (_root.ws.path.length) {
725                                _root.ws.clean=false;
726                                markClean(false);
727                                _root.ws.redraw();
728                                _root.ws.highlightPoints(5000,"anchor");
729                                _root.ws.highlight();
730                                restartElastic();
731                        } else {
732                                _root.map.anchors[_root.drawpoint].endElastic();
733                                _root.ws.remove();
734                                _root.drawpoint=-1;
735                                deselectAll();
736                        }
737                } else if (_root.pointselected>-2) {
738                        // delete selected point
739                        if (doall==1) { _root.ws.path[_root.pointselected].removeFromAllWays(); }
740                                         else { _root.ws.removeAnchorPoint(pointselected); }
741                        _root.pointselected=-2;
742                        _root.drawpoint=-1;
743                        _root.map.elastic.clear();
744                        clearTooltip();
745                        markClean(false);
746                        if (_root.wayselected) { _root.ws.select(); }
747                }
748        };
749
750        function keyRevert() {
751                if              (_root.wayselected<0) { _root.ws.saveUndo(iText("deleting",'deleting'));
752                                                                                stopDrawing();
753                                                                                removeMovieClip(_root.map.areas[wayselected]);
754                                                                                removeMovieClip(_root.ws); }
755                else if (_root.wayselected>0) { _root.ws.saveUndo(iText("cancelling changes to",'action_cancelchanges'));
756                                                                                stopDrawing();
757                                                                                _root.ws.reload(); }
758                else if (_root.poiselected>0) { _root.map.pois[poiselected].saveUndo(iText("cancelling changes to",'action_cancelchanges'));
759                                                                                _root.map.pois[poiselected].reload(); }
760                else if (_root.poiselected<0) { _root.map.pois[poiselected].saveUndo(iText("deleting",'deleting'));
761                                                                                removeMovieClip(_root.map.pois[poiselected]); }
762                revertDirtyRelations();
763                deselectAll();
764        };
765
766
767
768        // =====================================================================
769        // Potlatch-specific UI functions
770       
771        function writeText(obj,t) {
772                with (obj) {
773                        text=t; wordWrap=true;
774                        setTextFormat(plainSmall);
775                        selectable=false; type='dynamic';
776                }
777        }
778
779        function handleError(code,result) {
780                var h=100;
781                if (code==-2) { error=result[0]+iText("\n\nPlease e-mail richard\@systemeD.net with a bug report, saying what you were doing at the time.",'emailauthor'); h+=50; }
782                                 else { error=result[0]; }
783                _root.windows.attachMovie("modal","error",++windowdepth);
784                _root.windows.error.init(275,h,new Array('Ok'),null);
785                _root.windows.error.box.createTextField("prompt",2,7,9,250,h-30);
786                writeText(_root.windows.error.box.prompt,error);
787        }
788
789        function handleWarning() {
790                _root.windows.attachMovie("modal","error",++windowdepth);
791                _root.windows.error.init(275,130,new Array('Retry','Cancel'),handleWarningAction);
792                _root.windows.error.box.createTextField("prompt",2,7,9,250,100);
793                writeText(_root.windows.error.box.prompt,iText("Sorry - the connection to the OpenStreetMap server failed. Any recent changes have not been saved.\n\nWould you like to try again?",'error_connectionfailed'));
794        };
795
796        function handleWarningAction(choice) {
797                if (choice=='Retry') {
798                        // loop through all ways which are uploading, and reupload
799                        _root.panel.i_warning._visible=false;
800                        for (var qway in _root.map.ways) {
801                                if (_root.map.ways[qway].uploading) {
802                                        _root.map.ways[qway].uploading=false;
803                                        _root.map.ways[qway].upload();
804                                }
805                        }
806                        for (var qrel in _root.map.relations) {
807                                if (_root.map.relations[qrel].uploading) {
808                                        _root.map.relations[qrel].uploading=false;
809                                        _root.map.relations[qrel].upload();
810                                }
811                        }
812                }
813        };
814
815
816        // =====================================================================
817        // Internationalisation functions
818       
819        function iText(en,id,key1,key2) {
820                var t=en;
821                if (l!='en' && _root.i18n[id][_root.lang]) {
822                        t=_root.i18n[id][_root.lang];
823                }
824                t=replaceStr(t,'$1',key1);
825                t=replaceStr(t,'$2',key2);
826                t=replaceStr(t,'\\n',"\n");
827                return t;
828        }
829
830        function replaceStr(s,a,b) {
831                while (s.indexOf(a)>-1) {
832                        var n=s.indexOf(a);
833                        s=s.substr(0,n)+b+s.substr(n+a.length);
834                }
835                return s;
836        }
837
838
839        // =====================================================================
840        // General support functions
841
842        // everyFrame() - called onEnterFrame
843
844        function everyFrame() {
845
846                // ---- Fix Yahoo! peculiarities
847                _root.yahoo.myMap.enableKeyboardShortcuts(false);
848
849                if (preferences.data.bgtype==2) {
850                        var t=0;
851                        for (i in _root.yahoo.myMap.map["map_"+(18-_root.scale)].mc) {
852                                t+=_root.yahoo.myMap.map["map_"+(18-_root.scale)].mc[i][i].getBytesTotal();
853                        }
854                        _root.yahoo._visible=(t>124000);        // 122850=all blank
855                }
856
857                if (_root.yahoo.myMap.config.isLoaded) {
858                        if (!_root.yahooinited) {
859                                _root.yahooinited=true;
860                                _root.yahooresizer=setInterval(resizeWindow,1000);
861                                setYahooSize();
862                                enableYahooZoom();
863                                _root.yahoo.myMap.map.updateCopyright();
864                        } else if (!_root.yahoorightsize) {
865                                _root.yahoorightsize=true;
866                                _root.yahooresizer=setInterval(resizeWindow,1000);
867                        }
868                }
869
870                // ---- Do we need to redraw the property window?
871                if (_root.redopropertywindow) {
872                        _root.redopropertywindow.tidy();
873                        _root.redopropertywindow.reinit();
874                        _root.redopropertywindow=null;
875                }
876
877                // ---- If resizing has stopped, issue new whichways
878                //              and resize panel
879                var t=new Date();
880                if ((t.getTime()-lastresize.getTime())>500) {
881                        if (lastresize.getTime()>lastwhichways.getTime()) {
882                                whichWays();
883                                redrawBackground();
884                        }
885                }
886
887                // ---- Control "loading ways" display
888                var loading=(_root.waysrequested!=_root.waysreceived) || (_root.whichrequested!=_root.whichreceived);
889                if (loading && _root.writesrequested) { setIOStatus(3); }
890                          else if (_root.writesrequested) { setIOStatus(2); }
891                                                        else if (loading) { setIOStatus(1); }
892                                                                                 else { _root.io=0; _root.waysloading._visible=false; }
893
894                // ---- Redraw lines if necessary (5 per frame)
895                if (_root.redrawlist.length) {
896                        for (var i=0; i<5; i++) {
897                                var w=_root.redrawlist.pop();
898                                _root.map.ways[w].redraw(_root.redrawskip);
899                        }
900                } else { _root.redrawskip=true; }
901
902                // ---- Service tile queue
903                if (preferences.data.bgtype==1 || preferences.data.bgtype==3) { serviceTileQueue(); }
904                if (_root.map.ways._alpha<40) { if (!Key.isToggled(Key.CAPSLOCK)) { dimMap(); } }
905                       
906                // ---- Reinstate focus if lost after click event
907                if (_root.reinstatefocus) {
908                        Selection.setFocus(_root.reinstatefocus); 
909                        _root.reinstatefocus=null;
910                }
911        }
912       
913        // Dim map on CAPS LOCK
914
915        function dimMap() {
916                _root.map.areas._alpha=
917                _root.map.highlight._alpha=
918                _root.map.relations._alpha=
919                _root.map.ways._alpha=
920                _root.map.pois._alpha=Key.isToggled(Key.CAPSLOCK)?30:100;
921        }
922
923        // Options window
924       
925        function openOptionsWindow() {
926                _root.windows.attachMovie("modal","options",++windowdepth);
927                _root.windows.options.init(390,130,new Array('Ok'),function() { preferences.flush(); } );
928                var box=_root.windows.options.box;
929
930                // Background selector
931
932                box.attachMovie("radio","bgoption",40);
933                box.bgoption.addButton(10,15,'');
934                box.bgoption.addButton(10,35,'Yahoo!');
935                box.bgoption.addButton(10,55,iText("Custom: ",'custom'));
936                box.bgoption.addButton(10,75,iText("No background",'nobackground'));
937                box.bgoption.doOnChange=function(n) { preferences.data.bgtype=n; initBackground(); };
938
939                box.attachMovie("menu","background",60);
940                box.background.init(24,12,preferences.data.tileset,
941                        new Array("OSM - Mapnik","OSM - Osmarender","OSM - Maplint (errors)","OSM - cycle map","Out-of-copyright map","OpenTopoMap"),
942                        'Choose the background to display',function(n) { preferences.data.tileset=n; _root.windows.options.box.bgoption.select(1); },null,0);
943
944                var w=box.bgoption[3].prompt._width+25;
945                box.createTextField("custom",50,w,52,190-w,17);
946                box.custom.setNewTextFormat(plainSmall); box.custom.type='input';
947                box.custom.variable="preferences.data.tilecustom";
948                box.custom.background=true; box.custom.backgroundColor=0xDDDDDD;
949                box.custom.border=true; box.custom.borderColor=0xFFFFFF;
950                box.custom.onSetFocus=function() { this._parent.bgoption.select(3); };
951                box.custom.onKillFocus=function() { initBackground(); };
952
953                box.bgoption.select(preferences.data.bgtype);
954
955                // Checkboxes
956
957                box.attachMovie("checkbox","fadepref",5);
958                box.fadepref.init(10,100,iText("Fade background",'option_fadebackground'),preferences.data.dimbackground,function(n) { preferences.data.dimbackground=n; redrawBackground(); });
959
960                box.attachMovie("checkbox","linepref",8);
961                box.linepref.init(220,15,iText("Use thin lines at all scales",'option_thinlines'),preferences.data.thinlines,function(n) { preferences.data.thinlines=n; changeScaleTo(_root.scale); redrawWays(); });
962
963                box.attachMovie("checkbox","noname",10);
964                box.noname.init(220,35,iText("Highlight unnamed roads",'option_noname'),preferences.data.noname,function(n) { preferences.data.noname=n; redrawWays(); });
965
966                box.attachMovie("checkbox","pointer",4);
967                box.pointer.init(220,55,iText("Use pen and hand pointers",'option_custompointers'),preferences.data.custompointer,function(n) { preferences.data.custompointer=n; });
968
969                box.attachMovie("checkbox","warnings",3);
970                box.warnings.init(220,75,iText("Show floating warnings",'option_warnings'),preferences.data.advice,function(n) { preferences.data.advice=n; });
971
972        }
973       
974        // markClean - set JavaScript variable for alert when leaving page
975
976        function markClean(a) {
977                if (!_root.sandbox) {
978                        if (winie) { flash.external.ExternalInterface.call("markChanged",a); }
979                                  else { getURL("javascript:var changesaved="+a); }
980                }
981        }
982       
983        // deselectAll
984
985        function deselectAll() {
986                _root.map.createEmptyMovieClip("anchors",5000); 
987                _root.map.elastic.clear();
988                removeMovieClip(_root.map.highlight);
989                _root.panel.i_clockwise._visible=false;
990                _root.panel.i_anticlockwise._visible=false;
991                _root.panel.i_direction._visible=true;
992                _root.panel.i_direction._alpha=50;
993                clearTooltip();
994                setTypeText("","");
995                _root.panel.padlock._visible=false;
996
997                _root.panel.properties.saveAttributes();
998                _root.panel.properties.tidy();
999                _root.panel.properties.init('');
1000                _root.panel.presets.init();
1001                updateButtons();
1002                updateScissors(false);
1003                poiselected=0;
1004                pointselected=-2;
1005                lastpoint=0;
1006                selectWay(0);
1007                markClean(true);
1008        };
1009       
1010        // uploadSelected
1011       
1012        function uploadSelected() {
1013                _root.panel.properties.tidy();
1014                if (_root.wayselected!=0 && !_root.ws.clean) {
1015                        uploadDirtyWays(true);
1016                }
1017                if (_root.poiselected!=0 && !_root.map.pois[poiselected].clean) {
1018                        _root.map.pois[poiselected].upload();
1019                }
1020                uploadDirtyRelations();
1021        };
1022       
1023        function uploadDirtyWays(allow_ws) {
1024                var z=_root.map.ways;
1025                for (i in z) {
1026                        if (!_root.map.ways[i].clean && (i!=wayselected || allow_ws) && !_root.map.ways[i].hasDependentNodes()) { 
1027                                _root.map.ways[i].upload();
1028                        }
1029                }
1030        };
1031
1032        // highlightSquare
1033       
1034        function highlightSquare(sx,sy,ss) {
1035                _root.map.createEmptyMovieClip("highlight",5);
1036                _root.map.highlight._x=sx;
1037                _root.map.highlight._y=sy;
1038                _root.map.highlight.beginFill(0xFFFF00,80);
1039                _root.map.highlight.moveTo(-ss, ss);
1040                _root.map.highlight.lineTo( ss, ss);
1041                _root.map.highlight.lineTo( ss,-ss);
1042                _root.map.highlight.lineTo(-ss,-ss);
1043                _root.map.highlight.lineTo(-ss, ss);
1044                _root.map.highlight.endFill();
1045        };
1046
1047        // setIOStatus - update top-right message
1048
1049        function setIOStatus(msg) {
1050                if (_root.io==msg) { return; }
1051                _root.io=msg; var t;
1052                switch (msg) {
1053                        case 3: t=iText("loading/saving data",'hint_saving_loading'); break;
1054                        case 2: t=iText("saving data",'hint_saving'); break;
1055                        case 1: t=iText("loading data",'hint_loading'); break;
1056                }
1057                _root.waysloading.createTextField('prompt',2,0,0,195,20);
1058                with (_root.waysloading.prompt) { text=t; setTextFormat(plainRight); selectable=false; }
1059                _root.waysloading.createEmptyMovieClip('bg',1);
1060                with (_root.waysloading.bg) {
1061                        beginFill(0xFFFFFF,75);
1062                        moveTo(215,0); lineTo(210-_root.waysloading.prompt.textWidth-22,0);
1063                        lineTo(210-_root.waysloading.prompt.textWidth-22,_root.waysloading.prompt.textHeight+5);
1064                        lineTo(215,_root.waysloading.prompt.textHeight+5); lineTo(215,0);
1065                        endFill();
1066                }
1067                _root.waysloading._visible=true;
1068        }
1069
1070        // deepCopy (recursive) and shallowCopy (non-recursive)
1071
1072        function deepCopy(z) {
1073                var a;
1074                if (z.length==null) { a=new Object(); }
1075                                           else { a=new Array(); }
1076                for (var i in z) {
1077                        if (typeof(z[i])=='object') { a[i]=deepCopy(z[i]); }
1078                                                                   else { a[i]=z[i]; }
1079                }
1080                return a;
1081        };
1082
1083        function shallowCopy(z) {
1084                var a;
1085                if (z.length==null) { a=new Object(); }
1086                                           else { a=new Array(); }
1087                for (var i in z) { a[i]=z[i]; }
1088                return a;
1089        }
Note: See TracBrowser for help on using the repository browser.