/**
* Copyright (C) 2011 Brian Ferris <bdferris@onebusaway.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onebusaway.webapp.gwt.oba_application.control;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.onebusaway.geospatial.model.CoordinateBounds;
import org.onebusaway.transit_data.model.oba.LocalSearchResult;
import org.onebusaway.transit_data.model.oba.MinTransitTimeResult;
import org.onebusaway.transit_data.model.oba.MinTravelTimeToStopsBean;
import org.onebusaway.transit_data.model.oba.TimedPlaceBean;
import org.onebusaway.transit_data.model.tripplanning.TransitShedConstraintsBean;
import org.onebusaway.webapp.gwt.common.model.ModelEventSink;
import org.onebusaway.webapp.gwt.oba_application.control.state.SearchCompleteState;
import org.onebusaway.webapp.gwt.oba_application.control.state.SearchProgressState;
import org.onebusaway.webapp.gwt.oba_application.model.ResultsModel;
import org.onebusaway.webapp.gwt.oba_application.model.TimedLocalSearchResult;
import org.onebusaway.webapp.gwt.oba_application.search.LocalSearchCallback;
import org.onebusaway.webapp.gwt.oba_application.search.LocalSearchProvider;
import org.onebusaway.webapp.gwt.where_library.rpc.WebappServiceAsync;
import com.google.gwt.user.client.rpc.AsyncCallback;
public class LocalSearchHandler implements LocalSearchCallback {
private Map<String, LocalSearchResult> _placeResults = new HashMap<String, LocalSearchResult>();
private PlaceHandler _placeHandler = new PlaceHandler();
private LocalSearchProvider _searchProvider;
private ModelEventSink<StateEvent> _events;
private ResultsModel _model;
private TransitShedConstraintsBean _constraints;
private MinTravelTimeToStopsBean _travelTimes;
private List<CoordinateBounds> _searchGrid;
private List<String> _queries = new ArrayList<String>();
private List<String> _categories = new ArrayList<String>();
private int _queryIndex = 0;
private int _gridIndex = 0;
private int _searchCount = 0;
private boolean _complete = false;
private String _resultId;
public LocalSearchHandler(TransitShedConstraintsBean constraints,
MinTransitTimeResult result) {
_constraints = constraints;
_travelTimes = result.getMinTravelTimeToStops();
_searchGrid = result.getSearchGrid();
_resultId = Long.toString(System.currentTimeMillis());
for (CoordinateBounds bounds : _searchGrid)
System.out.println(bounds);
}
public void setEventSink(ModelEventSink<StateEvent> events) {
_events = events;
}
public void setLocalSearchProvider(LocalSearchProvider searchProvider) {
_searchProvider = searchProvider;
}
public void setModel(ResultsModel model) {
_model = model;
}
public void addQuery(String query, String category) {
_queries.add(query);
_categories.add(category);
}
public void run() {
for (int i = 0; i < 2; i++)
nextGrid();
}
public void onSuccess(List<LocalSearchResult> results) {
if (results.isEmpty()) {
_searchCount++;
nextGrid();
} else {
for (LocalSearchResult result : results)
_placeResults.put(result.getId(), result);
WebappServiceAsync service = WebappServiceAsync.SERVICE;
service.getLocalPathsToStops(_constraints.getConstraints(), _travelTimes,
results, _placeHandler);
}
}
public void onFailure(Throwable ex) {
ex.printStackTrace();
}
private void nextGrid() {
if (_gridIndex == _searchGrid.size()) {
_queryIndex++;
_gridIndex = 0;
}
if (checkCompletion())
return;
CoordinateBounds bounds = _searchGrid.get(_gridIndex++);
String query = _queries.get(_queryIndex);
String category = _categories.get(_queryIndex);
_searchProvider.search(bounds, query, category, this);
}
private boolean checkCompletion() {
double total = _searchGrid.size() * _queries.size();
if (_gridIndex < _searchGrid.size() && _queryIndex < _queries.size()) {
double processed = _queryIndex * _searchGrid.size() + _gridIndex;
_events.fireModelChange(new StateEvent(new SearchProgressState(processed
/ total)));
return false;
}
if (!_complete && _searchCount == total) {
_complete = true;
_events.fireModelChange(new StateEvent(new SearchCompleteState()));
}
return true;
}
private class PlaceHandler implements AsyncCallback<List<TimedPlaceBean>> {
public void onSuccess(List<TimedPlaceBean> beans) {
List<TimedLocalSearchResult> results = new ArrayList<TimedLocalSearchResult>(
beans.size());
for (final TimedPlaceBean bean : beans) {
final LocalSearchResult result = _placeResults.get(bean.getPlaceId());
TimedLocalSearchResult r = new TimedLocalSearchResult(_resultId,
result, bean);
results.add(r);
}
_model.addEntries(results);
_searchCount++;
nextGrid();
}
public void onFailure(Throwable ex) {
ex.printStackTrace();
_searchCount++;
nextGrid();
}
}
}