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