001package jmri.implementation.configurexml;
002
003import java.util.List;
004import jmri.InstanceManager;
005import jmri.NamedBeanHandle;
006import jmri.SignalHead;
007import jmri.Turnout;
008import jmri.implementation.SingleTurnoutSignalHead;
009import org.jdom2.Element;
010import org.slf4j.Logger;
011import org.slf4j.LoggerFactory;
012
013/**
014 * Handle XML configuration for SingleTurnoutSignalHead objects. Based Upon
015 * DoubleTurnoutSignalHeadXML by Bob Jacobsen
016 *
017 * @author Kevin Dickerson: Copyright (c) 2010
018 */
019public class SingleTurnoutSignalHeadXml extends jmri.managers.configurexml.AbstractNamedBeanManagerConfigXML {
020
021    public SingleTurnoutSignalHeadXml() {
022    }
023
024    /**
025     * Default implementation for storing the contents of a
026     * SingleTurnoutSignalHead.
027     *
028     * @param o Object to store, of type TripleTurnoutSignalHead
029     * @return Element containing the complete info
030     */
031    @Override
032    public Element store(Object o) {
033        SingleTurnoutSignalHead p = (SingleTurnoutSignalHead) o;
034
035        Element element = new Element("signalhead");
036        element.setAttribute("class", this.getClass().getName());
037
038        // include contents
039        element.addContent(new Element("systemName").addContent(p.getSystemName()));
040
041        storeCommon(p, element);
042
043        Element el = new Element("appearance");
044        el.setAttribute("defines", "thrown");
045        el.addContent(getSignalColour(p.getOnAppearance()));
046        element.addContent(el);
047
048        el = new Element("appearance");
049        el.setAttribute("defines", "closed");
050        el.addContent(getSignalColour(p.getOffAppearance()));
051        element.addContent(el);
052
053        el = new Element("turnoutname");
054        el.setAttribute("defines", "aspect");
055        el.addContent(p.getOutput().getName());
056        element.addContent(el);
057        //element.addContent(addTurnoutElement("aspect"));
058
059        return element;
060    }
061
062    private String getSignalColour(int mAppearance) {
063        switch (mAppearance) {
064            case SignalHead.RED:
065                return "red";
066            case SignalHead.FLASHRED:
067                return "flashred";
068            case SignalHead.YELLOW:
069                return "yellow";
070            case SignalHead.FLASHYELLOW:
071                return "flashyellow";
072            case SignalHead.GREEN:
073                return "green";
074            case SignalHead.FLASHGREEN:
075                return "flashgreen";
076            case SignalHead.LUNAR:
077                return "lunar";
078            case SignalHead.FLASHLUNAR:
079                return "flashlunar";
080            case SignalHead.DARK:
081                return "dark";
082            default:
083                log.warn("Unexpected appearance: {}", mAppearance);
084                // go dark
085                return "dark";
086        }
087    }
088
089    @Override
090    public boolean load(Element shared, Element perNode) {
091        List<Element> l = shared.getChildren("turnoutname");
092        if (l.size() == 0) {
093            l = shared.getChildren("turnout");
094        }
095        NamedBeanHandle<Turnout> lit = loadTurnout(l.get(0));
096
097        int off = loadAppearance(shared.getChildren("appearance"), "closed");
098        int on = loadAppearance(shared.getChildren("appearance"), "thrown");
099
100        // put it together
101        String sys = getSystemName(shared);
102        String uname = getUserName(shared);
103
104        SignalHead h;
105        if (uname == null) {
106            h = new SingleTurnoutSignalHead(sys, lit, on, off);
107        } else {
108            h = new SingleTurnoutSignalHead(sys, uname, lit, on, off);
109        }
110
111        loadCommon(h, shared);
112
113        SignalHead existingBean =
114                InstanceManager.getDefault(jmri.SignalHeadManager.class)
115                        .getBySystemName(sys);
116
117        if ((existingBean != null) && (existingBean != h)) {
118            log.error("systemName is already registered: {}", sys);
119        } else {
120            InstanceManager.getDefault(jmri.SignalHeadManager.class).register(h);
121        }
122
123        return true;
124    }
125
126    private int loadAppearance(List<Element> l, String state) {
127        for (int i = 0; i < l.size(); i++) {
128            if (l.get(i).getAttribute("defines").getValue().equals(state)) {
129                return getIntFromColour(l.get(i).getText());
130            }
131        }
132        return 0x00;
133    }
134
135    /**
136     * Load a turnout.
137     * Needs to handle two types of element: turnoutname is new form, turnout is
138     * old form.
139     *
140     * @param o Object read from storage, of type Turnout
141     * @return Turnout bean
142     */
143    NamedBeanHandle<Turnout> loadTurnout(Object o) {
144        Element e = (Element) o;
145
146        String name = e.getText();
147        try {
148            Turnout t = InstanceManager.turnoutManagerInstance().provideTurnout(name);
149            return jmri.InstanceManager.getDefault(jmri.NamedBeanHandleManager.class).getNamedBeanHandle(name, t);
150        } catch (IllegalArgumentException ex) {
151            log.warn("Failed to provide Turnout \"{}\" in loadTurnout", name);
152            return null;
153        }
154    }
155
156    private int getIntFromColour(String colour) {
157        switch (colour.toLowerCase()) {
158            case "red":
159                return SignalHead.RED;
160            case "yellow":
161                return SignalHead.YELLOW;
162            case "green":
163                return SignalHead.GREEN;
164            case "lunar":
165                return SignalHead.LUNAR;
166            case "dark":
167                return SignalHead.DARK;
168            case "flashred":
169                return SignalHead.FLASHRED;
170            case "flashyellow":
171                return SignalHead.FLASHYELLOW;
172            case "flashgreen":
173                return SignalHead.FLASHGREEN;
174            case "flashlunar":
175                return SignalHead.FLASHLUNAR;
176            default:
177                log.warn("Unexpected appearance: {}", colour);
178                break;
179        }
180        return SignalHead.DARK;
181
182    }
183
184    private final static Logger log = LoggerFactory.getLogger(SingleTurnoutSignalHeadXml.class);
185}