package it.cavallium.warppi.gui.expression.blocks;

import it.unimi.dsi.fastutil.objects.ObjectArrayList;

public class BlockReference<T extends Block> {
	private final T block;
	private final BlockContainer container;
	private int cachedBlockPosition;
	private final ObjectArrayList<Block> containerBlocks;

	public BlockReference(final T block, final int cachedBlockPosition, final ObjectArrayList<Block> containerBlocks, final BlockContainer container) {
		this.block = block;
		this.cachedBlockPosition = cachedBlockPosition;
		this.containerBlocks = containerBlocks;
		this.container = container;
	}

	public T get() {
		return block;
	}

	public BlockContainer getContainer() {
		return container;
	}

	public int getIndex() {
		if (containerBlocks.size() > cachedBlockPosition && cachedBlockPosition >= 0
			&& containerBlocks.get(cachedBlockPosition) == block) {
			return cachedBlockPosition;
		} else {
			return cachedBlockPosition = containerBlocks.indexOf(block);
		}
	}

	public BlockReference<?> getNextBlock() {
		return getBlockAtSafe(getIndex() + 1);
	}

	public boolean hasNextBlock() {
		return isInsideBounds(getIndex() + 1);
	}

	public BlockReference<?> getPreviousBlock() {
		return getBlockAtSafe(getIndex() - 1);
	}

	public boolean hasPreviousBlock() {
		return isInsideBounds(getIndex() - 1);
	}

	private BlockReference<?> getBlockAtSafe(final int i) {
		if (isInsideBounds(i)) {
			return container.getBlockAt(i);
		}
		return null;
	}

	private boolean isInsideBounds(final int i) {
		return i < container.getSize() && i >= 0;
	}

}
