/** * 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.view; import java.util.ArrayList; import java.util.List; import org.onebusaway.transit_data.model.oba.LocalSearchResult; import org.onebusaway.webapp.gwt.common.MapOverlayManager; import org.onebusaway.webapp.gwt.common.widgets.DivPanel; import org.onebusaway.webapp.gwt.common.widgets.DivWidget; import org.onebusaway.webapp.gwt.oba_application.control.CommonControl; import org.onebusaway.webapp.gwt.oba_application.control.StateEvent; import org.onebusaway.webapp.gwt.oba_application.control.StateEventListener; import org.onebusaway.webapp.gwt.oba_application.control.state.SearchStartedState; import org.onebusaway.webapp.gwt.oba_application.control.state.SelectedPlaceChangedState; import org.onebusaway.webapp.gwt.oba_application.control.state.State; import org.onebusaway.webapp.gwt.oba_application.control.state.TripPlansState; import org.onebusaway.webapp.gwt.oba_application.model.TimedLocalSearchResult; import org.onebusaway.webapp.gwt.oba_application.resources.OneBusAwayCssResource; import org.onebusaway.webapp.gwt.oba_application.resources.OneBusAwayStandardResources; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.maps.client.InfoWindow; import com.google.gwt.maps.client.InfoWindowContent; import com.google.gwt.maps.client.MapWidget; import com.google.gwt.maps.client.geom.LatLng; import com.google.gwt.maps.client.geom.Point; import com.google.gwt.maps.client.geom.Size; import com.google.gwt.maps.client.overlay.Icon; import com.google.gwt.maps.client.overlay.Marker; import com.google.gwt.maps.client.overlay.MarkerOptions; import com.google.gwt.maps.client.overlay.Overlay; import com.google.gwt.resources.client.ImageResource; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Widget; public class ActiveResultPresenter implements StateEventListener { private static OneBusAwayCssResource _css = OneBusAwayStandardResources.INSTANCE.getCss(); private FlowPanel _widget = new FlowPanel(); private CommonControl _control; private MapOverlayManager _mapOverlayManager; private List<Overlay> _currentOverlays = new ArrayList<Overlay>(); private List<Widget> _currentDirectionWidgets = new ArrayList<Widget>(); public ActiveResultPresenter() { _widget.addStyleName(_css.ActiveResult()); } public void setControl(CommonControl control) { _control = control; } public void setMapOverlayManager(MapOverlayManager manager) { _mapOverlayManager = manager; } public Widget getWidget() { return _widget; } public void handleUpdate(StateEvent evevent) { State state = evevent.getState(); if (state instanceof SearchStartedState) { reset(); } else if (state instanceof SelectedPlaceChangedState) { SelectedPlaceChangedState placeChange = (SelectedPlaceChangedState) state; reset(); TimedLocalSearchResult result = placeChange.getSelectedResult(); if (result != null) { LocalSearchResult entry = result.getLocalSearchResult(); LatLng point = LatLng.newInstance(entry.getLat(), entry.getLon()); updatWidgetForResult(result); openInfoWindowForResult(result); Marker m15 = new Marker(point, MarkerOptions.newInstance(getStar15Marker())); Marker m20 = new Marker(point, MarkerOptions.newInstance(getStar20Marker())); Marker m30 = new Marker(point, MarkerOptions.newInstance(getStar30Marker())); _mapOverlayManager.addOverlay(m15, 0, 14); _mapOverlayManager.addOverlay(m20, 14, 17); _mapOverlayManager.addOverlay(m30, 17, 20); _mapOverlayManager.setCenter(point); _currentOverlays.add(m15); _currentOverlays.add(m20); _currentOverlays.add(m30); } } else if (state instanceof TripPlansState) { hideInfoWindow(); for (Widget widget : _currentDirectionWidgets) widget.setVisible(false); } } private void reset() { _currentDirectionWidgets.clear(); _widget.clear(); _widget.setVisible(false); hideInfoWindow(); if (!_currentOverlays.isEmpty()) { for (Overlay overlay : _currentOverlays) _mapOverlayManager.removeOverlay(overlay); _currentOverlays.clear(); } } private void hideInfoWindow() { // Hide that info window if need be MapWidget map = _mapOverlayManager.getMapWidget(); InfoWindow window = map.getInfoWindow(); window.close(); } private void updatWidgetForResult(TimedLocalSearchResult result) { fillEntryPanel(result, _widget); _widget.setVisible(true); } private void openInfoWindowForResult(TimedLocalSearchResult result) { FlowPanel panel = new FlowPanel(); fillEntryPanel(result, panel); LocalSearchResult entry = result.getLocalSearchResult(); LatLng point = LatLng.newInstance(entry.getLat(), entry.getLon()); MapWidget map = _mapOverlayManager.getMapWidget(); InfoWindow window = map.getInfoWindow(); window.open(point, new InfoWindowContent(panel)); } private void fillEntryPanel(TimedLocalSearchResult result, FlowPanel panel) { LocalSearchResult entry = result.getLocalSearchResult(); DivPanel namePanel = new DivPanel(); namePanel.addStyleName(_css.ActiveResultNamePanel()); panel.add(namePanel); if (entry.getUrl() == null) { DivWidget name = new DivWidget(entry.getName()); name.addStyleName(_css.ActiveResultName()); namePanel.add(name); } else { Anchor name = new Anchor(entry.getName(), entry.getUrl()); name.addStyleName(_css.ActiveResultName()); name.setTarget("_blank"); namePanel.add(name); } DivWidget address = new DivWidget(getFormatedAddressForEntry(entry)); address.addStyleName(_css.ActiveResultAddress()); panel.add(address); DivWidget phone = new DivWidget(getFormatedPhoneNumber(entry)); phone.addStyleName(_css.ActiveResultPhone()); panel.add(phone); DivPanel ratingPanel = new DivPanel(); ratingPanel.addStyleName(_css.ActiveResultRatingPanel()); panel.add(ratingPanel); if (entry.getRatingUrl() != null) { Image image = new Image(entry.getRatingUrl()); image.setSize("84px", "17px"); image.addStyleName(_css.ActiveResultRatingImage()); ratingPanel.add(image); } else if (entry.getRatingUrlSmall() != null) { Image image = new Image(entry.getRatingUrlSmall()); image.addStyleName(_css.ActiveResultRatingImageSmall()); ratingPanel.add(image); } else { DivWidget rating = new DivWidget(entry.getRating() + "/" + entry.getMaxRating()); ratingPanel.add(rating); } DivWidget time = new DivWidget("Travel time: ~" + (result.getTime() / 60) + " mins"); time.addStyleName(_css.ActiveResultTravelTime()); panel.add(time); _currentDirectionWidgets.add(time); DivPanel directionsPanel = new DivPanel(); directionsPanel.addStyleName(_css.ActiveResultDirectionsPanel()); panel.add(directionsPanel); Anchor directions = new Anchor("Get Directions Using Public Transit"); directions.addStyleName(_css.ActiveResultDirections()); directions.addClickHandler(new DirectionsHandler(entry)); directionsPanel.add(directions); _currentDirectionWidgets.add(directions); } private String getFormatedAddressForEntry(LocalSearchResult entry) { return entry.getAddress() + " " + entry.getCity() + ", " + entry.getRegion() + " " + entry.getZip(); } private String getFormatedPhoneNumber(LocalSearchResult entry) { String number = entry.getPhoneNumber(); if (number.length() == 10) { return "(" + number.substring(0, 3) + ") " + number.substring(3, 6) + "-" + number.substring(6); } else if (number.length() == 7) { return number.substring(0, 3) + "-" + number.substring(3); } else { return number; } } private Icon getStar30Marker() { OneBusAwayStandardResources resources = OneBusAwayStandardResources.INSTANCE; ImageResource r = resources.getStar30(); Icon icon = Icon.newInstance(r.getURL()); icon.setIconSize(Size.newInstance(30, 28)); icon.setIconAnchor(Point.newInstance(15, 14)); return icon; } private Icon getStar20Marker() { OneBusAwayStandardResources resources = OneBusAwayStandardResources.INSTANCE; ImageResource r = resources.getStar20(); Icon icon = Icon.newInstance(r.getURL()); icon.setIconSize(Size.newInstance(20, 19)); icon.setIconAnchor(Point.newInstance(10, 10)); return icon; } private Icon getStar15Marker() { OneBusAwayStandardResources resources = OneBusAwayStandardResources.INSTANCE; ImageResource r = resources.getStar15(); Icon icon = Icon.newInstance(r.getURL()); icon.setIconSize(Size.newInstance(15, 14)); icon.setIconAnchor(Point.newInstance(8, 7)); return icon; } private final class DirectionsHandler implements ClickHandler { private LocalSearchResult entry; private DirectionsHandler(LocalSearchResult entry) { this.entry = entry; } public void onClick(ClickEvent arg0) { _control.getDirectionsToPlace(entry); } } }