package net.minecraft.world.level.pathfinder;

import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth;

public class Node {
    public final int x;
    public final int y;
    public final int z;
    private final int hash;
    public int heapIdx;
    public float g;
    public float h;
    public float f;
    public Node cameFrom;
    public boolean closed;
    public float walkedDistance;
    public float costMalus;
    public BlockPathTypes type;
    
    public Node(final int integer1, final int integer2, final int integer3) {
        this.heapIdx = -1;
        this.type = BlockPathTypes.BLOCKED;
        this.x = integer1;
        this.y = integer2;
        this.z = integer3;
        this.hash = createHash(integer1, integer2, integer3);
    }
    
    public Node cloneMove(final int integer1, final int integer2, final int integer3) {
        final Node cqo5 = new Node(integer1, integer2, integer3);
        cqo5.heapIdx = this.heapIdx;
        cqo5.g = this.g;
        cqo5.h = this.h;
        cqo5.f = this.f;
        cqo5.cameFrom = this.cameFrom;
        cqo5.closed = this.closed;
        cqo5.walkedDistance = this.walkedDistance;
        cqo5.costMalus = this.costMalus;
        cqo5.type = this.type;
        return cqo5;
    }
    
    public static int createHash(final int integer1, final int integer2, final int integer3) {
        return (integer2 & 0xFF) | (integer1 & 0x7FFF) << 8 | (integer3 & 0x7FFF) << 24 | ((integer1 < 0) ? Integer.MIN_VALUE : 0) | ((integer3 < 0) ? 32768 : 0);
    }
    
    public float distanceTo(final Node cqo) {
        final float float3 = (float)(cqo.x - this.x);
        final float float4 = (float)(cqo.y - this.y);
        final float float5 = (float)(cqo.z - this.z);
        return Mth.sqrt(float3 * float3 + float4 * float4 + float5 * float5);
    }
    
    public float distanceToSqr(final Node cqo) {
        final float float3 = (float)(cqo.x - this.x);
        final float float4 = (float)(cqo.y - this.y);
        final float float5 = (float)(cqo.z - this.z);
        return float3 * float3 + float4 * float4 + float5 * float5;
    }
    
    public float distanceManhattan(final Node cqo) {
        final float float3 = (float)Math.abs(cqo.x - this.x);
        final float float4 = (float)Math.abs(cqo.y - this.y);
        final float float5 = (float)Math.abs(cqo.z - this.z);
        return float3 + float4 + float5;
    }
    
    public float distanceManhattan(final BlockPos fk) {
        final float float3 = (float)Math.abs(fk.getX() - this.x);
        final float float4 = (float)Math.abs(fk.getY() - this.y);
        final float float5 = (float)Math.abs(fk.getZ() - this.z);
        return float3 + float4 + float5;
    }
    
    public BlockPos asBlockPos() {
        return new BlockPos(this.x, this.y, this.z);
    }
    
    @Override
    public boolean equals(final Object object) {
        if (object instanceof Node) {
            final Node cqo3 = (Node)object;
            return this.hash == cqo3.hash && this.x == cqo3.x && this.y == cqo3.y && this.z == cqo3.z;
        }
        return false;
    }
    
    @Override
    public int hashCode() {
        return this.hash;
    }
    
    public boolean inOpenSet() {
        return this.heapIdx >= 0;
    }
    
    @Override
    public String toString() {
        return "Node{x=" + this.x + ", y=" + this.y + ", z=" + this.z + '}';
    }
    
    public static Node createFromStream(final FriendlyByteBuf kv) {
        final Node cqo2 = new Node(kv.readInt(), kv.readInt(), kv.readInt());
        cqo2.walkedDistance = kv.readFloat();
        cqo2.costMalus = kv.readFloat();
        cqo2.closed = kv.readBoolean();
        cqo2.type = BlockPathTypes.values()[kv.readInt()];
        cqo2.f = kv.readFloat();
        return cqo2;
    }
}
