001package jmri.jmrit.display.controlPanelEditor.configurexml;
002
003import jmri.jmrit.catalog.NamedIcon;
004import jmri.jmrit.display.configurexml.PositionableLabelXml;
005import jmri.jmrit.display.controlPanelEditor.ControlPanelEditor;
006import jmri.jmrit.display.controlPanelEditor.PortalIcon;
007import jmri.jmrit.display.palette.ItemPalette;
008import jmri.jmrit.logix.OBlock;
009import jmri.jmrit.logix.Portal;
010
011import java.util.HashMap;
012import java.util.List;
013import java.util.Map;
014
015import jmri.configurexml.JmriConfigureXmlException;
016import jmri.jmrit.display.Positionable;
017
018import org.jdom2.Attribute;
019import org.jdom2.Element;
020import org.slf4j.Logger;
021import org.slf4j.LoggerFactory;
022
023/**
024 * Handle configuration for display.PortalIcon objects.
025 *
026 * @author Pete cressman Copyright: Copyright (c) 2010, 2020
027 */
028public class PortalIconXml extends PositionableLabelXml {
029
030    public PortalIconXml() {
031    }
032
033    /**
034     * Default implementation for storing the contents of a PortalIcon.
035     *
036     * @param o Object to store, of type PortalIcon
037     * @return Element containing the complete info
038     */
039    @Override
040    public Element store(Object o) {
041
042        PortalIcon p = (PortalIcon) o;
043        if (!p.isActive()) {
044            return null;  // if flagged as inactive, don't store
045        }
046        Element element = new Element("PortalIcon");
047        storeCommonAttributes(p, element);
048        element.setAttribute("scale", String.valueOf(p.getScale()));
049        element.setAttribute("rotate", String.valueOf(p.getDegrees()));
050
051        // include contents
052        Portal portal = p.getPortal();
053        if (portal == null) {
054            log.info("PortalIcon has no associated Portal.");
055            return null;
056        }
057        element.setAttribute("portalName", portal.getName());
058        if (portal.getToBlock() != null) {
059            element.setAttribute("toBlockName", portal.getToBlockName());
060        }
061        if (portal.getFromBlockName() != null) {
062            element.setAttribute("fromBlockName", portal.getFromBlockName());
063        }
064        element.setAttribute("arrowSwitch", "" + (p.getArrowSwitch() ? "yes" : "no"));
065        element.setAttribute("arrowHide", "" + (p.getArrowHide() ? "yes" : "no"));
066
067        HashMap<String, NamedIcon> map = p.getIconMap();
068        if (map != null) {
069            Element elem = new Element("icons");
070            String family = p.getFamily();
071            if (family != null) {
072                elem.setAttribute("family", family);
073            }
074            for (Map.Entry<String, NamedIcon> entry : map.entrySet()) {
075                elem.addContent(storeIcon(entry.getKey(), entry.getValue()));
076            }
077        }
078
079        storeLogixNG_Data(p, element);
080
081        element.setAttribute("class", "jmri.jmrit.display.controlPanelEditor.configurexml.PortalIconXml");
082        return element;
083    }
084
085    /**
086     * Create a PositionableLabel, then add to a target JLayeredPane
087     *
088     * @param element Top level Element to unpack.
089     * @param o       an Editor as an Object
090     * @throws JmriConfigureXmlException when a error prevents creating the objects as as
091     *                   required by the input XML
092     */
093    @Override
094    public void load(Element element, Object o) throws JmriConfigureXmlException {
095        if (!(o instanceof ControlPanelEditor)) {
096            log.error("Can't load portalIcon.  Panel editor must use ControlPanelEditor.");
097            return;
098        }
099        ControlPanelEditor ed = (ControlPanelEditor) o;
100
101        String fromBlk;
102        try {
103            fromBlk = element.getAttribute("fromBlockName").getValue();
104        } catch (NullPointerException e) {
105            log.error("incorrect information for portalIcon; must use fromBlockName.");
106            return;
107        }
108        String portalName;
109        try {
110            portalName = element.getAttribute("portalName").getValue();
111        } catch (NullPointerException e) {
112            log.error("incorrect information for portalIcon; must use portalName.");
113            return;
114        }
115        OBlock block = jmri.InstanceManager.getDefault(jmri.jmrit.logix.OBlockManager.class).getOBlock(fromBlk);
116        Portal portal = block.getPortalByName(portalName);
117
118        PortalIcon l = new PortalIcon(ed, portal);
119        try {
120            ed.putItem(l);
121        } catch (Positionable.DuplicateIdException e) {
122            throw new JmriConfigureXmlException("Positionable id is not unique", e);
123        }
124
125        // load individual item's option settings after editor has set its global settings
126        loadCommonAttributes(l, ControlPanelEditor.MARKERS, element);
127        Attribute a = element.getAttribute("scale");
128        double scale = 1.0;
129        if (a != null) {
130            try {
131                scale = a.getDoubleValue();
132            } catch (org.jdom2.DataConversionException dce) {
133                log.error("{} can't convert scale", l.getNameString(), dce);
134            }
135        }
136        l.setScale(scale);
137
138        a = element.getAttribute("rotate");
139        int deg = 0;
140        if (a != null) {
141            try {
142                deg = a.getIntValue();
143            } catch (org.jdom2.DataConversionException dce) {
144                log.error("{} can't convert rotate", l.getNameString(), dce);
145            }
146        }
147        l.setDegrees(deg);
148
149        boolean value = true;
150        if ((a = element.getAttribute("arrowSwitch")) != null && a.getValue().equals("no")) {
151            value = false;
152        }
153        l.setArrowOrientation(value);
154        value = (a = element.getAttribute("arrowHide")) != null && a.getValue().equals("yes");
155        l.setHideArrows(value);
156
157        Element iconsElem = element.getChild("icons");
158        if (iconsElem != null) {
159            Attribute attr = iconsElem.getAttribute("family");
160            if (attr != null) {
161                l.setFamily(attr.getValue());
162            }
163            List<Element> states = iconsElem.getChildren();
164            if (log.isDebugEnabled()) {
165                log.debug("icons element has{} items", states.size());
166            }
167            for (Element stateElem : states) {
168                String state = stateElem.getName();
169                if (log.isDebugEnabled()) {
170                    log.debug("setIcon for state \"{}\"", state);
171                }
172                NamedIcon icon = loadIcon(l, state, iconsElem, "PortalIcon \"" + portalName + "\": icon \"" + state + "\" ", ed);
173                if (icon != null) {
174                    l.setIcon(state, icon);
175                } else {
176                    log.info("PortalIcon \"{}\": icon \"{}\" removed", portalName, state);
177                    return;
178                }
179            }
180        } else {
181            ItemPalette.loadIcons();
182            l.makeIconMap();
183        }
184
185        loadLogixNG_Data(l, element);
186    }
187
188    private final static Logger log = LoggerFactory.getLogger(PortalIconXml.class);
189}