001package jmri.jmrit.display.layoutEditor.configurexml;
002
003import java.awt.geom.Point2D;
004import java.util.List;
005import jmri.Turnout;
006import jmri.jmrit.display.layoutEditor.LayoutEditor;
007import jmri.jmrit.display.layoutEditor.LayoutTurntable;
008import jmri.jmrit.display.layoutEditor.LayoutTurntableView;
009import jmri.jmrit.display.layoutEditor.TrackSegment;
010import org.jdom2.Attribute;
011import org.jdom2.DataConversionException;
012import org.jdom2.Element;
013
014/**
015 * This module handles configuration for display.LayoutTurntable objects for a
016 * LayoutEditor.
017 *
018 * @author David Duchamp Copyright (c) 2007
019 * @author George Warner Copyright (c) 2017-2018
020 * @author Bob Jacobsen  Copyright (c) 2020
021 */
022public class LayoutTurntableViewXml extends LayoutTrackViewXml {
023
024    public LayoutTurntableViewXml() {
025    }
026
027    /**
028     * Default implementation for storing the contents of a LayoutTurntable
029     *
030     * @param o Object to store, of type LayoutTurntable
031     * @return Element containing the complete info
032     */
033    @Override
034    public Element store(Object o) {
035
036        LayoutTurntableView pv = (LayoutTurntableView) o;
037        LayoutTurntable p = pv.getTurntable();
038
039        Element element = new Element("layoutturntable");
040        boolean turnoutControl = p.isTurnoutControlled();
041        // include attributes
042        element.setAttribute("ident", p.getId());
043        if (!p.getBlockName().isEmpty()) {
044            element.setAttribute("blockname", p.getBlockName());
045        }
046        element.setAttribute("radius", "" + p.getRadius());
047        Point2D coords = pv.getCoordsCenter();
048        element.setAttribute("xcen", "" + coords.getX());
049        element.setAttribute("ycen", "" + coords.getY());
050        element.setAttribute("turnoutControlled", "" + (turnoutControl ? "yes" : "no"));
051        element.setAttribute("class", "jmri.jmrit.display.layoutEditor.configurexml.LayoutTurntableXml");  // temporary until storage split
052        // add ray tracks
053        for (int i = 0; i < p.getNumberRays(); i++) {
054            Element rElem = new Element("raytrack");
055            rElem.setAttribute("angle", "" + p.getRayAngle(i));
056            TrackSegment t = p.getRayConnectOrdered(i);
057            if (t != null) {
058                rElem.setAttribute("connectname", t.getId());
059            }
060            rElem.setAttribute("index", "" + p.getRayIndex(i));
061            if (turnoutControl && p.getRayTurnoutName(i) != null) {
062                rElem.setAttribute("turnout", p.getRayTurnoutName(i));
063                if (p.getRayTurnoutState(i) == Turnout.THROWN) {
064                    rElem.setAttribute("turnoutstate", "thrown");
065                } else {
066                    rElem.setAttribute("turnoutstate", "closed");
067                }
068                if (p.isRayDisabled(i)) {
069                    rElem.setAttribute("disabled", "yes");
070                }
071                if (p.isRayDisabledWhenOccupied(i)) {
072                    rElem.setAttribute("disableWhenOccupied", "yes");
073                }
074            }
075            element.addContent(rElem);
076        }
077        storeLogixNG_Data(pv, element);
078        return element;
079    }
080
081    @Override
082    public boolean load(Element shared, Element perNode) {
083        log.error("Invalid method called");
084        return false;
085    }
086
087    /**
088     * Load, starting with the layout turntable element, then all the other data
089     *
090     * @param element Top level Element to unpack.
091     * @param o       LayoutEditor as an Object
092     */
093    @Override
094    public void load(Element element, Object o) {
095        // create the objects
096        LayoutEditor p = (LayoutEditor) o;
097
098        // get center point
099        String name = element.getAttribute("ident").getValue();
100        double x = 0.0;
101        double y = 0.0;
102        double radius = 25.0;
103        try {
104            x = element.getAttribute("xcen").getFloatValue();
105            y = element.getAttribute("ycen").getFloatValue();
106            radius = element.getAttribute("radius").getFloatValue();
107        } catch (org.jdom2.DataConversionException e) {
108            log.error("failed to convert layoutturntable center or radius attributes");
109        }
110        // create the new LayoutTurntable
111        LayoutTurntable lt = new LayoutTurntable(name, p);
112        LayoutTurntableView lv = new LayoutTurntableView(lt, new Point2D.Double(x, y), p);
113
114        p.addLayoutTrack(lt, lv);
115
116        lv.setCoordsCenter(new Point2D.Double(x, y));
117        log.trace("LayoutTurntable at {}, {}", x, y);
118
119        lt.setRadius(radius);
120
121        // get remaining attribute
122        Attribute a = element.getAttribute("blockname");
123        if (a != null) {
124            lt.tLayoutBlockName = a.getValue();
125        }
126
127        try {
128            lt.setTurnoutControlled(element.getAttribute("turnoutControlled").getBooleanValue());
129        } catch (DataConversionException e1) {
130            log.warn("unable to convert layout turnout turnoutControlled attribute");
131        } catch (NullPointerException e) {  // considered normal if the attribute is not present
132        }
133
134        // load ray tracks
135        List<Element> rayTrackList = element.getChildren("raytrack");
136        if (rayTrackList.size() > 0) {
137            for (Element value : rayTrackList) {
138                double angle = 0.0;
139                int index = 0;
140                try {
141                    angle = (value.getAttribute("angle")).getFloatValue();
142                    index = (value.getAttribute("index")).getIntValue();
143                } catch (DataConversionException e) {
144                    log.error("failed to convert ray track angle or index attributes");
145                }
146                String connectName = "";
147                a = value.getAttribute("connectname");
148                if (a != null) {
149                    connectName = a.getValue();
150                }
151                lt.addRayTrack(angle, index, connectName);
152                if (lt.isTurnoutControlled() && value.getAttribute("turnout") != null) {
153                    if (value.getAttribute("turnoutstate").getValue().equals("thrown")) {
154                        lt.setRayTurnout(index, value.getAttribute("turnout").getValue(), Turnout.THROWN);
155                    } else {
156                        lt.setRayTurnout(index, value.getAttribute("turnout").getValue(), Turnout.CLOSED);
157                    }
158                    try {
159                        lt.setRayDisabled(index, value.getAttribute("disabled").getBooleanValue());
160                    } catch (DataConversionException e1) {
161                        log.warn("unable to convert layout turnout disabled attribute");
162                    } catch (NullPointerException e) {  // considered normal if the attribute is not present
163                    }
164                    try {
165                        lt.setRayDisabledWhenOccupied(index, value.getAttribute("disableWhenOccupied").getBooleanValue());
166                    } catch (DataConversionException e1) {
167                        log.warn("unable to convert layout turnout disableWhenOccupied attribute");
168                    } catch (NullPointerException e) {  // considered normal if the attribute is not present
169                    }
170                }
171            }
172        }
173
174        loadLogixNG_Data(lv, element);
175    }
176
177    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LayoutTurntableViewXml.class);
178}