var nyc = nyc || {};
/**
* @desc A class for managing user-specified location information
* @public
* @class
* @extends {nyc.EventHandling}
* @constructor
* @param {nyc.LocationMgr.Options} options Constructor options
* @fires nyc.Locate#geocode
* @fires nyc.Locate#geolocation
*/
nyc.LocationMgr = function(options){
this.controls = options.controls;
this.locate = options.locate;
this.locator = options.locator;
this.autoLocate = options.autoLocate || this.autoLocate;
this.dialog = new nyc.Dialog();
this.locate.on(nyc.Locate.EventType.GEOCODE, this.located, this);
this.locate.on(nyc.Locate.EventType.GEOLOCATION, this.located, this);
this.locate.on(nyc.Locate.EventType.AMBIGUOUS, this.ambiguous, this);
this.controls.on(nyc.ZoomSearch.EventType.SEARCH, this.locate.search, this.locate);
this.controls.on(nyc.ZoomSearch.EventType.GEOLOCATE, this.locate.locate, this.locate);
this.controls.on(nyc.ZoomSearch.EventType.DISAMBIGUATED, this.located, this);
this.locateFromQueryString();
};
nyc.LocationMgr.prototype = {
/**
* @desc The search controls
* @public
* @member {nyc.ZoomSearch}
*/
controls: null,
/**
* @private
* @member {nyc.Locate}
*/
locate: null,
/**
* @private
* @member {nyc.Locator}
*/
locator: null,
/**
* @private
* @member {nyc.Dialog}
*/
dialog: null,
/**
* @private
* @member {boolean}
*/
autoLocate: false,
/**
* @private
* @method
* @param {nyc.Locate.Ambiguous} data
*/
ambiguous: function(data){
if (data.possible.length){
this.controls.disambiguate(data);
}else{
this.controls.searching(false);
this.dialog.ok('The location you entered was not understood');
}
},
/**
* @private
* @method
* @param {nyc.Locate.Result} data
*/
located: function(data){
var me = this;
me.controls.val(data.type == nyc.Locate.EventType.GEOLOCATION ? '' : data.name);
me.locator.zoomLocation(data, function(){
me.trigger(data.type, data);
});
},
/**
* @private
* @method
*/
locateFromQueryString: function(){
var qstr = document.location.search, args = {};
try{
var params = qstr.substr(1).split("&");
for (var i = 0; i < params.length; i++){
var p = params[i].split("=");
args[p[0]] = decodeURIComponent(p[1]);
}
}catch(ignore){}
if (args.address){
this.locate.search(args.address);
}else if (this.autoLocate){
this.locate.locate();
}
}
};
nyc.inherits(nyc.LocationMgr, nyc.EventHandling);
/**
* @desc Object type to hold constructor options for {@link nyc.LocationMgr}
* @public
* @typedef {Object}
* @property {nyc.ZoomSearch} controls The UX controls for user input
* @property {nyc.Locate} locate The geocoding and geolocation provider
* @property {nyc.Locator} locator The locator used to manipulate a map
* @property {boolean} [autoLocate=false] Automatically locate using device geolocation on load
*/
nyc.LocationMgr.Options;