
/**
 * Application to handle BigMap, i.e. a map with juxtapositioned result list.
 * 
 * 
 * 1. User interacts with map
 * 2. URL / Param change
 * 3. onStateChange
 * 4. Updates Map section / zoom (if via user interaction, map will be unchanged) 
 * 5. MapWidget loads positions and shows markers
 * 6. onPositionsLoaded event (with positions)
 * 7. ContextServiceConnector creates result list from positions
 * 
 */
function BrowseByLocationApp() {
	BrowseByLocationApp.baseConstructor.call(this, $("#searchComponent"), new ContextServiceConnector(this));

	this.mapWidget = new MapWidgetForServiceConnector($("#mapWidget"), this);
	this.mapWidget.options.showPositionsInProximity = true;
	this.mapWidget.options.searchOnlyAndAlways = true;
	this.mapWidget.showSearchToolbar();
	
	this.componentController.register(this.mapWidget);
	
	this.itemsPerPage = 12;
	
	this._startUp();
}
BrowseByLocationApp.extend(PagedSearch);

BrowseByLocationApp.prototype.startUp = function(){
	// Empty overwritten, so ComponentController gets init'ed after MapWidget creation.
}

BrowseByLocationApp.prototype._startUp = function() {
	// Call original startUp method
	BrowseByLocationApp.superClass.startUp.call(this);
}

BrowseByLocationApp.prototype.getSubscriptionEvents = function() {
	return [new SubscriptionEvent("positionsLoaded", this.onPositionsLoaded)];
}

// Gets called by map interaction
BrowseByLocationApp.prototype.onMapChanged = function(lat, lng, zoom){
	console.log("BrowseByLocationApp.onMapChanged");
	
	this.query.clearConstraints("context");
	this.query.addConstraint("context", {
		lat: lat,
		lng: lng,
		zoom: zoom
	});
	
	// No call of onQueryChanged to not reset page to 1.
	// (But: That results in no resetting even if new search. Was chosen as it seems more probable the user wants to see mostly the same result page)
	
	// Paging is done via ContextService, and round-trip map loading
	this.storeStateInURL();
}

// Gets called if state / URL params changed
BrowseByLocationApp.prototype.onStateChange = function(event){		
	console.log("BrowseByLocationApp.onStateChange", event);
	
	if (this.isInvalidSWFAddressValue()) {
		return;
	}
	
	this.query.constructFromURLString(SWFAddress.getParameter("query"));
	this.currentPage = BrowseByLocationApp.getPageNumber(SWFAddress.getParameter("page"));
	
	if (this.query.isEmpty()) {
		// TODO Use default start map from within MapWidget
		this.query.addConstraint("context", {
			lat: MapWidget.EUROPE_CENTER_LAT_LNG.lat(),
			lng: MapWidget.EUROPE_CENTER_LAT_LNG.lng(),
			zoom: MapWidget.START_ZOOM_LEVEL
		});
	}
	
	this.serviceConnector.setParams(this.query, this.currentPage, this.itemsPerPage);
	this.updateMap();
}

// Updates map view and loads locations
BrowseByLocationApp.prototype.updateMap = function() {
	if (this.mapWidget != null) {
		var p = this.serviceConnector.params;
		this.mapWidget.setPosition(p.lat, p.lng, p.zoom);
		this.mapWidget.resultOffset = (this.currentPage - 1) * this.itemsPerPage;
		
		// Load specifically as the MapWidgetForServiceConnector interrupts the map-move listener
		this.mapWidget.loadAndCreatePositionsInCurrentArea();
	}
}


BrowseByLocationApp.prototype.onPositionsLoaded = function(event, args) {
	var results = this.serviceConnector.parseLocations(args[0], args[1]);
	this.onResult(results.resultList, results.numResults);
}

BrowseByLocationApp.getPageNumber = function(pageParamString) {
	var pageNum = Number(pageParamString);
	return (Utils.isUndefined(pageNum) || isNaN(pageNum)==-1 || isNaN(pageNum) || pageNum < 1) ? 1 : pageNum;
}

BrowseByLocationApp.prototype.isInvalidSWFAddressValue = function() {
	if (unescape(SWFAddress.getValue()) == this.lastSWFAddressValue) {
		console.warn("Executing the same query twice?");
		return true;
	}	
	this.lastSWFAddressValue = unescape(SWFAddress.getValue());
	return false;
}
