/* This program is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package org.opentripplanner.routing.edgetype;
import java.util.Map;
import java.util.HashMap;
import java.util.EnumSet;
import org.opentripplanner.routing.core.TraverseMode;
import org.opentripplanner.routing.core.TraverseModeSet;
/**
* Who can traverse a street in a single direction.
*/
public enum StreetTraversalPermission {
NONE(0),
PEDESTRIAN(1),
BICYCLE(2),
PEDESTRIAN_AND_BICYCLE(2 | 1),
CAR(4),
PEDESTRIAN_AND_CAR(4 | 1),
BICYCLE_AND_CAR(4 | 2),
ALL(4 | 2 | 1);
private static final Map<Integer, StreetTraversalPermission> lookup = new HashMap<Integer, StreetTraversalPermission>();
static {
for (StreetTraversalPermission s : EnumSet.allOf(StreetTraversalPermission.class))
lookup.put(s.code, s);
}
public int code;
private StreetTraversalPermission(int code) {
this.code = code;
}
public static StreetTraversalPermission get(int code) {
return lookup.get(code);
}
public StreetTraversalPermission add(StreetTraversalPermission perm) {
return get(this.code | perm.code);
}
/**
* Returns intersection of allowed permissions between current permissions and given permissions
*
* @param perm
* @return
*/
public StreetTraversalPermission intersection(StreetTraversalPermission perm) {
return get(this.code & perm.code);
}
public StreetTraversalPermission remove(StreetTraversalPermission perm) {
return get(this.code & ~perm.code);
}
public StreetTraversalPermission modify(boolean permissive, StreetTraversalPermission perm) {
return permissive ? add(perm) : remove(perm);
}
public boolean allows(StreetTraversalPermission perm) {
return (code & perm.code) != 0;
}
/**
* Returns true if any of the specified modes are allowed to use this street.
*/
public boolean allows(TraverseModeSet modes) {
if (modes.getWalk() && allows(StreetTraversalPermission.PEDESTRIAN)) {
return true;
} else if (modes.getBicycle() && allows(StreetTraversalPermission.BICYCLE)) {
return true;
} else if (modes.getCar() && allows(StreetTraversalPermission.CAR)) {
return true;
}
return false;
}
/**
* Returns true if the given mode is allowed to use this street.
*/
public boolean allows(TraverseMode mode) {
if (mode == TraverseMode.WALK && allows(StreetTraversalPermission.PEDESTRIAN)) {
return true;
} else if (mode == TraverseMode.BICYCLE && allows(StreetTraversalPermission.BICYCLE)) {
return true;
} else if (mode == TraverseMode.CAR && allows(StreetTraversalPermission.CAR)) {
return true;
}
return false;
}
/**
* Returns true if there are any modes allowed by this permission.
*/
public boolean allowsAnything() {
return !this.allowsNothing();
}
/**
* Returns true if there no modes are by this permission.
*/
public boolean allowsNothing() {
// TODO(flamholz): what about CROSSHATCHED?
return this == StreetTraversalPermission.NONE;
}
}