001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.mappaint.mapcss;
003
004import org.openstreetmap.josm.data.osm.Tag;
005import org.openstreetmap.josm.data.osm.Tagged;
006import org.openstreetmap.josm.gui.mappaint.Environment;
007import org.openstreetmap.josm.tools.CheckParameterUtil;
008
009/**
010 * This is a condition that needs to be fulfilled in order to apply a MapCSS style.
011 */
012@FunctionalInterface
013public interface Condition {
014
015    /**
016     * Checks if the condition applies in the given MapCSS {@link Environment}.
017     * @param e The environment to check. May not be <code>null</code>.
018     * @return <code>true</code> if the condition applies.
019     */
020    boolean applies(Environment e);
021
022    /**
023     * Checks if the condition applies in the given {@link Tagged} element.
024     * @param tagged The tagged to check.
025     * @return <code>true</code> if the condition applies.
026     */
027    default boolean applies(Tagged tagged) {
028        return false;
029    }
030
031    /**
032     * Context, where the condition applies.
033     */
034    enum Context {
035        /**
036         * normal primitive selector, e.g. way[highway=residential]
037         */
038        PRIMITIVE,
039
040        /**
041         * link between primitives, e.g. relation &gt;[role=outer] way
042         */
043        LINK
044    }
045
046    /**
047     * This is a condition that can be converted to a tag
048     * @author Michael Zangl
049     * @since 10674 (ToTagConvertable), 17642 (TagCondition)
050     */
051    interface TagCondition extends Condition {
052
053        @Override
054        default boolean applies(Environment e) {
055            CheckParameterUtil.ensureThat(!e.isLinkContext(), "Illegal state: TagCondition not supported in LINK context");
056            return applies(e.osm);
057        }
058
059        @Override
060        boolean applies(Tagged tagged);
061
062        /**
063         * Converts the current condition to a tag
064         * @param tagged A tagged object to use as context. May be ignored.
065         * @return A tag with the key/value of this condition.
066         */
067        Tag asTag(Tagged tagged);
068    }
069}