/**
* Copyright 2014
* SMEdit https://github.com/StarMade/SMEdit
* SMTools https://github.com/StarMade/SMTools
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
**/
package jo.sm.logic;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import jo.sm.data.CubeIterator;
import jo.sm.data.SparseMatrix;
import jo.sm.logic.utils.StreamUtils;
import jo.sm.logic.utils.StringUtils;
import jo.sm.logic.utils.XMLEditUtils;
import jo.sm.logic.utils.XMLUtils;
import jo.sm.ship.data.Block;
import jo.vecmath.Point3i;
/**
* @Auther Jo Jaquinta for SMEdit Classic - version 1.0
**/
public class GridLogic {
private static final Logger log = Logger.getLogger(GridLogic.class.getName());
public static SparseMatrix<Block> extract(SparseMatrix<Block> grid, Point3i lower, Point3i upper) {
SparseMatrix<Block> subset = new SparseMatrix<>();
for (Iterator<Point3i> i = new CubeIterator(lower, upper); i.hasNext();) {
Point3i p = i.next();
subset.set(p, grid.get(p));
}
return subset;
}
public static void insert(SparseMatrix<Block> grid, SparseMatrix<Block> insertion, Point3i lowerInsertionPoint) {
Point3i lower = new Point3i();
Point3i upper = new Point3i();
insertion.getBounds(lower, upper);
for (Iterator<Point3i> i = new CubeIterator(lower, upper); i.hasNext();) {
Point3i insertionPoint = i.next();
Block b = insertion.get(insertionPoint);
if (b == null) {
continue;
}
Point3i gridPoint = new Point3i(insertionPoint);
gridPoint.sub(lower);
gridPoint.add(lowerInsertionPoint);
grid.set(gridPoint, b);
}
}
public static String toString(SparseMatrix<Block> grid) {
Document doc = toDocument(grid);
return XMLUtils.writeString(doc.getFirstChild());
}
public static Document toDocument(SparseMatrix<Block> grid) {
Point3i lower = new Point3i();
Point3i upper = new Point3i();
grid.getBounds(lower, upper);
Document doc = XMLUtils.newDocument();
Node root = XMLEditUtils.addElement(doc, "blocks");
XMLEditUtils.addAttribute(root, "lower", lower.x + "," + lower.y + "," + lower.z);
XMLEditUtils.addAttribute(root, "upper", upper.x + "," + upper.y + "," + upper.z);
for (Iterator<Point3i> i = grid.iteratorNonNull(); i.hasNext();) {
Point3i p = i.next();
Block b = grid.get(p);
Node block = XMLEditUtils.addElement(root, "block");
XMLEditUtils.addAttribute(block, "location", p.x + "," + p.y + "," + p.z);
XMLEditUtils.addAttribute(block, "type", String.valueOf(b.getBlockID()));
if (b.getOrientation() != 0) {
XMLEditUtils.addAttribute(block, "orientation", String.valueOf(b.getOrientation()));
}
}
return doc;
}
public static SparseMatrix<Block> fromString(String xml) {
SparseMatrix<Block> grid = new SparseMatrix<>();
Document doc = XMLUtils.readString(xml);
for (Node block : XMLUtils.findNodes(doc, "blocks/block")) {
String[] xyz = XMLUtils.getAttribute(block, "location").split(",");
Point3i p = new Point3i(Integer.parseInt(xyz[0]), Integer.parseInt(xyz[1]), Integer.parseInt(xyz[2]));
short id = Short.parseShort(XMLUtils.getAttribute(block, "type"));
Block b = new Block(id);
String ori = XMLUtils.getAttribute(block, "orientation");
if (!StringUtils.isTrivial(ori)) {
b.setOrientation(Short.parseShort(ori));
}
grid.set(p, b);
}
return grid;
}
public static byte[] toBytes(SparseMatrix<Block> grid) {
try {
ByteArrayOutputStream baos;
GZIPOutputStream os;
try (ByteArrayInputStream is = new ByteArrayInputStream(toString(grid).getBytes())) {
baos = new ByteArrayOutputStream();
os = new GZIPOutputStream(baos);
StreamUtils.copy(is, os);
}
os.close();
return baos.toByteArray();
} catch (IOException e) {
log.log(Level.WARNING, "ByteArrayOutputStream failed!", e);
e.printStackTrace();
return new byte[0];
}
}
public static SparseMatrix<Block> fromBytes(byte[] bytes) {
try {
ByteArrayOutputStream os;
try (GZIPInputStream is = new GZIPInputStream(new ByteArrayInputStream(bytes))) {
os = new ByteArrayOutputStream();
StreamUtils.copy(is, os);
}
os.close();
return fromString(new String(os.toByteArray()));
} catch (IOException e) {
log.log(Level.WARNING, "ByteArrayOutputStream failed!", e);
e.printStackTrace();
return null;
}
}
public static void delete(SparseMatrix<Block> grid, Point3i lower, Point3i upper) {
for (Iterator<Point3i> i = new CubeIterator(lower, upper); i.hasNext();) {
Point3i p = i.next();
grid.set(p, null);
}
}
}