001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.mappaint;
003
004import java.util.Collection;
005import java.util.HashMap;
006import java.util.Map;
007import java.util.Map.Entry;
008
009import org.openstreetmap.josm.tools.CheckParameterUtil;
010
011/**
012 * Several layers / cascades, e.g. one for the main Line and one for each overlay.
013 * The range is (0,Infinity) at first and it shrinks in the process when
014 * StyleSources apply zoom level dependent properties.
015 */
016public class MultiCascade implements StyleKeys {
017
018    private final Map<String, Cascade> layers;
019    public Range range;
020
021    /**
022     * Constructs a new {@code MultiCascade}.
023     */
024    public MultiCascade() {
025        layers = new HashMap<>();
026        range = Range.ZERO_TO_INFINITY;
027    }
028
029    /**
030     * Return the cascade with the given name. If it doesn't exist, create
031     * a new layer with that name and return it. The new layer will be
032     * a clone of the "*" layer, if it exists.
033     * @param layer layer
034     * @return cascade
035     */
036    public Cascade getOrCreateCascade(String layer) {
037        CheckParameterUtil.ensureParameterNotNull(layer);
038        Cascade c = layers.get(layer);
039        if (c == null) {
040            if (layers.containsKey("*")) {
041                c = new Cascade(layers.get("*"));
042            } else {
043                c = new Cascade();
044                // Everything that is not on the default layer is assumed to
045                // be a modifier. Can be overridden in style definition.
046                if (!"default".equals(layer) && !"*".equals(layer)) {
047                    c.put(MODIFIER, Boolean.TRUE);
048                }
049            }
050            layers.put(layer, c);
051        }
052        return c;
053    }
054
055    /**
056     * Read-only version of {@link #getOrCreateCascade}. For convenience, it returns an
057     * empty cascade for non-existing layers. However this empty (read-only) cascade
058     * is not added to this MultiCascade object.
059     * @param layer layer
060     * @return cascade
061     */
062    public Cascade getCascade(String layer) {
063        if (layer == null) {
064            layer = "default";
065        }
066        Cascade c = layers.get(layer);
067        if (c == null) {
068            c = new Cascade();
069            if (!"default".equals(layer) && !"*".equals(layer)) {
070                c.put(MODIFIER, Boolean.TRUE);
071            }
072        }
073        return c;
074    }
075
076    public Collection<Entry<String, Cascade>> getLayers() {
077        return layers.entrySet();
078    }
079
080    public boolean hasLayer(String layer) {
081        return layers.containsKey(layer);
082    }
083}