001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.gui.mappaint;
003    
004    import java.util.Collection;
005    import java.util.HashMap;
006    import java.util.Map;
007    import java.util.Map.Entry;
008    
009    import 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     */
016    public class MultiCascade implements StyleKeys {
017    
018        private Map<String, Cascade> layers;
019        public Range range;
020    
021        public MultiCascade() {
022            layers = new HashMap<String, Cascade>();
023            range = new Range();
024        }
025    
026        /**
027         * Return the cascade with the given name. If it doesn't exist, create
028         * a new layer with that name and return it. The new layer will be
029         * a clone of the "*" layer, if it exists.
030         */
031        public Cascade getOrCreateCascade(String layer) {
032            CheckParameterUtil.ensureParameterNotNull(layer);
033            Cascade c = layers.get(layer);
034            if (c == null) {
035                if (layers.containsKey("*")) {
036                    c = layers.get("*").clone();
037                } else {
038                    c = new Cascade();
039                    // Everything that is not on the default layer is assumed to
040                    // be a modifier. Can be overridden in style definition.
041                    if (!layer.equals("default") && !layer.equals("*")) {
042                        c.put(MODIFIER, true);
043                    }
044                }
045                layers.put(layer, c);
046            }
047            return c;
048        }
049    
050        /**
051         * Read-only version of getOrCreateCascade. For convenience, it returns an
052         * empty cascade for non-existing layers. However this empty (read-only) cascade
053         * is not added to this MultiCascade object.
054         */
055        public Cascade getCascade(String layer) {
056            if (layer == null) {
057                layer = "default";
058            }
059            Cascade c = layers.get(layer);
060            if (c == null) {
061                c = new Cascade();
062                if (!layer.equals("default") && !layer.equals("*")) {
063                    c.put(MODIFIER, true);
064                }
065            }
066            return c;
067        }
068    
069        public Collection<Entry<String, Cascade>> getLayers() {
070            return layers.entrySet();
071        }
072    
073        public boolean hasLayer(String layer) {
074            return layers.containsKey(layer);
075        }
076    }