package net.minecraft.world.level.pathfinder;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.entity.Entity;
import javax.annotation.Nullable;
import net.minecraft.core.BlockPos;
import java.util.Set;
import java.util.List;

public class Path {
    private final List<Node> nodes;
    private Node[] openSet;
    private Node[] closedSet;
    private Set<Target> targetNodes;
    private int index;
    private final BlockPos target;
    private final float distToTarget;
    private final boolean reached;
    
    public Path(final List<Node> list, final BlockPos fk, final boolean boolean3) {
        this.openSet = new Node[0];
        this.closedSet = new Node[0];
        this.nodes = list;
        this.target = fk;
        this.distToTarget = (list.isEmpty() ? Float.MAX_VALUE : this.nodes.get(this.nodes.size() - 1).distanceManhattan(this.target));
        this.reached = boolean3;
    }
    
    public void next() {
        ++this.index;
    }
    
    public boolean isDone() {
        return this.index >= this.nodes.size();
    }
    
    @Nullable
    public Node last() {
        if (!this.nodes.isEmpty()) {
            return this.nodes.get(this.nodes.size() - 1);
        }
        return null;
    }
    
    public Node get(final int integer) {
        return this.nodes.get(integer);
    }
    
    public List<Node> getNodes() {
        return this.nodes;
    }
    
    public void truncate(final int integer) {
        if (this.nodes.size() > integer) {
            this.nodes.subList(integer, this.nodes.size()).clear();
        }
    }
    
    public void set(final int integer, final Node cqo) {
        this.nodes.set(integer, cqo);
    }
    
    public int getSize() {
        return this.nodes.size();
    }
    
    public int getIndex() {
        return this.index;
    }
    
    public void setIndex(final int integer) {
        this.index = integer;
    }
    
    public Vec3 getPos(final Entity akq, final int integer) {
        final Node cqo4 = this.nodes.get(integer);
        final double double5 = cqo4.x + (int)(akq.getBbWidth() + 1.0f) * 0.5;
        final double double6 = cqo4.y;
        final double double7 = cqo4.z + (int)(akq.getBbWidth() + 1.0f) * 0.5;
        return new Vec3(double5, double6, double7);
    }
    
    public Vec3 currentPos(final Entity akq) {
        return this.getPos(akq, this.index);
    }
    
    public Vec3 currentPos() {
        final Node cqo2 = this.nodes.get(this.index);
        return new Vec3(cqo2.x, cqo2.y, cqo2.z);
    }
    
    public boolean sameAs(@Nullable final Path cqq) {
        if (cqq == null) {
            return false;
        }
        if (cqq.nodes.size() != this.nodes.size()) {
            return false;
        }
        for (int integer3 = 0; integer3 < this.nodes.size(); ++integer3) {
            final Node cqo4 = this.nodes.get(integer3);
            final Node cqo5 = cqq.nodes.get(integer3);
            if (cqo4.x != cqo5.x || cqo4.y != cqo5.y || cqo4.z != cqo5.z) {
                return false;
            }
        }
        return true;
    }
    
    public boolean canReach() {
        return this.reached;
    }
    
    public Node[] getOpenSet() {
        return this.openSet;
    }
    
    public Node[] getClosedSet() {
        return this.closedSet;
    }
    
    public static Path createFromStream(final FriendlyByteBuf kv) {
        final boolean boolean2 = kv.readBoolean();
        final int integer3 = kv.readInt();
        final int integer4 = kv.readInt();
        final Set<Target> set5 = Sets.newHashSet();
        for (int integer5 = 0; integer5 < integer4; ++integer5) {
            set5.add(Target.createFromStream(kv));
        }
        final BlockPos fk6 = new BlockPos(kv.readInt(), kv.readInt(), kv.readInt());
        final List<Node> list7 = Lists.newArrayList();
        for (int integer6 = kv.readInt(), integer7 = 0; integer7 < integer6; ++integer7) {
            list7.add(Node.createFromStream(kv));
        }
        final Node[] arr9 = new Node[kv.readInt()];
        for (int integer8 = 0; integer8 < arr9.length; ++integer8) {
            arr9[integer8] = Node.createFromStream(kv);
        }
        final Node[] arr10 = new Node[kv.readInt()];
        for (int integer9 = 0; integer9 < arr10.length; ++integer9) {
            arr10[integer9] = Node.createFromStream(kv);
        }
        final Path cqq11 = new Path(list7, fk6, boolean2);
        cqq11.openSet = arr9;
        cqq11.closedSet = arr10;
        cqq11.targetNodes = set5;
        cqq11.index = integer3;
        return cqq11;
    }
    
    @Override
    public String toString() {
        return "Path(length=" + this.nodes.size() + ")";
    }
    
    public BlockPos getTarget() {
        return this.target;
    }
    
    public float getDistToTarget() {
        return this.distToTarget;
    }
}
