package net.osmand.plus;
import android.content.Context;
import net.osmand.StateChangedListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class ApplicationMode {
private static Map<String, Set<ApplicationMode>> widgetsVisibilityMap = new LinkedHashMap<>();
private static Map<String, Set<ApplicationMode>> widgetsAvailabilityMap = new LinkedHashMap<>();
private static List<ApplicationMode> values = new ArrayList<>();
private static List<ApplicationMode> cachedFilteredValues = new ArrayList<>();
/*
* DEFAULT("Browse map"), CAR("Car"), BICYCLE("Bicycle"), PEDESTRIAN("Pedestrian");
*/
public static final ApplicationMode DEFAULT = create(R.string.app_mode_default, "default").speed(1.5f, 5).arrivalDistance(90).defLocation().
icon(R.drawable.map_world_globe_dark, R.drawable.ic_world_globe_dark).reg();
public static final ApplicationMode CAR = create(R.string.app_mode_car, "car").speed(15.3f, 35).carLocation().
icon(R.drawable.map_action_car_dark, R.drawable.ic_action_car_dark).reg();
public static final ApplicationMode BICYCLE = create(R.string.app_mode_bicycle, "bicycle").speed(5.5f, 15).arrivalDistance(60).bicycleLocation().
icon(R.drawable.map_action_bicycle_dark, R.drawable.ic_action_bicycle_dark).reg();
public static final ApplicationMode PEDESTRIAN = create(R.string.app_mode_pedestrian, "pedestrian").speed(1.5f, 5).arrivalDistance(45).
icon(R.drawable.map_action_pedestrian_dark, R.drawable.ic_action_pedestrian_dark).reg();
public static final ApplicationMode AIRCRAFT = create(R.string.app_mode_aircraft, "aircraft").speed(40f, 100).carLocation().
icon(R.drawable.map_action_aircraft, R.drawable.ic_action_aircraft).reg();
public static final ApplicationMode BOAT = create(R.string.app_mode_boat, "boat").speed(5.5f, 20).carLocation().
icon(R.drawable.map_action_sail_boat_dark, R.drawable.ic_action_sail_boat_dark).reg();
public static final ApplicationMode HIKING = create(R.string.app_mode_hiking, "hiking").speed(1.5f, 5).parent(PEDESTRIAN).
icon(R.drawable.map_action_trekking_dark, R.drawable.ic_action_trekking_dark).reg();
public static final ApplicationMode MOTORCYCLE = create(R.string.app_mode_motorcycle, "motorcycle").speed(15.3f, 40).
carLocation().parent(CAR).
icon(R.drawable.map_action_motorcycle_dark, R.drawable.ic_action_motorcycle_dark).reg();
public static final ApplicationMode TRUCK = create(R.string.app_mode_truck, "truck").speed(15.3f, 40).
carLocation().parent(CAR).
icon(R.drawable.map_action_truck_dark, R.drawable.ic_action_truck_dark).reg();
public static final ApplicationMode BUS = create(R.string.app_mode_bus, "bus").speed(15.3f, 40).
carLocation().parent(CAR).
icon(R.drawable.map_action_bus_dark, R.drawable.ic_action_bus_dark).reg();
public static final ApplicationMode TRAIN = create(R.string.app_mode_train, "train").speed(25f, 40).
carLocation().icon(R.drawable.map_action_train, R.drawable.ic_action_train).reg();
static {
ApplicationMode[] exceptDefault = new ApplicationMode[]{CAR, PEDESTRIAN, BICYCLE, BOAT, AIRCRAFT, BUS, TRAIN};
ApplicationMode[] exceptPedestrianAndDefault = new ApplicationMode[]{CAR, BICYCLE, BOAT, AIRCRAFT, BUS, TRAIN};
ApplicationMode[] exceptAirBoatDefault = new ApplicationMode[]{CAR, BICYCLE, PEDESTRIAN};
ApplicationMode[] pedestrian = new ApplicationMode[]{PEDESTRIAN};
ApplicationMode[] pedestrianBicycle = new ApplicationMode[]{PEDESTRIAN, BICYCLE};
ApplicationMode[] all = null;
ApplicationMode[] none = new ApplicationMode[]{};
// left
regWidgetVisibility("next_turn", exceptPedestrianAndDefault);
regWidgetVisibility("next_turn_small", pedestrian);
regWidgetVisibility("next_next_turn", exceptPedestrianAndDefault);
regWidgetAvailability("next_turn", exceptDefault);
regWidgetAvailability("next_turn_small", exceptDefault);
regWidgetAvailability("next_next_turn", exceptDefault);
// right
regWidgetVisibility("intermediate_distance", all);
regWidgetVisibility("distance", all);
regWidgetVisibility("time", all);
regWidgetVisibility("speed", exceptPedestrianAndDefault);
regWidgetVisibility("max_speed", CAR);
regWidgetVisibility("altitude", pedestrianBicycle);
regWidgetVisibility("gps_info", none);
regWidgetAvailability("intermediate_distance", all);
regWidgetAvailability("distance", all);
regWidgetAvailability("time", all);
regWidgetAvailability("map_marker_1st", none);
regWidgetAvailability("map_marker_2nd", none);
// top
regWidgetVisibility("config", none);
regWidgetVisibility("layers", none);
regWidgetVisibility("compass", none);
regWidgetVisibility("street_name", exceptAirBoatDefault);
regWidgetVisibility("back_to_location", all);
regWidgetVisibility("monitoring_services", none);
regWidgetVisibility("bgService", none);
}
private static class ApplicationModeBuilder {
private ApplicationMode applicationMode;
public ApplicationMode reg() {
values.add(applicationMode);
return applicationMode;
}
public ApplicationModeBuilder icon(int mapIcon, int smallIconDark) {
applicationMode.mapIconId = mapIcon;
applicationMode.smallIconDark = smallIconDark;
return this;
}
public ApplicationModeBuilder carLocation() {
applicationMode.bearingIconDay = R.drawable.map_car_bearing;
applicationMode.bearingIconNight = R.drawable.map_car_bearing_night;
applicationMode.headingIconDay = R.drawable.map_car_location_view_angle;
applicationMode.headingIconNight = R.drawable.map_car_location_view_angle_night;
applicationMode.locationIconDay = R.drawable.map_car_location;
applicationMode.locationIconNight = R.drawable.map_car_location_night;
return this;
}
public ApplicationModeBuilder parent(ApplicationMode parent) {
applicationMode.parent = parent;
return this;
}
public ApplicationModeBuilder bicycleLocation() {
applicationMode.bearingIconDay = R.drawable.map_bicycle_bearing;
applicationMode.bearingIconNight = R.drawable.map_bicycle_bearing_night;
applicationMode.headingIconDay = R.drawable.map_bicycle_location_view_angle;
applicationMode.headingIconNight = R.drawable.map_bicycle_location_view_angle_night;
applicationMode.locationIconDay = R.drawable.map_bicycle_location;
applicationMode.locationIconNight = R.drawable.map_bicycle_location_night;
return this;
}
public ApplicationModeBuilder defLocation() {
applicationMode.bearingIconDay = R.drawable.map_pedestrian_bearing;
applicationMode.bearingIconNight = R.drawable.map_pedestrian_bearing_night;
applicationMode.headingIconDay = R.drawable.map_default_location_view_angle;
applicationMode.headingIconNight = R.drawable.map_default_location_view_angle_night;
applicationMode.locationIconDay = R.drawable.map_pedestrian_location;
applicationMode.locationIconNight = R.drawable.map_pedestrian_location_night;
return this;
}
public ApplicationModeBuilder speed(float defSpeed, int distForTurn) {
applicationMode.defaultSpeed = defSpeed;
applicationMode.minDistanceForTurn = distForTurn;
return this;
}
public ApplicationModeBuilder arrivalDistance(int arrivalDistance) {
applicationMode.arrivalDistance = arrivalDistance;
return this;
}
}
private static ApplicationModeBuilder create(int key, String stringKey) {
ApplicationModeBuilder builder = new ApplicationModeBuilder();
builder.applicationMode = new ApplicationMode(key, stringKey);
return builder;
}
private ApplicationMode(int key, String stringKey) {
this.key = key;
this.stringKey = stringKey;
}
public static List<ApplicationMode> values(OsmandSettings settings) {
if (cachedFilteredValues.isEmpty()) {
if (listener == null) {
listener = new StateChangedListener<String>() {
@Override
public void stateChanged(String change) {
cachedFilteredValues = new ArrayList<ApplicationMode>();
}
};
settings.AVAILABLE_APP_MODES.addListener(listener);
}
String available = settings.AVAILABLE_APP_MODES.get();
cachedFilteredValues = new ArrayList<ApplicationMode>();
for (ApplicationMode v : values) {
if (available.indexOf(v.getStringKey() + ",") != -1 || v == DEFAULT) {
cachedFilteredValues.add(v);
}
}
}
return cachedFilteredValues;
}
public static List<ApplicationMode> allPossibleValues() {
return new ArrayList<ApplicationMode>(values);
}
// returns modifiable ! Set<ApplicationMode> to exclude non-wanted derived
public static Set<ApplicationMode> regWidgetVisibility(String widgetId, ApplicationMode... am) {
HashSet<ApplicationMode> set = new HashSet<>();
if (am == null) {
set.addAll(values);
} else {
Collections.addAll(set, am);
}
for (ApplicationMode m : values) {
// add derived modes
if (set.contains(m.getParent())) {
set.add(m);
}
}
widgetsVisibilityMap.put(widgetId, set);
return set;
}
public boolean isWidgetCollapsible(String key) {
return false;
}
public boolean isWidgetVisible(String key) {
Set<ApplicationMode> set = widgetsVisibilityMap.get(key);
if (set == null) {
return false;
}
return set.contains(this);
}
public static Set<ApplicationMode> regWidgetAvailability(String widgetId, ApplicationMode... am) {
HashSet<ApplicationMode> set = new HashSet<>();
if (am == null) {
set.addAll(values);
} else {
Collections.addAll(set, am);
}
for (ApplicationMode m : values) {
// add derived modes
if (set.contains(m.getParent())) {
set.add(m);
}
}
widgetsAvailabilityMap.put(widgetId, set);
return set;
}
public boolean isWidgetAvailable(String key) {
Set<ApplicationMode> set = widgetsAvailabilityMap.get(key);
if (set == null) {
return true;
}
return set.contains(this);
}
public static List<ApplicationMode> getModesDerivedFrom(ApplicationMode am) {
List<ApplicationMode> list = new ArrayList<ApplicationMode>();
for (ApplicationMode a : values) {
if (a == am || a.getParent() == am) {
list.add(a);
}
}
return list;
}
public ApplicationMode getParent() {
return parent;
}
public int getSmallIconDark() {
return smallIconDark;
}
public boolean hasFastSpeed() {
return getDefaultSpeed() > 10;
}
public int getResourceBearingDay() {
return bearingIconDay;
}
public int getResourceBearingNight() {
//return bearingIconDay;
return bearingIconNight;
}
public int getResourceHeadingDay() {
return headingIconDay;
}
public int getResourceHeadingNight() {
return headingIconNight;
}
public int getResourceLocationDay() {
return locationIconDay;
}
public int getResourceLocationNight() {
//return locationIconDay;
return locationIconNight;
}
public String getStringKey() {
return stringKey;
}
public int getMapIconId() {
return mapIconId;
}
public int getStringResource() {
return key;
}
public String toHumanString(Context ctx) {
return ctx.getString(key);
}
public String toHumanStringCtx(Context ctx) {
return ctx.getString(key);
}
public static ApplicationMode valueOfStringKey(String key, ApplicationMode def) {
for (ApplicationMode p : values) {
if (p.getStringKey().equals(key)) {
return p;
}
}
return def;
}
public float getDefaultSpeed() {
return defaultSpeed;
}
public int getMinDistanceForTurn() {
return minDistanceForTurn;
}
public int getArrivalDistance() {
return arrivalDistance;
}
public boolean isDerivedRoutingFrom(ApplicationMode mode) {
return this == mode || getParent() == mode;
}
private final int key;
private final String stringKey;
private ApplicationMode parent;
private int mapIconId = R.drawable.map_world_globe_dark;
private int smallIconDark = R.drawable.ic_world_globe_dark;
private float defaultSpeed = 10f;
private int minDistanceForTurn = 50;
private int arrivalDistance = 90;
private int bearingIconDay = R.drawable.map_pedestrian_bearing;
private int bearingIconNight = R.drawable.map_pedestrian_bearing_night;
private int headingIconDay = R.drawable.map_pedestrian_location_view_angle;
private int headingIconNight = R.drawable.map_pedestrian_location_view_angle_night;
private int locationIconDay = R.drawable.map_pedestrian_location;
private int locationIconNight = R.drawable.map_pedestrian_location_night;
private static StateChangedListener<String> listener;
}