001package jmri.jmrit.display.configurexml;
002
003import jmri.configurexml.JmriConfigureXmlException;
004import jmri.jmrit.catalog.NamedIcon;
005import jmri.jmrit.display.*;
006
007import org.jdom2.Attribute;
008import org.jdom2.Element;
009import org.slf4j.Logger;
010import org.slf4j.LoggerFactory;
011
012/**
013 * Handle configuration for display.TurnoutIcon objects.
014 *
015 * Based upon the TurnoutIconXml by Bob Jacobsen
016 *
017 * @author Kevin Dickerson Copyright: Copyright (c) 2010
018 */
019public class SlipTurnoutIconXml extends PositionableLabelXml {
020
021    public SlipTurnoutIconXml() {
022    }
023
024    /**
025     * Default implementation for storing the contents of a TurnoutIcon
026     *
027     * @param o Object to store, of type TurnoutIcon
028     * @return Element containing the complete info
029     */
030    @Override
031    public Element store(Object o) {
032
033        SlipTurnoutIcon p = (SlipTurnoutIcon) o;
034        if (!p.isActive()) {
035            return null;  // if flagged as inactive, don't store
036        }
037        Element element = new Element("slipturnouticon");
038
039        element.addContent(new Element("turnoutEast").addContent(p.getNamedTurnout(SlipTurnoutIcon.EAST).getName()));
040        element.addContent(new Element("turnoutWest").addContent(p.getNamedTurnout(SlipTurnoutIcon.WEST).getName()));
041
042        switch (p.getTurnoutType()) {
043            case SlipTurnoutIcon.DOUBLESLIP:
044                element.addContent(storeIcon("lowerWestToLowerEast", p.getLowerWestToLowerEastIcon(), p.getLWLEText()));
045                element.addContent(storeIcon("upperWestToUpperEast", p.getUpperWestToUpperEastIcon(), p.getUWUEText()));
046                element.setAttribute("turnoutType", "doubleSlip");
047                break;
048            case SlipTurnoutIcon.SINGLESLIP:
049                element.addContent(storeIcon("lowerWestToLowerEast", p.getLowerWestToLowerEastIcon(), p.getLWLEText()));
050                element.setAttribute("turnoutType", "singleSlip");
051                element.setAttribute("singleSlipRoute", p.getSingleSlipRoute() ? "upperWestToUpperEast" : "lowerWestToLowerEast");
052                break;
053            case SlipTurnoutIcon.THREEWAY:
054                element.addContent(storeIcon("lowerWestToLowerEast", p.getLowerWestToLowerEastIcon(), p.getLWLEText()));
055                element.setAttribute("turnoutType", "threeWay");
056                element.setAttribute("firstTurnoutExit", p.getSingleSlipRoute() ? "upper" : "lower");
057                break;
058            case SlipTurnoutIcon.SCISSOR:
059                if (!p.getSingleSlipRoute()) {
060                    element.addContent(new Element("turnoutLowerEast").addContent(p.getNamedTurnout(SlipTurnoutIcon.LOWEREAST).getName()));
061                    element.addContent(new Element("turnoutLowerWest").addContent(p.getNamedTurnout(SlipTurnoutIcon.LOWERWEST).getName()));
062                }
063                element.addContent(storeIcon("lowerWestToLowerEast", p.getLowerWestToLowerEastIcon(), p.getLWLEText()));
064                element.setAttribute("turnoutType", "scissor");
065                break;
066            default:
067                log.warn("Unhandled turnout type: {}", p.getTurnoutType());
068                break;
069        }
070
071        storeCommonAttributes(p, element);
072
073        // include contents
074        element.setAttribute("tristate", p.getTristate() ? "true" : "false");
075        //element.setAttribute("turnoutType", p.getTurnoutType()?"double":"single");
076
077        // new style
078        element.addContent(storeIcon("lowerWestToUpperEast", p.getLowerWestToUpperEastIcon(), p.getLWUEText()));
079        element.addContent(storeIcon("upperWestToLowerEast", p.getUpperWestToLowerEastIcon(), p.getUWLEText()));
080        element.addContent(super.storeIcon("unknown", p.getUnknownIcon()));
081        element.addContent(super.storeIcon("inconsistent", p.getInconsistentIcon()));
082
083        storeLogixNG_Data(p, element);
084
085        element.setAttribute("class", "jmri.jmrit.display.configurexml.SlipTurnoutIconXml");
086
087        return element;
088    }
089
090    Element storeIcon(String elemName, NamedIcon icon, String text) {
091        Element element = super.storeIcon(elemName, icon);
092        element.addContent(new Element("text").addContent(text));
093        return element;
094    }
095
096    /**
097     * Create a PositionableLabel, then add to a target JLayeredPane
098     *
099     * @param element Top level Element to unpack.
100     * @param o       Editor as an Object
101     * @throws JmriConfigureXmlException when a error prevents creating the objects as as
102     *                   required by the input XML
103     */
104    @Override
105    public void load(Element element, Object o) throws JmriConfigureXmlException {
106        // create the objects
107        Editor p = (Editor) o;
108
109        SlipTurnoutIcon l = new SlipTurnoutIcon(p);
110        int rotation = 0;
111        try {
112            Attribute a = element.getAttribute("rotate");
113            rotation = a.getIntValue();
114        } catch (org.jdom2.DataConversionException ignored) {
115        } catch (NullPointerException e) {  // considered normal if the attributes are not present
116        }
117
118        String nameEast = loadTurnout(element, "turnoutEast");
119        /*try {
120         nameEast=element.getAttribute("turnoutEast").getValue();
121         } catch ( NullPointerException e) { 
122         log.error("incorrect information for turnout; must use turnout name");
123         return;
124         }*/
125        String nameWest = loadTurnout(element, "turnoutWest");
126        /*try {
127         nameWest=element.getAttribute("turnoutWest").getValue();
128         } catch ( NullPointerException e) { 
129         log.error("incorrect information for turnout; must use turnout name");
130         return;
131         }*/
132
133        Attribute a = element.getAttribute("turnoutType");
134        if (a != null) {
135            if (a.getValue().equals("doubleSlip")) {
136                l.setTurnoutType(SlipTurnoutIcon.DOUBLESLIP);
137            } else if (a.getValue().equals("singleSlip")) {
138                l.setTurnoutType(SlipTurnoutIcon.SINGLESLIP);
139                a = element.getAttribute("singleSlipRoute");
140                if ((a == null) || a.getValue().equals("upperWestToUpperEast")) {
141                    l.setSingleSlipRoute(true);
142                } else {
143                    l.setSingleSlipRoute(false);
144                }
145            } else if (a.getValue().equals("threeWay")) {
146                l.setTurnoutType(SlipTurnoutIcon.THREEWAY);
147                a = element.getAttribute("firstTurnoutExit");
148                if ((a == null) || a.getValue().equals("lower")) {
149                    l.setSingleSlipRoute(false);
150                } else {
151                    l.setSingleSlipRoute(true);
152                }
153            } else if (a.getValue().equals("scissor")) {
154                l.setTurnoutType(SlipTurnoutIcon.SCISSOR);
155                if (loadTurnout(element, "turnoutLowerWest") == null) {
156                    l.setSingleSlipRoute(true);
157                } else {
158                    //loadTurnout(element, "turnoutLowerEast");
159                    l.setSingleSlipRoute(false);
160                    l.setTurnout(loadTurnout(element, "turnoutLowerEast"), SlipTurnoutIcon.LOWEREAST);
161                    l.setTurnout(loadTurnout(element, "turnoutLowerWest"), SlipTurnoutIcon.LOWERWEST);
162                }
163
164            }
165        }
166        loadTurnoutIcon("lowerWestToUpperEast", rotation, l, element, p);
167        loadTurnoutIcon("upperWestToLowerEast", rotation, l, element, p);
168        switch (l.getTurnoutType()) {
169            case SlipTurnoutIcon.DOUBLESLIP:
170                loadTurnoutIcon("lowerWestToLowerEast", rotation, l, element, p);
171                loadTurnoutIcon("upperWestToUpperEast", rotation, l, element, p);
172                break;
173            default:
174                loadTurnoutIcon("lowerWestToLowerEast", rotation, l, element, p);
175                break;
176        }
177
178        loadTurnoutIcon("unknown", rotation, l, element, p);
179        loadTurnoutIcon("inconsistent", rotation, l, element, p);
180
181        a = element.getAttribute("tristate");
182        if ((a == null) || a.getValue().equals("true")) {
183            l.setTristate(true);
184        } else {
185            l.setTristate(false);
186        }
187
188        l.setTurnout(nameEast, SlipTurnoutIcon.EAST);
189        l.setTurnout(nameWest, SlipTurnoutIcon.WEST);
190
191        try {
192            p.putItem(l);
193        } catch (Positionable.DuplicateIdException e) {
194            throw new JmriConfigureXmlException("Positionable id is not unique", e);
195        }
196
197        loadLogixNG_Data(l, element);
198
199        // load individual item's option settings after editor has set its global settings
200        loadCommonAttributes(l, Editor.TURNOUTS, element);
201    }
202
203    private String loadTurnout(Element element, String turn) {
204        if (element != null) {
205            Element e = element.getChild(turn);
206            if (e != null) {
207                return e.getText();
208            }
209        }
210        return null;
211    }
212
213    private void loadTurnoutIcon(String state, int rotation, SlipTurnoutIcon l,
214            Element element, Editor ed) {
215        NamedIcon icon = loadIcon(l, state, element, "SlipTurnout \"" + l.getNameString() + "\" icon \"" + state + "\" ", ed);
216        String textValue = null;
217
218        if (icon != null) {
219            if (state.equals("lowerWestToUpperEast")) {
220                l.setLowerWestToUpperEastIcon(icon);
221            } else if (state.equals("upperWestToLowerEast")) {
222                l.setUpperWestToLowerEastIcon(icon);
223            } else if (state.equals("lowerWestToLowerEast")) {
224                l.setLowerWestToLowerEastIcon(icon);
225            } else if (state.equals("upperWestToUpperEast")) {
226                l.setUpperWestToUpperEastIcon(icon);
227            } else if (state.equals("unknown")) {
228                l.setUnknownIcon(icon);
229            } else if (state.equals("inconsistent")) {
230                l.setInconsistentIcon(icon);
231            }
232        } else {
233            return;
234        }
235        Element elem = element.getChild(state);
236        if (elem != null) {
237            Element e = elem.getChild("text");
238            if (e != null) {
239                textValue = e.getText();
240            }
241        }
242        if (textValue != null) {
243            if (state.equals("lowerWestToUpperEast")) {
244                l.setLWUEText(textValue);
245            } else if (state.equals("upperWestToLowerEast")) {
246                l.setUWLEText(textValue);
247            } else if (state.equals("lowerWestToLowerEast")) {
248                l.setLWLEText(textValue);
249            } else if (state.equals("upperWestToUpperEast")) {
250                l.setUWUEText(textValue);
251            }
252        }
253    }
254
255    private final static Logger log = LoggerFactory.getLogger(SlipTurnoutIconXml.class);
256
257}