001package jmri.jmrit.display.controlPanelEditor.shape.configurexml;
002
003import java.awt.geom.GeneralPath;
004import java.awt.geom.PathIterator;
005
006import jmri.configurexml.JmriConfigureXmlException;
007import jmri.jmrit.display.Editor;
008import jmri.jmrit.display.Positionable;
009import jmri.jmrit.display.controlPanelEditor.shape.PositionablePolygon;
010
011import org.jdom2.Element;
012import org.slf4j.Logger;
013import org.slf4j.LoggerFactory;
014
015/**
016 * Handle configuration for display.PositionableShape objects
017 *
018 * @author Pete Cressman Copyright (c) 2012
019 */
020public class PositionablePolygonXml extends PositionableShapeXml {
021
022    public PositionablePolygonXml() {
023    }
024
025    /**
026     * Default implementation for storing the contents of a PositionableShape
027     *
028     * @param o Object to store, of type PositionableShape
029     * @return Element containing the complete info
030     */
031    @Override
032    public Element store(Object o) {
033        PositionablePolygon p = (PositionablePolygon) o;
034
035        if (!p.isActive()) {
036            return null;  // if flagged as inactive, don't store
037        }
038        Element element = new Element("positionablePolygon");
039        storeCommonAttributes(p, element);
040        element.addContent(storePath(p));
041
042        element.setAttribute("class", "jmri.jmrit.display.controlPanelEditor.shape.configurexml.PositionablePolygonXml");
043        return element;
044    }
045
046    protected Element storePath(PositionablePolygon p) {
047        Element elem = new Element("path");
048        PathIterator iter = p.getPathIterator(null);
049        float[] coord = new float[6];
050        while (!iter.isDone()) {
051            int type = iter.currentSegment(coord);
052            elem.addContent(storeVertex(type, coord));
053            iter.next();
054        }
055        return elem;
056    }
057
058    private Element storeVertex(int type, float[] coord) {
059        Element elem = new Element("vertex");
060        elem.setAttribute("type", String.valueOf(type));
061        for (int i = 0; i < coord.length; i++) {
062            elem.setAttribute("idx" + i, String.valueOf(coord[i]));
063        }
064        return elem;
065    }
066
067    /**
068     * Create a PositionableShape, then add to a target JLayeredPane
069     *
070     * @param element Top level Element to unpack.
071     * @param o       Editor as an Object
072     * @throws JmriConfigureXmlException when a error prevents creating the objects as as
073     *                   required by the input XML
074     */
075    @Override
076    public void load(Element element, Object o) throws JmriConfigureXmlException {
077        // create the objects
078        Editor ed = (Editor) o;
079        GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
080        Element elem = element.getChild("path");
081
082        float[] coord = new float[6];
083        java.util.List<Element> list = elem.getChildren("vertex");
084        for (Element e : list) {
085            int type = getInt(e, "type");
086            for (int i = 0; i < coord.length; i++) {
087                coord[i] = getFloat(e, "idx" + i);
088            }
089            switch (type) {
090                case PathIterator.SEG_MOVETO:
091                    path.moveTo(coord[0], coord[1]);
092                    break;
093                case PathIterator.SEG_LINETO:
094                    path.lineTo(coord[0], coord[1]);
095                    break;
096                case PathIterator.SEG_QUADTO:
097                    path.quadTo(coord[0], coord[1], coord[2], coord[3]);
098                    break;
099                case PathIterator.SEG_CUBICTO:
100                    path.curveTo(coord[0], coord[1], coord[2], coord[3], coord[4], coord[5]);
101                    break;
102                case PathIterator.SEG_CLOSE:
103                    path.closePath();
104                    break;
105                default:
106                    log.warn("Unhandled type: {}", type);
107                    break;
108            }
109        }
110        PositionablePolygon ps = new PositionablePolygon(ed, path);
111        // get object class and determine editor being used
112        try {
113            ed.putItem(ps);
114        } catch (Positionable.DuplicateIdException e) {
115            throw new JmriConfigureXmlException("Positionable id is not unique", e);
116        }
117        // load individual item's option settings after editor has set its global settings
118        loadCommonAttributes(ps, Editor.MARKERS, element);
119    }
120    private final static Logger log = LoggerFactory.getLogger(PositionablePolygonXml.class);
121}