import { backBlockLocation, directionState, getLeftBlock, getRightBlock } from '../util/globalVariables';

const sofaSideOffsets = {
	north: { right: { x: 1, y: 0, z: 0, allow: "east" }, left: { x: -1, y: 0, z: 0, allow: "west" } },
	south: { right: { x: -1, y: 0, z: 0, allow: "west" }, left: { x: 1, y: 0, z: 0, allow: "east" } },
	west:  { right: { x: 0, y: 0, z: -1, allow: "north" }, left: { x: 0, y: 0, z: 1, allow: "south" } },
	east:  { right: { x: 0, y: 0, z: 1, allow: "south" }, left: { x: 0, y: 0, z: -1, allow: "north" } }
};
const sofaCornerOffsets = {
	north: [
		{ location: { x: -1, y: 0, z: 0 }, requiredDirection: "north", check: { x: 0, y: 0, z: 1, direction: "east" } },
		{ location: { x: 1, y: 0, z: 0 }, requiredDirection: "north", check: { x: 0, y: 0, z: 1, direction: "west" } }
	],
	south: [
		{ location: { x: 1, y: 0, z: 0 }, requiredDirection: "south", check: { x: 0, y: 0, z: -1, direction: "west" } },
		{ location: { x: -1, y: 0, z: 0 }, requiredDirection: "south", check: { x: 0, y: 0, z: -1, direction: "east" } }
	],
	west: [
		{ location: { x: 0, y: 0, z: -1 }, requiredDirection: "west", check: { x: 1, y: 0, z: 0, direction: "south" } },
		{ location: { x: 0, y: 0, z: 1 }, requiredDirection: "west", check: { x: 1, y: 0, z: 0, direction: "north" } }
	],
	east: [
		{ location: { x: 0, y: 0, z: 1 }, requiredDirection: "east", check: { x: -1, y: 0, z: 0, direction: "north" } },
		{ location: { x: 0, y: 0, z: -1 }, requiredDirection: "east", check: { x: -1, y: 0, z: 0, direction: "south" } }
	]
};
export class McfSofa {
	constructor() {
		this.onPlace = this.onPlace.bind(this);
		this.onPlayerBreak = this.onPlayerBreak.bind(this);
	}
	checkSide(block, direction, { x, y, z, allow }) {
		const sideBlock = block.offset({ x, y, z });
		const sideDirection = sideBlock.permutation.getState(directionState);
		return sideBlock.hasTag("mr:sofa") && (sideDirection === direction || sideDirection === allow) ? 1 : 0;
	}
	update(block) {
		const direction = block.permutation.getState(directionState);
		const sideOffsets = sofaSideOffsets[direction];
		block.setPermutation(block.permutation
			.withState("mr:r", this.checkSide(block, direction, sideOffsets.right))
			.withState("mr:l", this.checkSide(block, direction, sideOffsets.left))
		)
		let cornerState = 0;
		for (const prop of sofaCornerOffsets[direction]) {
			const targetBlock = block.offset(prop.location);
			const checkBlock = block.offset(prop.check);
			if (targetBlock.hasTag("mr:sofa") && targetBlock.permutation.getState(directionState) === prop.requiredDirection && checkBlock.permutation.getState(directionState) === prop.check.direction) {
				cornerState = 1;
				break;
			}
		}
		block.setPermutation(block.permutation.withState("mr:f", cornerState));
	}
	updateNearest(block, permutation) {
		const direction = permutation.getState(directionState);
		const rightBlock = getLeftBlock(block, direction);
		const leftBlock = getRightBlock(block, direction);
		const frontBlock = block.offset(backBlockLocation[direction]);

		if (rightBlock.hasTag("mr:sofa")) this.update(rightBlock);
		if (leftBlock.hasTag("mr:sofa")) this.update(leftBlock);
		if (frontBlock.hasTag("mr:sofa")) this.update(frontBlock);
	}
	onPlace(e) {
		this.update(e.block);
		this.updateNearest(e.block, e.block.permutation);
	}
	onPlayerBreak(e) {
		this.updateNearest(e.block, e.brokenBlockPermutation);
	}
}