const ClipContext = Java.loadClass("net.minecraft.world.level.ClipContext")

function calculateViewVector(xRot, yRot) {
    let f = xRot * JavaMath.PI / 180.0;
    let f1 = -yRot * JavaMath.PI / 180.0;
    let f2 = JavaMath.cos(f1);
    let f3 = JavaMath.sin(f1);
    let f4 = JavaMath.cos(f);
    let f5 = JavaMath.sin(f);
    return new Vec3(f3 * f4, -f5, f2 * f4);
}


function rayTrace(entity, distance) {
    let eyePos = entity.getEyePosition(1)
    // let viewVec = entity.getViewVector(1);
    // let viewVec = calculateViewVector(0, entity.getViewYRot(1));
    let viewVec = entity.motionDirection.normal;

    let endVec = eyePos.add(viewVec.x * distance, viewVec.y * distance, viewVec.z * distance);
    return entity.level.clip(new ClipContext(eyePos, endVec, "outline", "none", entity));
}


(function () {
    let ClientboundSetEntityMotionPacket = Java.loadClass('net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket');


    StartupEvents.registry('palladium:abilities', (event) => {

        event.create('ninjago:wall_climb')

            .icon(palladium.createItemIcon('palladium:vibranium_circuit'))

            .addProperty('climb_speed', 'float', 0.1, 'the speed at which you can climb.')
            .addProperty("data_name", "string", "ninjago_climb", "Persistent data used")

            .lastTick((entity, entry, holder, enabled) => {
                if (enabled) {
                    let data_name = entry.getPropertyByName('data_name');
                    entity.persistentData[data_name] = 0;
                }
            })

            .tick((entity, entry, holder, enabled) => {
                if (enabled) {
                    let climb_speed = entry.getPropertyByName('climb_speed');
                    let data_name = entry.getPropertyByName('data_name');
                    let head_rotation = entity.pitch
                    let level = entity.serverLevel()
                    entity.persistentData[data_name] = 0;




                    let raytrace_block = rayTrace(entity, 1)
                    if (raytrace_block.type !== "miss") {
                        let currentPosup = new BlockPos(raytrace_block.blockPos);

                        let blockState = level.getBlock(currentPosup).blockState;
                        if (blockState.isCollisionShapeFullBlock(level, currentPosup)) {
                            entity.setMotion(0, climb_speed, 0);
                            entity.persistentData[data_name] = 1;

                            if (head_rotation <= -70 && head_rotation >= -90) {
                                entity.persistentData[data_name] = 4;
                                entity.setMotion(0, climb_speed, 0);
                            }
                            if (head_rotation <= 90 && head_rotation >= 70) {
                                entity.persistentData[data_name] = 4;
                                entity.setMotion(0, (climb_speed * -1), 0);
                            }
                            entity.connection.send(new ClientboundSetEntityMotionPacket(entity));
                        }
                    }
                }

            })
    });
})();

function containsTag(tags, tag) {
    for (let i = 0; i < tags.length; i++) {
        if (tags[i].equals(tag)) {
            return true;
        }
    }
    return false;
}
