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

import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.Entity;
import javax.annotation.Nullable;
import net.minecraft.world.entity.LivingEntity;
import java.util.function.Predicate;

public class TargetingConditions {
    public static final TargetingConditions DEFAULT;
    private double range;
    private boolean allowInvulnerable;
    private boolean allowSameTeam;
    private boolean allowUnseeable;
    private boolean allowNonAttackable;
    private boolean testInvisible;
    private Predicate<LivingEntity> selector;
    
    public TargetingConditions() {
        this.range = -1.0;
        this.testInvisible = true;
    }
    
    public TargetingConditions range(final double double1) {
        this.range = double1;
        return this;
    }
    
    public TargetingConditions allowInvulnerable() {
        this.allowInvulnerable = true;
        return this;
    }
    
    public TargetingConditions allowSameTeam() {
        this.allowSameTeam = true;
        return this;
    }
    
    public TargetingConditions allowUnseeable() {
        this.allowUnseeable = true;
        return this;
    }
    
    public TargetingConditions allowNonAttackable() {
        this.allowNonAttackable = true;
        return this;
    }
    
    public TargetingConditions ignoreInvisibilityTesting() {
        this.testInvisible = false;
        return this;
    }
    
    public TargetingConditions selector(@Nullable final Predicate<LivingEntity> predicate) {
        this.selector = predicate;
        return this;
    }
    
    public boolean test(@Nullable final LivingEntity akz1, final LivingEntity akz2) {
        if (akz1 == akz2) {
            return false;
        }
        if (akz2.isSpectator()) {
            return false;
        }
        if (!akz2.isAlive()) {
            return false;
        }
        if (!this.allowInvulnerable && akz2.isInvulnerable()) {
            return false;
        }
        if (this.selector != null && !this.selector.test(akz2)) {
            return false;
        }
        if (akz1 != null) {
            if (!this.allowNonAttackable) {
                if (!akz1.canAttack(akz2)) {
                    return false;
                }
                if (!akz1.canAttackType(akz2.getType())) {
                    return false;
                }
            }
            if (!this.allowSameTeam && akz1.isAlliedTo(akz2)) {
                return false;
            }
            if (this.range > 0.0) {
                final double double4 = this.testInvisible ? akz2.getVisibilityPercent(akz1) : 1.0;
                final double double5 = this.range * double4;
                final double double6 = akz1.distanceToSqr(akz2.getX(), akz2.getY(), akz2.getZ());
                if (double6 > double5 * double5) {
                    return false;
                }
            }
            if (!this.allowUnseeable && akz1 instanceof Mob && !((Mob)akz1).getSensing().canSee(akz2)) {
                return false;
            }
        }
        return true;
    }
    
    static {
        DEFAULT = new TargetingConditions();
    }
}
