001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.mappaint.mapcss;
003
004import java.util.List;
005import java.util.Objects;
006
007import org.openstreetmap.josm.gui.mappaint.Environment;
008import org.openstreetmap.josm.tools.Utils;
009
010/**
011 * A MapCSS rule.
012 *
013 * A MapCSS style is simply a list of MapCSS rules. Each rule has a selector
014 * and a declaration. Whenever the selector matches the primitive, the
015 * declaration block is executed for this primitive.
016 */
017public class MapCSSRule implements Comparable<MapCSSRule> {
018
019    public final Selector selector;
020    public final Declaration declaration;
021
022    public static class Declaration {
023        public final List<Instruction> instructions;
024        // declarations in the StyleSource are numbered consecutively
025        public final int idx;
026
027        public Declaration(List<Instruction> instructions, int idx) {
028            this.instructions = instructions;
029            this.idx = idx;
030        }
031
032        /**
033         * <p>Executes the instructions against the environment {@code env}</p>
034         *
035         * @param env the environment
036         */
037        public void execute(Environment env) {
038            for (Instruction i : instructions) {
039                i.execute(env);
040            }
041        }
042
043        @Override
044        public int hashCode() {
045            return Objects.hash(instructions, idx);
046        }
047
048        @Override
049        public boolean equals(Object obj) {
050            if (this == obj) return true;
051            if (obj == null || getClass() != obj.getClass()) return false;
052            Declaration that = (Declaration) obj;
053            return idx == that.idx &&
054                    Objects.equals(instructions, that.instructions);
055        }
056
057        @Override
058        public String toString() {
059            return "Declaration [instructions=" + instructions + ", idx=" + idx + ']';
060        }
061    }
062
063    /**
064     * Constructs a new {@code MapCSSRule}.
065     * @param selector The selector
066     * @param declaration The declaration
067     */
068    public MapCSSRule(Selector selector, Declaration declaration) {
069        this.selector = selector;
070        this.declaration = declaration;
071    }
072
073    /**
074     * <p>Executes the instructions against the environment {@code env}</p>
075     *
076     * @param env the environment
077     */
078    public void execute(Environment env) {
079        declaration.execute(env);
080    }
081
082    @Override
083    public int compareTo(MapCSSRule o) {
084        return declaration.idx - o.declaration.idx;
085    }
086
087    @Override
088    public String toString() {
089        return selector + " {\n  " + Utils.join("\n  ", declaration.instructions) + "\n}";
090    }
091}
092