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        boolean dispatcherManaged = p.isDispatcherManaged();
052        if (dispatcherManaged) {
053            String exitMastName = p.getExitSignalMastName();
054            if (exitMastName != null && !exitMastName.isEmpty()) {
055                element.setAttribute("exitmast", exitMastName);
056            }
057            String bufferMastName = p.getBufferSignalMastName();
058            if (bufferMastName != null && !bufferMastName.isEmpty()) {
059                element.setAttribute("buffermast", bufferMastName);
060            }
061            element.setAttribute("signalIconPlacement", "" + p.getSignalIconPlacement());
062            element.setAttribute("dispatcherManaged", "yes");
063        }
064        element.setAttribute("class", "jmri.jmrit.display.layoutEditor.configurexml.LayoutTurntableXml");  // temporary until storage split
065        // add ray tracks
066        for (int i = 0; i < p.getNumberRays(); i++) {
067            Element rElem = new Element("raytrack");
068            rElem.setAttribute("angle", "" + p.getRayAngle(i));
069            TrackSegment t = p.getRayConnectOrdered(i);
070            if (t != null) {
071                rElem.setAttribute("connectname", t.getId());
072            }
073            if (dispatcherManaged) {
074                String mastName = p.getRayTrackList().get(i).getApproachMastName();
075                if (mastName != null && !mastName.isEmpty()) {
076                    rElem.setAttribute("approachmast", mastName);
077                }
078            }
079            rElem.setAttribute("index", "" + p.getRayIndex(i));
080            if (turnoutControl && p.getRayTurnoutName(i) != null) {
081                rElem.setAttribute("turnout", p.getRayTurnoutName(i));
082                if (p.getRayTurnoutState(i) == Turnout.THROWN) {
083                    rElem.setAttribute("turnoutstate", "thrown");
084                } else {
085                    rElem.setAttribute("turnoutstate", "closed");
086                }
087                if (p.isRayDisabled(i)) {
088                    rElem.setAttribute("disabled", "yes");
089                }
090                if (p.isRayDisabledWhenOccupied(i)) {
091                    rElem.setAttribute("disableWhenOccupied", "yes");
092                }
093            }
094            element.addContent(rElem);
095        }
096        storeLogixNG_Data(pv, element);
097        return element;
098    }
099
100    @Override
101    public boolean load(Element shared, Element perNode) {
102        log.error("Invalid method called");
103        return false;
104    }
105
106    /**
107     * Load, starting with the layout turntable element, then all the other data
108     *
109     * @param element Top level Element to unpack.
110     * @param o       LayoutEditor as an Object
111     */
112    @Override
113    public void load(Element element, Object o) {
114        // create the objects
115        LayoutEditor p = (LayoutEditor) o;
116
117        // get center point
118        String name = element.getAttribute("ident").getValue();
119        double x = 0.0;
120        double y = 0.0;
121        double radius = 25.0;
122        try {
123            x = element.getAttribute("xcen").getFloatValue();
124            y = element.getAttribute("ycen").getFloatValue();
125            radius = element.getAttribute("radius").getFloatValue();
126        } catch (org.jdom2.DataConversionException e) {
127            log.error("failed to convert layoutturntable center or radius attributes");
128        }
129        // create the new LayoutTurntable
130        LayoutTurntable lt = new LayoutTurntable(name, p);
131        LayoutTurntableView lv = new LayoutTurntableView(lt, new Point2D.Double(x, y), p);
132
133        p.addLayoutTrack(lt, lv);
134
135        lv.setCoordsCenter(new Point2D.Double(x, y));
136        log.trace("LayoutTurntable at {}, {}", x, y);
137
138        lt.setRadius(radius);
139
140        // get remaining attribute
141        Attribute a = element.getAttribute("blockname");
142        if (a != null) {
143            lt.tLayoutBlockName = a.getValue();
144        }
145
146        a = element.getAttribute("turnoutControlled");
147        if (a != null) {
148            lt.setTurnoutControlled("yes".equalsIgnoreCase(a.getValue()));
149        }
150
151        a = element.getAttribute("dispatcherManaged");
152        if (a != null) {
153            lt.setDispatcherManaged("yes".equalsIgnoreCase(a.getValue()));
154            if (lt.isDispatcherManaged()) {
155                a = element.getAttribute("exitmast");
156                if (a != null) {
157                    lt.tExitSignalMastName = a.getValue();
158                }
159                a = element.getAttribute("buffermast");
160                if (a != null) {
161                    lt.tBufferSignalMastName = a.getValue();
162                }
163                a = element.getAttribute("signalIconPlacement");
164                if (a != null) {
165                    try {
166                        lt.setSignalIconPlacement(a.getIntValue());
167                    } catch (DataConversionException e) {
168                        log.error("failed to convert signalIconPlacement attribute");
169                    }
170                }
171            }
172        }
173
174        // load ray tracks
175        List<Element> rayTrackList = element.getChildren("raytrack");
176        if (rayTrackList.size() > 0) {
177            for (Element value : rayTrackList) {
178                double angle = 0.0;
179                int index = 0;
180                try {
181                    angle = (value.getAttribute("angle")).getFloatValue();
182                    index = (value.getAttribute("index")).getIntValue();
183                } catch (DataConversionException e) {
184                    log.error("failed to convert ray track angle or index attributes");
185                }
186                String connectName = "";
187                a = value.getAttribute("connectname");
188                if (a != null) {
189                    connectName = a.getValue();
190                }
191                LayoutTurntable.RayTrack ray = lt.addRay(angle);
192                ray.connectName = connectName;
193                if (lt.isDispatcherManaged()) {
194                    a = value.getAttribute("approachmast");
195                    if (a != null) {
196                        ray.approachMastName = a.getValue();
197                    }
198                }
199                if (lt.isTurnoutControlled() && value.getAttribute("turnout") != null) {
200                    if (value.getAttribute("turnoutstate").getValue().equals("thrown")) {
201                        lt.setRayTurnout(index, value.getAttribute("turnout").getValue(), Turnout.THROWN);
202                    } else {
203                        lt.setRayTurnout(index, value.getAttribute("turnout").getValue(), Turnout.CLOSED);
204                    }
205                    a = value.getAttribute("disabled");
206                    if (a != null) {
207                        lt.setRayDisabled(index, "yes".equalsIgnoreCase(a.getValue()));
208                    }
209                    a = value.getAttribute("disableWhenOccupied");
210                    if (a != null) {
211                        lt.setRayDisabledWhenOccupied(index, "yes".equalsIgnoreCase(a.getValue()));
212                    }
213                }
214            }
215        }
216
217        loadLogixNG_Data(lv, element);
218    }
219
220    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LayoutTurntableViewXml.class);
221}