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
053            Element elementPoints = new Element("points");
054            ArrayList<LayoutShape.LayoutShapePoint> shapePoints = s.getPoints();
055            for (LayoutShape.LayoutShapePoint p : shapePoints) {
056                Element elementPoint = new Element("point");
057
058                elementPoint.setAttribute("type", "" + pTypeEnumMap.outputFromEnum(p.getType()));
059
060                Point2D pt = p.getPoint();
061                elementPoint.setAttribute("x", "" + pt.getX());
062                elementPoint.setAttribute("y", "" + pt.getY());
063
064                elementPoints.addContent(elementPoint);
065            }
066            element.addContent(elementPoints);
067
068            element.setAttribute("class", getClass().getName());
069        }
070        return element;
071    }
072
073    @Override
074    public boolean load(Element shared, Element perNode) {
075        log.error("Invalid method called");
076        return false;
077    }
078
079    /**
080     * Load, starting with the LayoutShape element, then all the other data
081     *
082     * @param element Top level Element to unpack.
083     * @param o       LayoutEditor as an Object
084     */
085    @Override
086    public void load(Element element, Object o) {
087        // create the objects
088        LayoutEditor p = (LayoutEditor) o;
089
090        String name = element.getAttribute("ident").getValue();
091
092        LayoutShape.LayoutShapeType type =
093                sTypeEnumMap.inputFromAttribute(element.getAttribute("type"));
094
095        // create the new LayoutShape
096        LayoutShape s = new LayoutShape(name, type, p);
097
098        Attribute a = element.getAttribute("level");
099        if (a != null) {
100            try {
101                s.setLevel(a.getIntValue());
102            } catch (DataConversionException e) {
103                log.error("Layout Shape level attribute Conversion error.");
104            }
105        } else {
106            log.error("Layout Shape level attribute not found.");
107        }
108
109        a = element.getAttribute("linewidth");
110        if (a != null) {
111            try {
112                s.setLineWidth(a.getIntValue());
113            } catch (DataConversionException e) {
114                log.error("Layout Shape line width attribute Conversion error.");
115            }
116        } else {
117            log.error("Layout Shape line width attribute not found.");
118        }
119
120        a = element.getAttribute("lineColor");
121        if (a != null) {
122            try {
123                s.setLineColor(ColorUtil.stringToColor(a.getValue()));
124            } catch (IllegalArgumentException e) {
125                s.setLineColor(Color.BLACK);
126                log.error("Invalid lineColor {}; using black", a.getValue());
127            }
128        }
129
130        a = element.getAttribute("fillColor");
131        if (a != null) {
132            try {
133                s.setFillColor(ColorUtil.stringToColor(a.getValue()));
134            } catch (IllegalArgumentException e) {
135                s.setFillColor(Color.BLACK);
136                log.error("Invalid fillColor {}; using black", a.getValue());
137            }
138        }
139
140        Element pointsElement = element.getChild("points");
141        if (pointsElement != null) {
142            List<Element> elementList = pointsElement.getChildren("point");
143            if (elementList != null) {
144                if (!elementList.isEmpty()) {
145                    for (int i = 0; i < elementList.size(); i++) {
146                        Element relem = elementList.get(i);
147
148                        LayoutShape.LayoutShapePointType pointType =
149                                pTypeEnumMap.inputFromAttribute(relem.getAttribute("type"));
150                        
151                        double x = 0.0;
152                        double y = 0.0;
153                        try {
154                            x = (relem.getAttribute("x")).getFloatValue();
155                            y = (relem.getAttribute("y")).getFloatValue();
156                        } catch (DataConversionException e) {
157                            log.error("failed to convert Layout Shape point #{}coordinates attributes", i);
158                        }
159                        s.addPoint(pointType, new Point2D.Double(x, y));
160                    }
161                } else {
162                    log.error("No Layout Shape point elements");
163                }
164            } else {
165                log.error("Layout Shape point elements not found.");
166            }
167        } else {
168            log.error("Layout Shape points element not found.");
169        }
170        p.getLayoutShapes().add(s);
171        p.unionToPanelBounds(s.getBounds());
172    }
173
174    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LayoutShapeXml.class);
175}