001package jmri.jmrit.display;
002
003import java.util.Collection;
004import java.util.HashMap;
005import java.util.Iterator;
006import java.util.Map.Entry;
007import jmri.jmrit.catalog.NamedIcon;
008
009/**
010 * Gather common methods for Turnouts, Sensors, SignalHeads, Masts, etc.
011 *
012 * <a href="doc-files/Heirarchy.png"><img src="doc-files/Heirarchy.png" alt="UML class diagram for package" height="33%" width="33%"></a>
013 * @author Pete Cressman Copyright (C) 2011
014 */
015public class PositionableIcon extends PositionableLabel {
016
017    protected HashMap<String, NamedIcon> _iconMap;
018    protected String _iconFamily;
019    protected double _scale = 1.0;          // getScale, come from net result found in one of the icons
020    protected int _rotate = 0;
021
022    public PositionableIcon(Editor editor) {
023        // super ctor call to make sure this is an icon label
024        super(new NamedIcon("resources/icons/misc/X-red.gif", "resources/icons/misc/X-red.gif"), editor);
025    }
026
027    public PositionableIcon(NamedIcon s, Editor editor) {
028        // super ctor call to make sure this is an icon label
029        super(s, editor);
030    }
031
032    public PositionableIcon(String s, Editor editor) {
033        // super ctor call to make sure this is an icon label
034        super(s, editor);
035    }
036
037    @Override
038    public Positionable deepClone() {
039        PositionableIcon pos = new PositionableIcon(_editor);
040        return finishClone(pos);
041    }
042
043    protected Positionable finishClone(PositionableIcon pos) {
044        pos._iconFamily = _iconFamily;
045        pos._scale = _scale;
046        pos._rotate = _rotate;
047        pos._iconMap = cloneMap(_iconMap, pos);
048        return super.finishClone(pos);
049    }
050
051    public Collection<String> getStateNameCollection() {
052        log.error("getStateNameCollection() must be implemented by extensions!");
053        return null;
054    }
055
056    /**
057     * Get icon by its localized bean state name.
058     *
059     * @param state the state name
060     * @return the icon or null if no match
061     */
062    public NamedIcon getIcon(String state) {
063        return _iconMap.get(state);
064    }
065
066    public String getFamily() {
067        return _iconFamily;
068    }
069
070    public void setFamily(String family) {
071        _iconFamily = family;
072    }
073
074    public Iterator<String> getIconStateNames() {
075        return _iconMap.keySet().iterator();
076    }
077
078    public HashMap<String, NamedIcon> getIconMap() {
079        return cloneMap(_iconMap, this);
080    }
081
082    @Override
083    public int maxHeight() {
084        int max = super.maxHeight();
085        if (_iconMap != null) {
086            for (NamedIcon namedIcon : _iconMap.values()) {
087                max = Math.max(namedIcon.getIconHeight(), max);
088            }
089        }
090        return max;
091    }
092
093    @Override
094    public int maxWidth() {
095        int max = super.maxWidth();
096        if (_iconMap != null) {
097            for (NamedIcon namedIcon : _iconMap.values()) {
098                max = Math.max(namedIcon.getIconWidth(), max);
099            }
100        }
101        return max;
102    }
103
104    public void displayState(int state) {
105    }
106
107    /**
108     * ****** popup AbstractAction method overrides ********
109     */
110    @Override
111    protected void rotateOrthogonal() {
112        for (Entry<String, NamedIcon> entry : _iconMap.entrySet()) {
113            entry.getValue().setRotation(entry.getValue().getRotation() + 1, this);
114        }
115        updateSize();
116    }
117
118    @Override
119    public void setScale(double s) {
120        _scale = s;
121        if (_iconMap == null) {
122            return;
123        }
124        for (Entry<String, NamedIcon> entry : _iconMap.entrySet()) {
125            entry.getValue().scale(s, this);
126        }
127        updateSize();
128    }
129
130    @Override
131    public double getScale() {
132        return _scale;
133    }
134
135    @Override
136    public void rotate(int deg) {
137        _rotate = deg % 360;
138        setDegrees(deg);
139        if (_iconMap != null) {
140            for (Entry<String, NamedIcon> entry : _iconMap.entrySet()) {
141                entry.getValue().rotate(deg, this);
142            }
143        }
144        super.rotate(deg);
145        updateSize();
146    }
147
148    public static HashMap<String, NamedIcon> cloneMap(HashMap<String, NamedIcon> map,
149            PositionableLabel pos) {
150        HashMap<String, NamedIcon> clone = new HashMap<>();
151        if (map != null) {
152            for (Entry<String, NamedIcon> entry : map.entrySet()) {
153                clone.put(entry.getKey(), cloneIcon(entry.getValue(), pos));
154            }
155        }
156        return clone;
157    }
158
159    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(PositionableIcon.class);
160}