197 lines
5.5 KiB
Java
197 lines
5.5 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();
|
|
var prevContainerLastBlock = prevContainer.getLastBlock();
|
|
if (prevContainerLastBlock != null) {
|
|
return new BlockPosition(prevContainerLastBlock);
|
|
} else {
|
|
return new BlockPosition(prevContainer);
|
|
}
|
|
} 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);
|
|
var lastBlock = lastContainer.getLastBlock();
|
|
if (lastBlock != null) {
|
|
return new BlockPosition(lastBlock);
|
|
} else {
|
|
return new BlockPosition(lastContainer);
|
|
}
|
|
}
|
|
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;
|
|
}
|
|
}
|