import * as mc from '@minecraft/server';

export function beamBetweenLocations(origin, target, dimension, effect) {

    if(!locationIsValid(origin, dimension)) return;
    if(!locationIsValid(target, dimension)) return;

    let direction = { x: target.x - origin.x, y: target.y - origin.y, z: target.z - origin.z }
    let direction_normalized = locationNormalize(direction);
    let distance = getDistance(origin, target);
    if(distance == 0) return;   //no distance, no particle

    let midpoint = { x: origin.x + direction_normalized.x * distance / 2, y: origin.y + direction_normalized.y * distance / 2, z: origin.z + direction_normalized.z * distance / 2 }

    let mvm = new mc.MolangVariableMap();
    mvm.setFloat(`variable.dir_x`, direction_normalized.x);
    mvm.setFloat(`variable.dir_y`, direction_normalized.y);
    mvm.setFloat(`variable.dir_z`, direction_normalized.z);
    mvm.setFloat(`variable.distance`, distance);

    effect.forEach(element => { mc.world.getDimension(dimension).spawnParticle(element, midpoint, mvm); });
}

export function getDistance(a, b) {
    const dx = b.x - a.x;
    const dy = b.y - a.y;
    const dz = b.z - a.z;
    const distance = Math.hypot(dx, dy, dz);
    return distance;
}

function getLength(location) {
    return Math.hypot(location.x, location.y, location.z);
}

function locationNormalize(location) {
    const magnitude = getLength(location);
    const DirectionX = location.x / magnitude;
    const DirectionY = location.y / magnitude;
    const DirectionZ = location.z / magnitude;
    return { x: DirectionX, y: DirectionY, z: DirectionZ };
}

export function locationIsValid(location, dimension) {
    try {
        mc.world.getDimension(dimension).getBlock(location)
    }
    catch (error) {
        return false;
    };
    return true;
}