package edu.stanford.nlp.sempre.interactive.voxelurn; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import org.testng.collections.Lists; import edu.stanford.nlp.sempre.Json; import edu.stanford.nlp.sempre.interactive.Item; //individual stacks public class Voxel extends Item { public Color color; int row, col, height; int age; public Voxel(int row, int col, int height, String color) { this(row, col, height); this.color = Color.fromString(color); } public Voxel() { this.row = -1; this.col = 0; this.height = 0; this.color = Color.fromString("None"); this.names = new HashSet<>(); this.age = 0; } // used as a key public Voxel(int row, int col, int height) { this(); this.row = row; this.col = col; this.height = height; } public Voxel move(Direction dir) { switch (dir) { case Back: this.row += 1; break; case Front: this.row -= 1; break; case Left: this.col += 1; break; case Right: this.col -= 1; break; case Top: this.height += 1; break; case Bot: this.height -= 1; break; case None: break; } return this; } public Voxel copy(Direction dir) { Voxel c = this.clone(); switch (dir) { case Back: c.row += 1; break; case Front: c.row -= 1; break; case Left: c.col += 1; break; case Right: c.col -= 1; break; case Top: c.height += 1; break; case Bot: c.height -= 1; break; case None: break; } return c; } @Override public Object get(String property) { Object propval; if (property.equals("height")) propval = new Integer(this.height); else if (property.equals("row")) propval = new Integer(this.row); else if (property.equals("col")) propval = new Integer(this.col); else if (property.equals("age")) propval = new Integer(this.age); else if (property.equals("color")) propval = this.color.toString().toLowerCase(); // else if (property.equals("name")) // propval = this.names; else throw new RuntimeException("getting property " + property + " is not supported."); return propval; } @Override public void update(String property, Object value) { // updating with empty set does nothing, throw something? if (value instanceof Set && ((Set) value).size() == 0) return; if (value instanceof Set && ((Set) value).size() == 1) value = ((Set) value).iterator().next(); if (property.equals("height") && value instanceof Integer) this.height = (Integer) value; else if (property.equals("row") && value instanceof Integer) this.row = (Integer) value; else if (property.equals("col") && value instanceof Integer) this.height = (Integer) value; else if (property.equals("color") && value instanceof String) this.color = Color.fromString(value.toString()); else if (value instanceof Set) throw new RuntimeException(String.format( "Updating %s to %s is not allowed," + " which has %d values, but a property can only have 1 value. ", property, value.toString(), ((Set) value).size())); else throw new RuntimeException( String.format("Updating property %s to %s is not allowed! (type %s is not expected for %s) ", property, value.toString(), value.getClass(), property)); } @SuppressWarnings("unchecked") public static Voxel fromJSON(String json) { List<Object> props = Json.readValueHard(json, List.class); return fromJSONObject(props); } @SuppressWarnings("unchecked") public static Voxel fromJSONObject(List<Object> props) { Voxel retcube = new Voxel(); retcube.row = ((Integer) props.get(0)); retcube.col = ((Integer) props.get(1)); retcube.height = ((Integer) props.get(2)); retcube.color = Color.fromString(((String) props.get(3))); retcube.names.addAll((List<String>) props.get(4)); return retcube; } public Object toJSON() { List<String> globalNames = names.stream().collect(Collectors.toList()); List<Object> cube = Lists.newArrayList(row, col, height, color.toString(), globalNames); return cube; } @Override public Voxel clone() { Voxel c = new Voxel(this.row, this.col, this.height, this.color.toString()); return c; } @Override public int hashCode() { final int prime = 19; int result = 1; result = prime * result + col; result = prime * result + height; result = prime * result + row; // result = prime * result + (this.color == (CubeColor.Anchor)? 1 : 0); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Voxel other = (Voxel) obj; if (col != other.col) return false; if (height != other.height) return false; if (row != other.row) return false; // only anchored colors need to be the same. // if (this.color == CubeColor.Anchor ^ other.color == CubeColor.Anchor && // this.height == 0) // return false; return true; } @Override public boolean selected() { return names.contains("S"); } @Override public void select(boolean s) { if (s) names.add("S"); else names.remove("S"); } @Override public String toString() { return this.toJSON().toString(); } }