Package org.onebusaway.webapp.gwt.notification

Source Code of org.onebusaway.webapp.gwt.notification.NotificationWidgetPage

/**
* 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.notification;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.onebusaway.presentation.client.RoutePresenter;
import org.onebusaway.transit_data.model.ArrivalAndDepartureBean;
import org.onebusaway.transit_data.model.RouteBean;
import org.onebusaway.transit_data.model.StopBean;
import org.onebusaway.transit_data.model.StopWithArrivalsAndDeparturesBean;
import org.onebusaway.transit_data.model.trips.TripBean;
import org.onebusaway.webapp.gwt.common.PageException;
import org.onebusaway.webapp.gwt.common.context.Context;
import org.onebusaway.webapp.gwt.common.context.ContextManager;
import org.onebusaway.webapp.gwt.common.widgets.DivPanel;
import org.onebusaway.webapp.gwt.common.widgets.SpanWidget;
import org.onebusaway.webapp.gwt.where_library.WhereLibrary;
import org.onebusaway.webapp.gwt.where_library.pages.WhereCommonPage;
import org.onebusaway.webapp.gwt.where_library.resources.WhereLibraryStandardStopCssResource;
import org.onebusaway.webapp.gwt.where_library.rpc.WebappServiceAsync;
import org.onebusaway.webapp.gwt.where_library.view.ArrivalsAndDeparturesPresentaion;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

public class NotificationWidgetPage extends WhereCommonPage {

  private static DateTimeFormat _timeFormat = DateTimeFormat.getFormat("hh:mm");

  private static NotificationCssResource _notificationCss = NotificationResources.INSTANCE.getCss();

  private static WhereLibraryStandardStopCssResource _stopCss = WhereLibrary.INSTANCE.getStandardStopCss();

  private static final int DEFAULT_NOTIFY_MINUTES_BEFORE = 5;

  private static final String PARAM_TRIP_ID = "tripId";

  private static final String PARAM_STOP_ID = "stopId";

  private NotificationStateDAO _dao = new NotificationStateDAO();

  private DataRequestTimer _dataRequestTimer = new DataRequestTimer();

  private ArrivalsAndDeparturesHandler _arrivalsAndDeparturesHandler = new ArrivalsAndDeparturesHandler();

  private NotificationTimer _notificationTimer = new NotificationTimer();

  private String _tripId;

  private String _stopId;

  private DivPanel _stopPanel = new DivPanel(_stopCss.arrivalsStopInfo());

  private Grid _arrivalsAndDeparturesTable = new Grid(2, 3);

  private ArrivalsAndDeparturesPresentaion _methods;

  private List<NotificationMethod> _notificationMethods = new ArrayList<NotificationMethod>();

  private TextBox _minutesBeforeTextBox;

  private int _minutesBefore = DEFAULT_NOTIFY_MINUTES_BEFORE;

  private ArrivalAndDepartureBean _departureBean = null;

  public NotificationWidgetPage(ContextManager contextManager) {
    _methods = new ArrivalsAndDeparturesPresentaion(true);
    _notificationMethods.add(new SoundNotificationMethod());
    _notificationMethods.add(new PopupNotificationMethod());
  }

  public Widget create(final Context context) throws PageException {

    prepArrivalsAndDeparturesTable();

    DivPanel panel = new DivPanel();
    panel.addStyleName("panel");
    panel.add(_stopPanel);
    panel.add(_arrivalsAndDeparturesTable);

    DivPanel notificationOptionsPanel = new DivPanel(
        _notificationCss.notificationOptions());
    panel.add(notificationOptionsPanel);

    DivPanel minutesRow = getNotificationMinutesBeforePanel();
    notificationOptionsPanel.add(minutesRow);

    DivPanel methodsPanel = getMethodsPanel();
    notificationOptionsPanel.add(methodsPanel);

    // DivPanel saveDefaultsPanel = getSaveDefaultsPanel();
    // notificationOptionsPanel.add(saveDefaultsPanel);

    update(context);

    return panel;
  }

  private DivPanel getNotificationMinutesBeforePanel() {

    DivPanel minutesRow = new DivPanel(
        _notificationCss.notificationMinutesBeforePanel());

    minutesRow.add(new SpanWidget("Notify me"));

    _minutesBeforeTextBox = new TextBox();
    _minutesBeforeTextBox.addStyleName(_notificationCss.notificationMinutesBeforeTextBox());
    _minutesBeforeTextBox.setText(Integer.toString(DEFAULT_NOTIFY_MINUTES_BEFORE));
    MinutesBeforeHandler handler = new MinutesBeforeHandler();
    _minutesBeforeTextBox.addKeyUpHandler(handler);

    minutesRow.add(_minutesBeforeTextBox);

    minutesRow.add(new SpanWidget("minutes before arrival"));
    return minutesRow;
  }

  private DivPanel getMethodsPanel() {
    DivPanel methodsPanel = new DivPanel(
        _notificationCss.notificationMethodsPanel());

    for (NotificationMethod method : _notificationMethods) {
      DivPanel row = new DivPanel(_notificationCss.notificationMethodPanel());
      if (method.getSelectionRow(row))
        methodsPanel.add(row);
    }

    return methodsPanel;
  }

  private DivPanel getSaveDefaultsPanel() {
    DivPanel panel = new DivPanel(_notificationCss.notificationDefaultsPanel());
    panel.add(new SpanWidget("Make this the default for:",
        _notificationCss.notificationDefaultsText()));

    Button justThisStop = new Button("This Stop");
    justThisStop.addStyleName(_notificationCss.notificationDefaultsButton());
    justThisStop.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent arg0) {
        NotificationState state = getState();
        _dao.setState(_stopId, state, false);
      }
    });
    panel.add(justThisStop);

    Button allStops = new Button("All Stops");
    allStops.addStyleName(_notificationCss.notificationDefaultsButton());
    allStops.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent arg0) {
        NotificationState state = getState();
        _dao.setState(_stopId, state, true);
      }
    });
    panel.add(allStops);

    return panel;
  }

  @Override
  public Widget update(Context context) throws PageException {

    _tripId = context.getParam(PARAM_TRIP_ID);
    _stopId = context.getParam(PARAM_STOP_ID);

    System.out.println("tripId=" + _tripId + " stopId=" + _stopId);

    if (_tripId == null || _stopId == null) {
      _dataRequestTimer.cancel();
    } else {

      NotificationState state = _dao.getState(_stopId);
      _minutesBeforeTextBox.setText(Integer.toString(state.getMinutesBefore()));
      _minutesBefore = state.getMinutesBefore();

      Map<String, NotificationMethodState> methodStates = new HashMap<String, NotificationMethodState>();
      for (NotificationMethodState methodState : state.getMethodStates())
        methodStates.put(methodState.getId(), methodState);

      for (NotificationMethod method : _notificationMethods) {
        NotificationMethodState methodState = methodStates.get(method.getId());
        if (methodState != null)
          method.loadFromState(methodState);
      }

      _dataRequestTimer.run();
      _dataRequestTimer.scheduleRepeating(60 * 1000);
      refreshAlarm();
    }

    return null;
  }

  private void prepArrivalsAndDeparturesTable() {
    _arrivalsAndDeparturesTable.addStyleName(_stopCss.arrivalsTable());

    _arrivalsAndDeparturesTable.getRowFormatter().addStyleName(0,
        _stopCss.arrivalsHeader());
    _arrivalsAndDeparturesTable.getRowFormatter().addStyleName(1,
        _stopCss.arrivalsRow());

    _arrivalsAndDeparturesTable.getCellFormatter().addStyleName(0, 0,
        _stopCss.arrivalsRouteColumn());
    _arrivalsAndDeparturesTable.getCellFormatter().addStyleName(0, 1,
        _stopCss.arrivalsDestinationColumn());
    _arrivalsAndDeparturesTable.getCellFormatter().addStyleName(0, 2,
        _stopCss.arrivalsStatusColumn());

    _arrivalsAndDeparturesTable.getCellFormatter().addStyleName(1, 0,
        _stopCss.arrivalsRouteEntry());
    _arrivalsAndDeparturesTable.getCellFormatter().setStyleName(1, 2,
        _stopCss.arrivalsStatusEntry());

    _arrivalsAndDeparturesTable.setText(0, 0, "route");
    _arrivalsAndDeparturesTable.setText(0, 1, "destination");
    _arrivalsAndDeparturesTable.setText(0, 2, "minutes");

    _arrivalsAndDeparturesTable.setText(1, 1, "loading arrival data...");
  }

  private void refreshInterface(StopWithArrivalsAndDeparturesBean bean) {
    updateStopPanel(bean.getStop());
    for (ArrivalAndDepartureBean dep : bean.getArrivalsAndDepartures()) {
      TripBean trip = dep.getTrip();
      if (trip.getId().equals(_tripId)) {
        updateArrivalsAndDeparturePanel(dep);
        _departureBean = dep;
      }
    }
  }

  private void updateStopPanel(StopBean stop) {
    _stopPanel.clear();

    String url = "index.html#p(index)m(location)lat(" + stop.getLat() + ")lon("
        + stop.getLon() + ")accuracy(8)stop(" + stop.getId() + ")";

    DivPanel namePanel = new DivPanel(_stopCss.arrivalsStopAddress());
    _stopPanel.add(namePanel);

    Anchor nameLink = new Anchor(stop.getName(), url);
    namePanel.add(nameLink);

    DivPanel numberPanel = new DivPanel(_stopCss.arrivalsStopNumber());
    _stopPanel.add(numberPanel);
    Anchor numberLink = new Anchor("Stop # " + stop.getCode() + " - "
        + stop.getDirection() + " bound", url);
    numberPanel.add(numberLink);
  }

  private void updateArrivalsAndDeparturePanel(ArrivalAndDepartureBean bean) {

    long now = System.currentTimeMillis();

    TripBean trip = bean.getTrip();
    RouteBean route = trip.getRoute();
    String routeName = RoutePresenter.getNameForRoute(route);
    _arrivalsAndDeparturesTable.setText(1, 0, routeName);

    if (RoutePresenter.isRouteNameLong(routeName))
      _arrivalsAndDeparturesTable.getCellFormatter().addStyleName(1, 0,
          _stopCss.arrivalsRouteLongNameEntry());

    DivPanel divPanel = new DivPanel();

    DivPanel destinationPanel = new DivPanel(
        _stopCss.arrivalsDestinationEntry());
    divPanel.add(destinationPanel);
    String href = "trip.action?id=" + trip.getId() + "&stop="
        + bean.getStop().getId();
    destinationPanel.add(new Anchor(trip.getTripHeadsign(), href));

    DivPanel timeAndStatusPanel = new DivPanel(_stopCss.arrivalsTimePanel());
    divPanel.add(timeAndStatusPanel);
    String time = _timeFormat.format(new Date(bean.computeBestDepartureTime()));
    timeAndStatusPanel.add(new SpanWidget(time, _stopCss.arrivalsTimeEntry()));
    timeAndStatusPanel.add(new SpanWidget(" - "));
    String arrivalStatusLabelStyle = _methods.getStatusLabelStyle(bean);
    timeAndStatusPanel.add(new SpanWidget(_methods.getStatusLabel(bean),
        arrivalStatusLabelStyle));
    _arrivalsAndDeparturesTable.setWidget(1, 1, divPanel);

    _arrivalsAndDeparturesTable.getCellFormatter().setStyleName(1, 2,
        _stopCss.arrivalsStatusEntry());
    _arrivalsAndDeparturesTable.getCellFormatter().addStyleName(1, 2,
        arrivalStatusLabelStyle);
    if (_methods.isNow(bean))
      _arrivalsAndDeparturesTable.getCellFormatter().addStyleName(1, 2,
          _stopCss.arrivalStatusNow());

    _arrivalsAndDeparturesTable.setText(1, 2, _methods.getMinutesLabel(bean));
  }

  private void refreshAlarm() {

    System.out.println("reseting alarm");
    _notificationTimer.cancel();
    _minutesBefore = getMinutesBefore();

    if (_minutesBefore < 0) {
      System.out.println("invalid minutes before: " + _minutesBefore);
      _minutesBeforeTextBox.addStyleName("invalidValue");
    } else {
      System.out.println("good minutes before: " + _minutesBefore);
      _minutesBeforeTextBox.removeStyleName("invalidValue");
      _notificationTimer.schedule(5 * 1000);
    }
  }

  private int getMinutesBefore() {
    String minutesBeforeString = _minutesBeforeTextBox.getText();
    System.out.println("minutes before raw=" + minutesBeforeString);
    try {
      return Integer.parseInt(minutesBeforeString);
    } catch (NumberFormatException ex) {
      return -1;
    }
  }

  private void checkAlarm() {
    System.out.println("checking alarm");
    if (_departureBean != null) {
      System.out.println("we have a bean");
      if (_departureBean.computeBestDepartureTime() - _minutesBefore * 60
          * 1000 < System.currentTimeMillis()) {
        System.out.println("we have an alarm!");
        _notificationTimer.cancel();
        NotificationContextImpl context = new NotificationContextImpl();
        for (NotificationMethod method : _notificationMethods)
          method.handleNotification(context);
        return;
      }
    }
    _notificationTimer.schedule(30 * 1000);
  }

  private void resetNotifications() {
    System.out.println("notification reset");
    for (NotificationMethod method : _notificationMethods)
      method.handleNotificationReset();
  }

  private NotificationState getState() {
    NotificationState state = new NotificationState();
    state.setMinutesBefore(_minutesBefore);
    for (NotificationMethod method : _notificationMethods) {
      NotificationMethodState methodState = new NotificationMethodState();
      methodState.setId(method.getId());
      methodState.setEnabled(method.isEnabled());
      state.getMethodStates().add(methodState);
    }
    return state;
  }

  /****
   * Internal Classes
   ****/

  private class DataRequestTimer extends Timer {
    @Override
    public void run() {
      WebappServiceAsync service = WebappServiceAsync.SERVICE;
      service.getArrivalsByStopId(_stopId, _arrivalsAndDeparturesHandler);
    }
  }

  private class ArrivalsAndDeparturesHandler implements
      AsyncCallback<StopWithArrivalsAndDeparturesBean> {

    public void onSuccess(StopWithArrivalsAndDeparturesBean bean) {
      refreshInterface(bean);
    }

    public void onFailure(Throwable arg0) {

    }
  }

  private class MinutesBeforeHandler implements KeyUpHandler {
    public void onKeyUp(KeyUpEvent arg0) {
      refreshAlarm();
    }
  }

  private class NotificationTimer extends Timer {
    @Override
    public void run() {
      checkAlarm();
    }
  }

  private class NotificationContextImpl implements NotificationContext {
    public void reset() {
      resetNotifications();
    }
  }
}
TOP

Related Classes of org.onebusaway.webapp.gwt.notification.NotificationWidgetPage

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.