import { flipDir, getADirection, getADirectionState, getCounterClockwiseDir, isAxisVertical, isSameAxis, offsetVec } from "../util/dirUtils";
import { McStates } from "../reg/mcStates";
import { suppEvents } from "../suppEventHandler";
import { SuppStates } from "../reg/suppStates";
import { SuppTags } from "../reg/suppTags";
export const StairsPlacementComponent = {
    beforeOnPlayerPlace(event) {
        const block = event.block;
        const player = event.player;
        const newShape = getStairsShape(event.permutationToPlace, block.location, block.dimension);
        event.permutationToPlace = event.permutationToPlace.withState(SuppStates.StairShape, newShape);
    }
};
suppEvents.subscribeOnNeighborChanged((event) => {
    const block = event.block;
    if (block.hasTag(SuppTags.Stairs)) {
        if (!isAxisVertical(event.fromDir)) {
            const newShape = getStairsShape(block.permutation, block.location, block.dimension);
            block.setPermutation(block.permutation.withState(SuppStates.StairShape, newShape));
        }
    }
    //other bedrock brain fairt moment. stairs don't have as tate that encodes their shape......
    /*
    else if (event.neighborBlock.hasTag(SuppTags.Stairs) &&
        block.typeId.endsWith("stairs") && block.typeId.startsWith("minecraft")) {

        //update vanilla stairs
    }*/
});
function toBedrockWeirdState(stairShape, dir) {
    switch (stairShape) {
        case StairsShape.STRAIGHT:
            return 0;
        case StairsShape.INNER_LEFT:
            return 1;
        case StairsShape.INNER_RIGHT:
            return 2;
        case StairsShape.OUTER_LEFT:
            return 3;
        case StairsShape.OUTER_RIGHT:
            return 4;
    }
}
var StairsShape;
(function (StairsShape) {
    StairsShape["STRAIGHT"] = "straight";
    StairsShape["INNER_LEFT"] = "inner_left";
    StairsShape["INNER_RIGHT"] = "inner_right";
    StairsShape["OUTER_LEFT"] = "outer_left";
    StairsShape["OUTER_RIGHT"] = "outer_right";
})(StairsShape || (StairsShape = {}));
//sh*trock vanilla consistency...
function isUpsideDown(permutation) {
    const half = permutation.getState(McStates.VerticalHalf);
    if (half) {
        return half == "top";
    }
    const upsideDownBit = permutation.getState(McStates.UpsideDown);
    if (upsideDownBit != undefined) {
        return upsideDownBit == true;
    }
    return false;
}
//literally java code below
function isStairs(block) {
    return block.typeId.endsWith("stairs") || block.hasTag(SuppTags.Stairs);
}
function canTakeShape(myPerm, pos, level, face) {
    const neighbor = level.getBlock(offsetVec(pos, face));
    return !isStairs(neighbor) ||
        (getADirection(neighbor) != getADirectionState(myPerm)) ||
        (isUpsideDown(neighbor.permutation) != isUpsideDown(myPerm));
}
function getStairsShape(blockPerm, pos, level) {
    const direction = getADirectionState(blockPerm);
    const infront = level.getBlock(offsetVec(pos, direction));
    if (isStairs(infront) && isUpsideDown(blockPerm) == isUpsideDown(infront.permutation)) {
        const direction2 = getADirection(infront);
        if (!isSameAxis(direction, direction2) && canTakeShape(blockPerm, pos, level, flipDir(direction2))) {
            if (direction2 == getCounterClockwiseDir(direction)) {
                return StairsShape.OUTER_LEFT;
            }
            return StairsShape.OUTER_RIGHT;
        }
    }
    const behind = level.getBlock(offsetVec(pos, flipDir(direction)));
    if (isStairs(behind) && isUpsideDown(blockPerm) == isUpsideDown(behind.permutation)) {
        const direction3 = getADirection(behind);
        if (!isSameAxis(direction, direction3) && canTakeShape(blockPerm, pos, level, direction3)) {
            if (direction3 == getCounterClockwiseDir(direction)) {
                return StairsShape.INNER_LEFT;
            }
            return StairsShape.INNER_RIGHT;
        }
    }
    return StairsShape.STRAIGHT;
}
