001package jmri.jmrit.display.layoutEditor.configurexml;
002
003import java.awt.Color;
004import java.awt.geom.Point2D;
005import java.util.ArrayList;
006import java.util.List;
007import jmri.configurexml.AbstractXmlAdapter;
008import jmri.jmrit.display.layoutEditor.LayoutEditor;
009import jmri.jmrit.display.layoutEditor.LayoutShape;
010import jmri.util.ColorUtil;
011import org.jdom2.Attribute;
012import org.jdom2.DataConversionException;
013import org.jdom2.Element;
014
015/**
016 * This module handles configuration for LayoutShape objects for a LayoutEditor.
017 *
018 * @author George Warner Copyright (c) 2017-2018
019 */
020public class LayoutShapeXml extends AbstractXmlAdapter {
021
022    public LayoutShapeXml() {
023    }
024
025    // default mapping fine
026    static final EnumIoNames<LayoutShape.LayoutShapeType> sTypeEnumMap
027            = new EnumIoNames<>(LayoutShape.LayoutShapeType.class);
028    static final EnumIoNames<LayoutShape.LayoutShapePointType> pTypeEnumMap
029            = new EnumIoNames<>(LayoutShape.LayoutShapePointType.class);
030
031    /**
032     * Default implementation for storing the contents of a LayoutShape
033     *
034     * @param o Object to store, of type LayoutShape
035     * @return Element containing the complete info
036     */
037    @Override
038    public Element store(Object o) {
039        LayoutShape s = (LayoutShape) o;
040        Element element = null;
041
042        if (s.getNumberPoints() > 0) {
043            element = new Element("layoutShape");
044
045            // include attributes
046            element.setAttribute("ident", s.getName());
047            element.setAttribute("type", "" + sTypeEnumMap.outputFromEnum(s.getType()));
048            element.setAttribute("level", "" + s.getLevel());
049            element.setAttribute("linewidth", "" + s.getLineWidth());
050            element.setAttribute("lineColor", ColorUtil.colorToHexString(s.getLineColor()));
051            element.setAttribute("fillColor", ColorUtil.colorToHexString(s.getFillColor()));
052            if (s.isHidden()) {
053                element.setAttribute("hidden", "true");
054            }
055
056            Element elementPoints = new Element("points");
057            ArrayList<LayoutShape.LayoutShapePoint> shapePoints = s.getPoints();
058            for (LayoutShape.LayoutShapePoint p : shapePoints) {
059                Element elementPoint = new Element("point");
060
061                elementPoint.setAttribute("type", "" + pTypeEnumMap.outputFromEnum(p.getType()));
062
063                Point2D pt = p.getPoint();
064                elementPoint.setAttribute("x", "" + pt.getX());
065                elementPoint.setAttribute("y", "" + pt.getY());
066
067                elementPoints.addContent(elementPoint);
068            }
069            element.addContent(elementPoints);
070
071            element.setAttribute("class", getClass().getName());
072        }
073        return element;
074    }
075
076    @Override
077    public boolean load(Element shared, Element perNode) {
078        log.error("Invalid method called");
079        return false;
080    }
081
082    /**
083     * Load, starting with the LayoutShape element, then all the other data
084     *
085     * @param element Top level Element to unpack.
086     * @param o       LayoutEditor as an Object
087     */
088    @Override
089    public void load(Element element, Object o) {
090        // create the objects
091        LayoutEditor p = (LayoutEditor) o;
092
093        String name = element.getAttribute("ident").getValue();
094
095        LayoutShape.LayoutShapeType type =
096                sTypeEnumMap.inputFromAttribute(element.getAttribute("type"));
097
098        // create the new LayoutShape
099        LayoutShape s = new LayoutShape(name, type, p);
100
101        Attribute a = element.getAttribute("level");
102        if (a != null) {
103            try {
104                s.setLevel(a.getIntValue());
105            } catch (DataConversionException e) {
106                log.error("Layout Shape level attribute Conversion error.");
107            }
108        } else {
109            log.error("Layout Shape level attribute not found.");
110        }
111
112        a = element.getAttribute("linewidth");
113        if (a != null) {
114            try {
115                s.setLineWidth(a.getIntValue());
116            } catch (DataConversionException e) {
117                log.error("Layout Shape line width attribute Conversion error.");
118            }
119        } else {
120            log.error("Layout Shape line width attribute not found.");
121        }
122
123        a = element.getAttribute("lineColor");
124        if (a != null) {
125            try {
126                s.setLineColor(ColorUtil.stringToColor(a.getValue()));
127            } catch (IllegalArgumentException e) {
128                s.setLineColor(Color.BLACK);
129                log.error("Invalid lineColor {}; using black", a.getValue());
130            }
131        }
132
133        a = element.getAttribute("fillColor");
134        if (a != null) {
135            try {
136                s.setFillColor(ColorUtil.stringToColor(a.getValue()));
137            } catch (IllegalArgumentException e) {
138                s.setFillColor(Color.BLACK);
139                log.error("Invalid fillColor {}; using black", a.getValue());
140            }
141        }
142
143        a = element.getAttribute("hidden");
144        if (a != null) {
145            // The attribute only exists when true
146            s.setHidden(true);
147        }
148
149        Element pointsElement = element.getChild("points");
150        if (pointsElement != null) {
151            List<Element> elementList = pointsElement.getChildren("point");
152            if (elementList != null) {
153                if (!elementList.isEmpty()) {
154                    for (int i = 0; i < elementList.size(); i++) {
155                        Element relem = elementList.get(i);
156
157                        LayoutShape.LayoutShapePointType pointType =
158                                pTypeEnumMap.inputFromAttribute(relem.getAttribute("type"));
159
160                        double x = 0.0;
161                        double y = 0.0;
162                        try {
163                            x = (relem.getAttribute("x")).getFloatValue();
164                            y = (relem.getAttribute("y")).getFloatValue();
165                        } catch (DataConversionException e) {
166                            log.error("failed to convert Layout Shape point #{}coordinates attributes", i);
167                        }
168                        s.addPoint(pointType, new Point2D.Double(x, y));
169                    }
170                } else {
171                    log.error("No Layout Shape point elements");
172                }
173            } else {
174                log.error("Layout Shape point elements not found.");
175            }
176        } else {
177            log.error("Layout Shape points element not found.");
178        }
179        p.getLayoutShapes().add(s);
180        p.unionToPanelBounds(s.getBounds());
181    }
182
183    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LayoutShapeXml.class);
184}