001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.dialogs.relation.sort;
003
004import static org.openstreetmap.josm.gui.dialogs.relation.sort.WayConnectionType.Direction.NONE;
005import static org.openstreetmap.josm.tools.I18n.tr;
006
007/**
008 * A class used by the {@link RelationSorter} to store if two ways are already connected
009 */
010public class WayConnectionType {
011
012    /** True, if the corresponding primitive is not a way or the way is incomplete */
013    private final boolean invalid;
014
015    /** True, if linked to the previous member.  */
016    public boolean linkPrev;
017    /** True, if linked to the next member.  */
018    public boolean linkNext;
019
020    /**
021     * direction is FORWARD if the first node of this way is connected to the previous way
022     * and / or the last node of this way is connected to the next way.
023     * direction is BACKWARD if it is the other way around.
024     * direction has a ONEWAY value, if it is tagged as such and it is connected
025     * to the previous / next member.
026     * ONEWAY_FORWARD == the first node of the oneway is the last node of the previous way
027     * ONEWAY_BACKWARD == the last node of the oneway is the last node of the previous way
028     * direction has a ROUNDABOUT value, if it is tagged as such and it is somehow
029     * connected to the previous / next member.
030     * If there is no connection to the previous or next member, then
031     * direction has the value NONE.
032     */
033    public Direction direction;
034
035    public enum Direction {
036        FORWARD, BACKWARD, ROUNDABOUT_LEFT, ROUNDABOUT_RIGHT, NONE;
037
038        public boolean isRoundabout() {
039            return this == ROUNDABOUT_RIGHT || this == ROUNDABOUT_LEFT;
040        }
041    }
042
043    /** True, if the element is part of a closed loop of ways. */
044    public boolean isLoop;
045
046    public boolean isOnewayLoopForwardPart;
047    public boolean isOnewayLoopBackwardPart;
048    public boolean isOnewayHead;
049    public boolean isOnewayTail;
050
051    /** False, if the way is oneway and it doesn't follow the flow of the previous member */
052    public boolean onewayFollowsPrevious = true;
053    /** True, if the way is oneway and it doesn't follow the flow of the next member */
054    public boolean onewayFollowsNext = true;
055
056    public WayConnectionType(boolean linkPrev, boolean linkNext, Direction direction) {
057        this.linkPrev = linkPrev;
058        this.linkNext = linkNext;
059        this.isLoop = false;
060        this.direction = direction;
061        invalid = false;
062    }
063
064    public WayConnectionType(boolean invalid) {
065        this.invalid = invalid;
066    }
067
068    /** construct invalid instance */
069    public WayConnectionType() {
070        this.linkPrev = false;
071        this.linkNext = false;
072        this.isLoop = false;
073        this.direction = NONE;
074        invalid = true;
075    }
076
077    public boolean isValid() {
078        return !invalid;
079    }
080
081    @Override
082    public String toString() {
083        return "[P "+linkPrev+" ;N "+linkNext+" ;D "+direction+" ;L "+isLoop+
084                " ;FP " + isOnewayLoopForwardPart+";BP " + isOnewayLoopBackwardPart+
085                ";OH " + isOnewayHead+";OT " + isOnewayTail+']';
086    }
087
088    /**
089     * Returns the tooltip to display when hovering over the relation member.
090     * @return The tooltip, never null.
091     * @since 10248
092     */
093    public String getTooltip() {
094        boolean onewayGood = onewayFollowsPrevious && onewayFollowsNext;
095        if (!isValid())
096            return "";
097        else if (linkPrev && linkNext && onewayGood)
098            return tr("way is connected");
099        else if (linkPrev && linkNext && !onewayGood)
100            return tr("way is connected but has a wrong oneway direction");
101        else if (linkPrev && onewayGood)
102            return tr("way is connected to previous relation member");
103        else if (linkPrev && !onewayGood)
104            return tr("way is connected to previous relation member but has a wrong oneway direction");
105        else if (linkNext && onewayGood)
106            return tr("way is connected to next relation member");
107        else if (linkNext && !onewayGood)
108            return tr("way is connected to next relation member but has a wrong oneway direction");
109        else
110            return tr("way is not connected to previous or next relation member");
111    }
112}