package com.njtransit;
import android.app.Application;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import com.njtransit.domain.IService;
import com.njtransit.domain.Preferences;
import com.njtransit.domain.Station;
import com.njtransit.utils.Distance;
import java.util.*;
/** Shared state management */
public class SchedulerApplication extends Application implements
LocationListener {
private Location lastKnownLocation;
private Station arrivalStation, departureStation;
private Calendar departureDate;
private int stationOrderType = 1;
private Preferences preferences;
private DeviceInformation deviceInformation;
private static String LOCATION_PROVIDER = LocationManager.GPS_PROVIDER;
private List<Station> stations;
private Map<Integer, IService> services;
@SuppressWarnings("unused")
private LocationManager locationManager;
private DatabaseAdapter adapter;
/**
*
* @param location
* can be null, if so defaults to lastKnownLocation
* @return
*/
public Map<Station, Double> findClosestStation(Location location) {
Map<Station, Double> s = findClosestStations(location, 1);
if (s == null || s.isEmpty()) {
return Collections.<Station, Double> emptyMap();
}
return s;
}
/**
* This is a weak algorithm, if performance is a concern we should address
* it.
*
* @param location
* @param max
* @return Key-Value collection of station to relative metered distances
*/
public Map<Station, Double> findClosestStations(Location location, int max) {
if (location == null)
location = lastKnownLocation;
if (location == null || stations == null || stations.isEmpty())
return new HashMap<Station, Double>(2) {
private static final long serialVersionUID = 1L;
{
put(getStations().get(0), 100.0);
put(getStations().get(1), 200.0);
}
};
TreeMap<Double, Station> closest = new TreeMap<Double, Station>();
for (Station s : stations) {
double dist = Distance.greatCircle(location.getLatitude(), location
.getLongitude(), s.getLatitude(), s.getLongitude());
if (closest.size() < max) {
closest.put(dist, s);
} else {
for (Double oldDist : closest.keySet()) {
if (dist < oldDist) {
closest.remove(oldDist);
closest.put(dist, s);
break;
}
}
}
}
Map<Station, Double> inverted = new HashMap<Station, Double>(closest
.size());
for (Map.Entry<Double, Station> e : closest.entrySet()) {
inverted.put(e.getValue(), e.getKey());
}
return inverted;
}
public DatabaseAdapter getAdapter() {
return adapter;
}
public Station getArrivalStation() {
return arrivalStation;
}
public Calendar getDepartureDate() {
return departureDate;
}
public Station getDepartureStation() {
return departureStation;
}
public DeviceInformation getDeviceInformation() {
return deviceInformation;
}
public Location getLastKnownLocation() {
return lastKnownLocation;
}
public LocationManager getLocations() {
return (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
public Preferences getPreferences() {
if (preferences == null) {
preferences = new Preferences();
}
return preferences;
}
public Map<Integer, IService> getServices() {
return services;
}
public Station getStation(Integer id) {
for (Station s : getStations()) {
if (s.getId().equals(id)) {
return s;
}
}
return null;
}
public int getStationOrderType() {
return stationOrderType;
}
public List<Station> getStations() {
return stations;
}
@Override
public void onCreate() {
super.onCreate();
deviceInformation = DeviceInformation.getDeviceInformation(this);
setLastKnownLocation(getLocations().getLastKnownLocation(
LOCATION_PROVIDER));
if (getLastKnownLocation() == null) {
getLocations().requestLocationUpdates(LOCATION_PROVIDER, 3600000,
0, this);
new Thread() {
public void run() {
try {
Thread.sleep(20000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
getLocations().removeUpdates(SchedulerApplication.this);
}
}.start();
}
}
@Override
public void onLocationChanged(Location l) {
setLastKnownLocation(l);
// getTabHost().setCurrentTab(getTabHost().getCurrentTab());
getLocations().removeUpdates(this);
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public void reverseTrip() {
Station tmp = departureStation;
departureStation = arrivalStation;
arrivalStation = tmp;
}
public void setAdapter(DatabaseAdapter adapter) {
this.adapter = adapter;
}
public void setArrivalStation(Station arrivalStation) {
this.arrivalStation = arrivalStation;
}
public void setDepartureDate(Calendar departureDate) {
this.departureDate = departureDate;
}
public void setDepartureStation(Station departureStation) {
this.departureStation = departureStation;
}
public void setLastKnownLocation(Location lastKnownLocation) {
this.lastKnownLocation = lastKnownLocation;
}
public void setPreferences(Preferences preferences) {
this.preferences = preferences;
}
public void setServices(List<IService> services) {
this.services = new HashMap<Integer, IService>();
for (IService s : services) {
this.services.put(s.getId(), s);
}
}
public void setStationOrderType(int stationOrderType) {
this.stationOrderType = stationOrderType;
}
public void setStations(ArrayList<Station> stations) {
this.stations = stations;
}
}