WarpPI/core/src/main/java/it/cavallium/warppi/gui/expression/blocks/BlockPosition.java

187 lines
5.2 KiB
Java

package it.cavallium.warppi.gui.expression.blocks;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntCollections;
import org.apache.commons.lang3.NotImplementedException;
import java.util.Collections;
import java.util.Objects;
public final class BlockPosition {
private final BlockOrContainer pos;
public BlockPosition(BlockOrContainer pos) {
this.pos = pos;
}
public BlockPosition(Block block) {
this.pos = block;
}
public BlockPosition(BlockContainer container) {
this.pos = container;
}
public boolean isBlock() {
return pos instanceof Block;
}
public boolean isContainer() {
return pos instanceof BlockContainer;
}
public Block getBlock() {
return (Block) pos;
}
public BlockContainer getContainer() {
return (BlockContainer) pos;
}
public BlockOrContainer get() {
return pos;
}
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null || obj.getClass() != this.getClass()) return false;
var that = (BlockPosition) obj;
return Objects.equals(this.pos, that.pos);
}
@Override
public int hashCode() {
return Objects.hash(pos);
}
@Override
public String toString() {
return "BlockPosition[" +
"pos=" + pos + ']';
}
public BlockPosition getNext() {
if (pos instanceof BlockContainer) {
var container = (BlockContainer) pos;
var content = container.getContent();
if (content.isEmpty()) {
BlockContainer nextContainer;
if (container.hasParent()) {
var containers = container.getParentBlock().getInnerContainers();
var it = containers.listIterator(containers.indexOf(container) + 1);
nextContainer = it.hasNext() ? it.next() : null;
} else {
nextContainer = null;
}
if (nextContainer != null) {
return new BlockPosition(nextContainer);
} else {
var parentBlock = container.getParentBlock();
return parentBlock != null ? new BlockPosition(parentBlock) : null;
}
} else {
var targetBlock = content.get(0);
var innerContainers = targetBlock.getInnerContainers();
if (innerContainers != null && !innerContainers.isEmpty()) {
return new BlockPosition(innerContainers.get(0));
} else {
return new BlockPosition(targetBlock);
}
}
} else if (pos instanceof Block) {
var block = (Block) pos;
var ref = block.getReference();
var nextBlock = ref.getNextBlock();
if (nextBlock == null) {
var container = block.getParentContainer();
BlockContainer nextContainer;
if (container.hasParent()) {
var containers = container.getParentBlock().getInnerContainers();
var it = containers.listIterator(containers.indexOf(container) + 1);
nextContainer = it.hasNext() ? it.next() : null;
} else {
nextContainer = null;
}
if (nextContainer != null) {
return new BlockPosition(nextContainer);
} else {
var parentBlock = container.getParentBlock();
return parentBlock != null ? new BlockPosition(parentBlock) : null;
}
} else {
var targetBlock = nextBlock.get();
var innerContainers = targetBlock.getInnerContainers();
if (innerContainers != null && !innerContainers.isEmpty()) {
return new BlockPosition(innerContainers.get(0));
} else {
return new BlockPosition(targetBlock);
}
}
} else {
throw new UnsupportedOperationException();
}
}
public BlockPosition getPrevious() {
if (pos instanceof BlockContainer) {
var container = (BlockContainer) pos;
if (container.hasParent()) {
var parentBlock = container.getParentBlock();
var innerContainers = parentBlock.getInnerContainers();
if (innerContainers != null) {
var it = innerContainers.listIterator(innerContainers.indexOf(container));
if (it.hasPrevious()) {
var prevContainer = it.previous();
return prevContainer.getLastPosition();
} else {
var parentContainer = parentBlock.getParentContainer();
var blocks = parentContainer.getContentUnsafe();
var bIt = blocks.listIterator(blocks.indexOf(parentBlock));
if (bIt.hasPrevious()) {
return new BlockPosition(bIt.previous());
} else {
return new BlockPosition(parentContainer);
}
}
} else {
throw new UnsupportedOperationException();
}
} else {
return null;
}
} else if (pos instanceof Block) {
var block = (Block) pos;
var innerContainers = block.getInnerContainers();
if (innerContainers != null) {
var lastContainer = innerContainers.get(innerContainers.size() - 1);
return lastContainer.getLastPosition();
}
var ref = block.getReference();
var prevBlock = ref.getPreviousBlock();
if (prevBlock == null) {
var container = block.getParentContainer();
return new BlockPosition(container);
} else {
var targetBlock = prevBlock.get();
return new BlockPosition(targetBlock);
}
} else {
throw new UnsupportedOperationException();
}
}
public IntArrayList getURL() {
var url = new IntArrayList();
var parent = pos;
while (parent != null) {
var index = parent.getIndex();
if (index == -1) break;
url.add(index);
parent = parent.getParent();
}
Collections.reverse(url);
return url;
}
}