package org.apache.poi.xdgf.usermodel.section;
import java.awt.geom.Path2D;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.xdgf.geom.SplineCollector;
import org.apache.poi.xdgf.usermodel.XDGFCell;
import org.apache.poi.xdgf.usermodel.XDGFShape;
import org.apache.poi.xdgf.usermodel.XDGFSheet;
import org.apache.poi.xdgf.usermodel.section.geometry.Ellipse;
import org.apache.poi.xdgf.usermodel.section.geometry.GeometryRow;
import org.apache.poi.xdgf.usermodel.section.geometry.GeometryRowFactory;
import org.apache.poi.xdgf.usermodel.section.geometry.InfiniteLine;
import org.apache.poi.xdgf.usermodel.section.geometry.SplineKnot;
import org.apache.poi.xdgf.usermodel.section.geometry.SplineStart;
import com.microsoft.schemas.office.visio.x2012.main.RowType;
import com.microsoft.schemas.office.visio.x2012.main.SectionType;
public class GeometrySection extends XDGFSection {
GeometrySection _master;
SortedMap<Long, GeometryRow> _rows = new TreeMap<>();
public GeometrySection(SectionType section, XDGFSheet containingSheet) {
super(section, containingSheet);
for (RowType row: section.getRowArray()) {
if (_rows.containsKey(row.getIX()))
throw new POIXMLException("Index element '" + row.getIX() + "' already exists");
_rows.put(row.getIX(), GeometryRowFactory.load(row));
}
}
@Override
public void setupMaster(XDGFSection master) {
_master = (GeometrySection)master;
for (Entry<Long, GeometryRow> entry : _rows.entrySet()) {
GeometryRow masterRow = _master._rows.get(entry.getKey());
if (masterRow != null) {
try {
entry.getValue().setupMaster(masterRow);
} catch (ClassCastException e) {
}
}
}
}
public Boolean getNoShow() {
Boolean noShow = XDGFCell.maybeGetBoolean(_cells, "NoShow");
if (noShow == null) {
if (_master != null)
return _master.getNoShow();
return false;
}
return noShow;
}
public Iterable<GeometryRow> getCombinedRows() {
return new CombinedIterable<>(_rows,
_master == null ? null : _master._rows);
}
public Path2D.Double getPath(XDGFShape parent) {
Iterator<GeometryRow> rows = getCombinedRows().iterator();
GeometryRow first = rows.hasNext() ? rows.next() : null;
if (first instanceof Ellipse) {
return ((Ellipse)first).getPath();
} else if (first instanceof InfiniteLine) {
return ((InfiniteLine)first).getPath();
} else if (first instanceof SplineStart) {
throw new POIXMLException("SplineStart must be preceded by another type");
} else {
Path2D.Double path = new Path2D.Double();
SplineCollector renderer = null;
GeometryRow row;
while (true) {
if (first != null) {
row = first;
first = null;
} else {
if (!rows.hasNext())
break;
row = rows.next();
}
if (row instanceof SplineStart) {
if (renderer != null)
throw new POIXMLException("SplineStart found multiple times!");
renderer = new SplineCollector((SplineStart) row);
} else if (row instanceof SplineKnot) {
if (renderer == null)
throw new POIXMLException("SplineKnot found without SplineStart!");
renderer.addKnot((SplineKnot) row);
} else {
if (renderer != null) {
renderer.addToPath(path, parent);
renderer = null;
}
row.addToPath(path, parent);
}
}
if (renderer != null)
renderer.addToPath(path, parent);
return path;
}
}
}