package de._82grfl1bif.KPI_Visualizer.structures; import de._82grfl1bif.KPI_Visualizer.data.Klasse; import de._82grfl1bif.KPI_Visualizer.helpers.Layout; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.util.Vector; import javax.management.AttributeNotFoundException; import java.awt.*; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Random; public class Foundation extends Structure { private ArrayList children = new ArrayList<>(); private Layout layout; public Foundation(int depth, Material material) { //Foundations are uniform Height this.width.x = 0; this.depth = depth; this.material = material; } public Foundation(int depth, Material material, String name) { //Foundations are uniform Height this.width.x = 0; this.name = name; this.depth = depth; this.material = material; } public ArrayList getChildren() { return children; } public void addChildren(ArrayList children) { for (Structure s : children) { s.setDepth(this.depth); } this.children.addAll(children); } public Structure generateChild(boolean isFoundation, Klasse klasse, String name) { Structure result; if (isFoundation) { result = new Foundation(this.depth + 1, nextMaterial(), name); } else { result = new Building(Material.LIME_CONCRETE, klasse, name); } this.children.add(result); return result; } public Material nextMaterial() { Material result = null; Random rand = new Random(); while ((result == this.material) || (result == null)) { int r = rand.nextInt(15); //there are 16 kins of concrete switch (r) { case 0: result = Material.BLACK_CONCRETE; break; case 1: result = Material.BROWN_CONCRETE; break; case 2: result = Material.GRAY_CONCRETE; break; case 3: result = Material.LIME_CONCRETE; break; case 4: result = Material.YELLOW_CONCRETE; break; case 5: result = Material.LIGHT_GRAY_CONCRETE; break; case 6: result = Material.RED_CONCRETE; break; case 7: result = Material.BLUE_CONCRETE; break; case 8: result = Material.CYAN_CONCRETE; break; case 9: result = Material.GREEN_CONCRETE; break; case 10: result = Material.LIGHT_BLUE_CONCRETE; break; case 11: result = Material.MAGENTA_CONCRETE; break; case 12: result = Material.ORANGE_CONCRETE; break; case 13: result = Material.PINK_CONCRETE; break; case 14: result = Material.PURPLE_CONCRETE; break; case 15: result = Material.WHITE_CONCRETE; break; } } return result; } public void removeChildren() { this.children = new ArrayList<>(); } public void optimizeLayout() { int cWith = 0; for (Structure s : children) { s.setLocation(location.clone().add(new Vector(1, depth, ((cWith) + 1)))); cWith += (s.getWidth().x + 2); } this.width.x = cWith; } @Override public Structure getFromTree(String checkName) { if (this.name != null) { if (this.name.equals(checkName)) { return this; } else { for (Structure s : this.children) { if (s.getFromTree(checkName) != null) return s.getFromTree(checkName); } } } else { for (Structure s : this.children) { if (s.getFromTree(checkName) != null) return s.getFromTree(checkName); } } return null; } public Structure findByName(String findName) { if (this.name.equals(findName)) { return this; } else { for (Structure s : this.children) { if (s.getClass() == Foundation.class) { if ((((Foundation) s).findByName(findName)) != null) { return s; } } } } return null; } private static class DepthComparator implements Comparator { @Override public int compare(Foundation o1, Foundation o2) { return Integer.compare(o1.getDepth(), o2.getDepth()); } } private static class WidthComparator implements Comparator { @Override public int compare(Structure o1, Structure o2) { return Integer.compare(o1.getWidth().x, o2.getWidth().x); } } private boolean baseFoundation = true; public void organizeFoundation() { if (this.depth == 0 && baseFoundation) { //rootElement prepwork and recursion call ArrayList allFoundations = collectAllFoundations(); baseFoundation = false; allFoundations.sort(new DepthComparator()); Collections.reverse(allFoundations); //higher Depths first for (Foundation f : allFoundations) { //if(!this.equals(f)) f.organizeFoundation(); } } else { //normal Call and recursion this.children.sort(new WidthComparator()); Collections.reverse(this.children); //Widest Building or Foundation first this.layout = new Layout(this.children); this.layout.createLayout(); this.width.x = layout.getSize(); } } private ArrayList collectAllFoundations() { //called on the base Foundation ArrayList fCollection = new ArrayList<>(); fCollection.add(this); int currentDepth = this.depth; int lastDepthAdded = -1; while (lastDepthAdded != 0) { //while there are new nextDepths in this Depth. for (int i = 0; i < fCollection.size(); i++) { if (!(fCollection.get(i).getDepth() < currentDepth)) { //if f is not part of a historical depth fCollection.addAll(fCollection.get(i).getNextDepth()); lastDepthAdded = fCollection.get(i).getNextDepth().size(); } } currentDepth += 1; } return fCollection; } private ArrayList getNextDepth() { ArrayList result = new ArrayList<>(); for (Structure s : this.children) { if (s.getClass() == Foundation.class) { result.add((Foundation) s); } else { s.setDepth(this.depth); } } for (Foundation f : result) { f.setDepth((this.depth) + 1); } return result; } public void correctAllLocations(Location location) { for (Structure s : this.children) { try { Point temp = this.layout.getCoordinateOf(s); s.setLocation(location.clone().add(temp.x, 0, temp.y)); if (s.getClass() == Foundation.class) { Foundation f = (Foundation) s; f.correctAllLocations(f.getLocation()); } } catch (AttributeNotFoundException e) { e.printStackTrace(); } } } }