package net.minecraft.world.entity.ai.navigation;

import net.minecraft.world.level.BlockGetter;
import net.minecraft.network.protocol.game.DebugPackets;
import net.minecraft.util.Mth;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.pathfinder.Path;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.level.pathfinder.FlyNodeEvaluator;
import net.minecraft.world.level.pathfinder.PathFinder;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.Mob;

public class FlyingPathNavigation extends PathNavigation {
    public FlyingPathNavigation(final Mob ala, final Level bjw) {
        super(ala, bjw);
    }
    
    @Override
    protected PathFinder createPathFinder(final int integer) {
        (this.nodeEvaluator = new FlyNodeEvaluator()).setCanPassDoors(true);
        return new PathFinder(this.nodeEvaluator, integer);
    }
    
    @Override
    protected boolean canUpdatePath() {
        return (this.canFloat() && this.isInLiquid()) || !this.mob.isPassenger();
    }
    
    @Override
    protected Vec3 getTempMobPos() {
        return this.mob.position();
    }
    
    @Override
    public Path createPath(final Entity akq, final int integer) {
        return this.createPath(new BlockPos(akq), integer);
    }
    
    @Override
    public void tick() {
        ++this.tick;
        if (this.hasDelayedRecomputation) {
            this.recomputePath();
        }
        if (this.isDone()) {
            return;
        }
        if (this.canUpdatePath()) {
            this.updatePath();
        }
        else if (this.path != null && this.path.getIndex() < this.path.getSize()) {
            final Vec3 cvl2 = this.path.getPos(this.mob, this.path.getIndex());
            if (Mth.floor(this.mob.getX()) == Mth.floor(cvl2.x) && Mth.floor(this.mob.getY()) == Mth.floor(cvl2.y) && Mth.floor(this.mob.getZ()) == Mth.floor(cvl2.z)) {
                this.path.setIndex(this.path.getIndex() + 1);
            }
        }
        DebugPackets.sendPathFindingPacket(this.level, this.mob, this.path, this.maxDistanceToWaypoint);
        if (this.isDone()) {
            return;
        }
        final Vec3 cvl2 = this.path.currentPos(this.mob);
        this.mob.getMoveControl().setWantedPosition(cvl2.x, cvl2.y, cvl2.z, this.speedModifier);
    }
    
    @Override
    protected boolean canMoveDirectly(final Vec3 cvl1, final Vec3 cvl2, final int integer3, final int integer4, final int integer5) {
        int integer6 = Mth.floor(cvl1.x);
        int integer7 = Mth.floor(cvl1.y);
        int integer8 = Mth.floor(cvl1.z);
        double double10 = cvl2.x - cvl1.x;
        double double11 = cvl2.y - cvl1.y;
        double double12 = cvl2.z - cvl1.z;
        final double double13 = double10 * double10 + double11 * double11 + double12 * double12;
        if (double13 < 1.0E-8) {
            return false;
        }
        final double double14 = 1.0 / Math.sqrt(double13);
        double10 *= double14;
        double11 *= double14;
        double12 *= double14;
        final double double15 = 1.0 / Math.abs(double10);
        final double double16 = 1.0 / Math.abs(double11);
        final double double17 = 1.0 / Math.abs(double12);
        double double18 = integer6 - cvl1.x;
        double double19 = integer7 - cvl1.y;
        double double20 = integer8 - cvl1.z;
        if (double10 >= 0.0) {
            ++double18;
        }
        if (double11 >= 0.0) {
            ++double19;
        }
        if (double12 >= 0.0) {
            ++double20;
        }
        double18 /= double10;
        double19 /= double11;
        double20 /= double12;
        final int integer9 = (double10 < 0.0) ? -1 : 1;
        final int integer10 = (double11 < 0.0) ? -1 : 1;
        final int integer11 = (double12 < 0.0) ? -1 : 1;
        final int integer12 = Mth.floor(cvl2.x);
        final int integer13 = Mth.floor(cvl2.y);
        final int integer14 = Mth.floor(cvl2.z);
        int integer15 = integer12 - integer6;
        int integer16 = integer13 - integer7;
        int integer17 = integer14 - integer8;
        while (integer15 * integer9 > 0 || integer16 * integer10 > 0 || integer17 * integer11 > 0) {
            if (double18 < double20 && double18 <= double19) {
                double18 += double15;
                integer6 += integer9;
                integer15 = integer12 - integer6;
            }
            else if (double19 < double18 && double19 <= double20) {
                double19 += double16;
                integer7 += integer10;
                integer16 = integer13 - integer7;
            }
            else {
                double20 += double17;
                integer8 += integer11;
                integer17 = integer14 - integer8;
            }
        }
        return true;
    }
    
    public void setCanOpenDoors(final boolean boolean1) {
        this.nodeEvaluator.setCanOpenDoors(boolean1);
    }
    
    public void setCanPassDoors(final boolean boolean1) {
        this.nodeEvaluator.setCanPassDoors(boolean1);
    }
    
    @Override
    public boolean isStableDestination(final BlockPos fk) {
        return this.level.getBlockState(fk).entityCanStandOn(this.level, fk, this.mob);
    }
}
