// This library is maintained at
// http://github.com/othermedia/map-navigation
if(window.GUnload)Ojay(window).on('unload',GUnload);if(window.GMap2)JS.MethodChain.addMethods(GMap2);var MapNavigation=new JS.Class({include:[JS.State,Ojay.Observable],initialize:function(){if(window.GBrowserIsCompatible===undefined||!GBrowserIsCompatible())return this.setState('INCOMPATIBLE');this.setState('INACTIVE');this.on('locationchange',function(a,b,d){var c=d.getMarker(),f=c.getIcon();var g=f.activeImage;if(g)c.setImage(g);if(!b)return;c=b.getMarker(),f=c.getIcon();c.setImage(f.image)});this.on('adjustlocation').fitToMarkers()},getInitialState:function(){return{url:null}},changeState:function(a){var b;if(b=this.findLocationByURL(a.url))this.displayLocation(b)},getHTML:function(){this._elements=this._elements||{};var b=this._elements,d=this;if(b._container)return b._container;return b._container=Ojay(Ojay.HTML.div({className:d.klass.CONTAINER_CLASS},function(a){b._map=Ojay(a.div({className:d.klass.MAP_CLASS}));b._display=Ojay(a.div({className:d.klass.DISPLAY_CLASS}))}))},getDisplay:function(){return(this._elements||{})._display||Ojay()},install:function(a,b){if(this.inState('INCOMPATIBLE'))return;Ojay(b).insert(this.getHTML().node,a)},clear:function(){this.getGMap().clearOverlays();this._locations=[]},setContent:function(b){this.clear();this.addLocationList(YAHOO.lang.JSON.parse(b).map(function(a){return new this.klass.Location(a)},this))},addLocation:function(b,d,c){if(this.inState('INCOMPATIBLE'))return;this._locations=this._locations||[];b.setMap(this);this._locations.push(b);GEvent.addListener(b.getMarker(),'click',function(){var a=this.getMap();if(!a)return;a.changeState({url:this.getURL()})}.bind(b));if(this._map){if(b.hasLatLng()){this._map.addOverlay(b.getMarker());this.fitToMarkers();if(d)d.call(c||null)}else{b.on('locationfound',function(a){this._map.addOverlay(a.getMarker());if(d)d.call(c||null)},this)}this.notifyObservers('addlocation',b)}},addLocationList:function(d){var c=function(){var a=d.shift(),b;if(!a){b=this.getInitialState(),a;if(a=this.findLocationByURL(b.url))this.displayLocation(a);return}else{this.addLocation(a,function(){setTimeout(c.bind(this),10)},this)}};c.call(this)},getCurrentLocation:function(){return this._currentLocation||null},findLocationByURL:function(b){this._locations=this._locations||[];return this._locations.filter(function(a){return a.getURL()==b})[0]||null},getBounds:function(){if(this.inState('INCOMPATIBLE'))return null;if(!this._locations||!this._locations.length)return null;var g=this._locations.filter('hasLatLng').reduce(function(a,b){if(b.ignore)return a;var d=b.getLatLng(),c=d.lat(),f=d.lng();if(a===null)return{n:c,s:c,e:f,w:f};if(c>a.n)a.n=c;if(c<a.s)a.s=c;if(f>a.e)a.e=f;if(f<a.w)a.w=f;return a},null);return g?new GLatLngBounds(new GLatLng(g.s,g.w),new GLatLng(g.n,g.e)):null},fitToMarkers:function(){var a=this.getBounds();if(a===null)return;var b=this._map.getBoundsZoomLevel(a);this._map.setCenter(a.getCenter(),b)},getGMap:function(){return this._map||null},states:{INCOMPATIBLE:{},INACTIVE:{activate:function(){this.getHTML();var a=this._elements._map.getRegion();var b=this._map=new GMap2(this._elements._map.node,{size:new GSize(a.getWidth(),a.getHeight())});b.setCenter(new GLatLng(0,0),1);this.setState('READY');this.notifyObservers('ready')}},READY:{displayLocation:function(b){var d=this._currentLocation||null;this._currentLocation=b;var c=b.getURL();if(!c)return;this.setState('REQUESTING');this.notifyObservers('pagerequest',c);Ojay.HTTP.GET(c,{},{onSuccess:function(a){a.insertInto(this._elements._display);this.setState('READY');this.notifyObservers('pageload',c);this.notifyObservers('locationchange',d,b)}.bind(this),onFailure:function(){this.setState('READY')}.bind(this)})}},REQUESTING:{}},extend:{CONTAINER_CLASS:'map-navigation',MAP_CLASS:'map-container',DISPLAY_CLASS:'map-display',DEBUG:true,fromHTML:function(a,b){a=Ojay(a);var d=new MapNavigation();var c=this.Location.fromHTML(a,b);if(b)c.forEach(b);d.install('after',a);d.wait(0.001)._(function(){this.activate();this.addLocationList(c)});return d},Geocoder:new GClientGeocoder(),Location:new JS.Class({include:Ojay.Observable,extend:{DATA_CLASS:'geodata',fromHTML:function(g,h){g=Ojay(g);if(!g.node)return[];return g.descendants('a').reduce(function(a,b){var d=b.children('.'+this.DATA_CLASS);if(!d.node)return a;var c=d.node.innerHTML.stripTags(),f;try{f=YAHOO.lang.JSON.parse(c)}catch(e){alert('Invalid JSON data: '+c);f={}}f.title=b.node.innerHTML.replace(c,'').stripTags();f.href=b.node.href;f.icon=b.node.className.trim();a.push(new this(f,b,h));return a}.bind(this),[])}},initialize:function(a,b,d){this._data=a||{};this._filter=d;if(b)b.on('click',function(b,evnt){var c=this.getMap();if(!c)return;evnt.stopEvent();c.changeState({url:this.getURL()})},this)},setMap:function(a){this._map=a},getMap:function(){return this._map||null},hasLatLng:function(){return this._data.lat!==undefined&&this._data.lng!==undefined},getLatLng:function(a,b){var d=this._data;if(!this.hasLatLng()&&d.address&&!this._unknownLocation)MapNavigation.Geocoder.getLatLng(d.address,function(result){this.notifyObservers('locationfound');if(!result){if(MapNavigation.DEBUG)alert('Address could not be geocoded: '+d.address);return this._unknownLocation=true}d.lat=result.lat();d.lng=result.lng();this.getMarker().setLatLng(this.getLatLng());this.getMap().notifyObservers('adjustlocation',this)}.bind(this));if(!this._filtered&&this._filter){this._filtered=true;this._filter(this)}return new GLatLng(this._data.lat||0,this._data.lng||0)},getMarker:function(){if(this._marker)return this._marker;var a=MapNavigation.Icons.get(this._data.icon)||undefined;return this._marker=new GMarker(this.getLatLng(),a)},getURL:function(){return this._data.href||null}}),Icons:new JS.Singleton({initialize:function(){this._icons={}},register:function(a,b){this._icons[a]=this.make(b)},get:function(a){return this._icons[a]||null},make:function(a){var b=new GIcon();JS.extend(b,a||{});return b}})}});
