package net.minecraft.world.effect;

import org.apache.logging.log4j.LogManager;
import com.google.common.collect.ComparisonChain;
import net.minecraft.nbt.Tag;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.LivingEntity;
import javax.annotation.Nullable;
import org.apache.logging.log4j.Logger;

public class MobEffectInstance implements Comparable<MobEffectInstance> {
    private static final Logger LOGGER;
    private final MobEffect effect;
    private int duration;
    private int amplifier;
    private boolean splash;
    private boolean ambient;
    private boolean noCounter;
    private boolean visible;
    private boolean showIcon;
    @Nullable
    private MobEffectInstance hiddenEffect;
    
    public MobEffectInstance(final MobEffect aoe) {
        this(aoe, 0, 0);
    }
    
    public MobEffectInstance(final MobEffect aoe, final int integer) {
        this(aoe, integer, 0);
    }
    
    public MobEffectInstance(final MobEffect aoe, final int integer2, final int integer3) {
        this(aoe, integer2, integer3, false, true);
    }
    
    public MobEffectInstance(final MobEffect aoe, final int integer2, final int integer3, final boolean boolean4, final boolean boolean5) {
        this(aoe, integer2, integer3, boolean4, boolean5, boolean5);
    }
    
    public MobEffectInstance(final MobEffect aoe, final int integer2, final int integer3, final boolean boolean4, final boolean boolean5, final boolean boolean6) {
        this(aoe, integer2, integer3, boolean4, boolean5, boolean6, null);
    }
    
    public MobEffectInstance(final MobEffect aoe, final int integer2, final int integer3, final boolean boolean4, final boolean boolean5, final boolean boolean6, @Nullable final MobEffectInstance aog) {
        this.effect = aoe;
        this.duration = integer2;
        this.amplifier = integer3;
        this.ambient = boolean4;
        this.visible = boolean5;
        this.showIcon = boolean6;
        this.hiddenEffect = aog;
    }
    
    public MobEffectInstance(final MobEffectInstance aog) {
        this.effect = aog.effect;
        this.setDetailsFrom(aog);
    }
    
    void setDetailsFrom(final MobEffectInstance aog) {
        this.duration = aog.duration;
        this.amplifier = aog.amplifier;
        this.ambient = aog.ambient;
        this.visible = aog.visible;
        this.showIcon = aog.showIcon;
    }
    
    public boolean update(final MobEffectInstance aog) {
        if (this.effect != aog.effect) {
            MobEffectInstance.LOGGER.warn("This method should only be called for matching effects!");
        }
        boolean boolean3 = false;
        if (aog.amplifier > this.amplifier) {
            if (aog.duration < this.duration) {
                final MobEffectInstance aog2 = this.hiddenEffect;
                this.hiddenEffect = new MobEffectInstance(this);
                this.hiddenEffect.hiddenEffect = aog2;
            }
            this.amplifier = aog.amplifier;
            this.duration = aog.duration;
            boolean3 = true;
        }
        else if (aog.duration > this.duration) {
            if (aog.amplifier == this.amplifier) {
                this.duration = aog.duration;
                boolean3 = true;
            }
            else if (this.hiddenEffect == null) {
                this.hiddenEffect = new MobEffectInstance(aog);
            }
            else {
                this.hiddenEffect.update(aog);
            }
        }
        if ((!aog.ambient && this.ambient) || boolean3) {
            this.ambient = aog.ambient;
            boolean3 = true;
        }
        if (aog.visible != this.visible) {
            this.visible = aog.visible;
            boolean3 = true;
        }
        if (aog.showIcon != this.showIcon) {
            this.showIcon = aog.showIcon;
            boolean3 = true;
        }
        return boolean3;
    }
    
    public MobEffect getEffect() {
        return this.effect;
    }
    
    public int getDuration() {
        return this.duration;
    }
    
    public int getAmplifier() {
        return this.amplifier;
    }
    
    public boolean isAmbient() {
        return this.ambient;
    }
    
    public boolean isVisible() {
        return this.visible;
    }
    
    public boolean showIcon() {
        return this.showIcon;
    }
    
    public boolean tick(final LivingEntity aoy, final Runnable runnable) {
        if (this.duration > 0) {
            if (this.effect.isDurationEffectTick(this.duration, this.amplifier)) {
                this.applyEffect(aoy);
            }
            this.tickDownDuration();
            if (this.duration == 0 && this.hiddenEffect != null) {
                this.setDetailsFrom(this.hiddenEffect);
                this.hiddenEffect = this.hiddenEffect.hiddenEffect;
                runnable.run();
            }
        }
        return this.duration > 0;
    }
    
    private int tickDownDuration() {
        if (this.hiddenEffect != null) {
            this.hiddenEffect.tickDownDuration();
        }
        return --this.duration;
    }
    
    public void applyEffect(final LivingEntity aoy) {
        if (this.duration > 0) {
            this.effect.applyEffectTick(aoy, this.amplifier);
        }
    }
    
    public String getDescriptionId() {
        return this.effect.getDescriptionId();
    }
    
    @Override
    public String toString() {
        String string2;
        if (this.amplifier > 0) {
            string2 = this.getDescriptionId() + " x " + (this.amplifier + 1) + ", Duration: " + this.duration;
        }
        else {
            string2 = this.getDescriptionId() + ", Duration: " + this.duration;
        }
        if (this.splash) {
            string2 += ", Splash: true";
        }
        if (!this.visible) {
            string2 += ", Particles: false";
        }
        if (!this.showIcon) {
            string2 += ", Show Icon: false";
        }
        return string2;
    }
    
    @Override
    public boolean equals(final Object object) {
        if (this == object) {
            return true;
        }
        if (object instanceof MobEffectInstance) {
            final MobEffectInstance aog3 = (MobEffectInstance)object;
            return this.duration == aog3.duration && this.amplifier == aog3.amplifier && this.splash == aog3.splash && this.ambient == aog3.ambient && this.effect.equals(aog3.effect);
        }
        return false;
    }
    
    @Override
    public int hashCode() {
        int integer2 = this.effect.hashCode();
        integer2 = 31 * integer2 + this.duration;
        integer2 = 31 * integer2 + this.amplifier;
        integer2 = 31 * integer2 + (this.splash ? 1 : 0);
        integer2 = 31 * integer2 + (this.ambient ? 1 : 0);
        return integer2;
    }
    
    public CompoundTag save(final CompoundTag le) {
        le.putByte("Id", (byte)MobEffect.getId(this.getEffect()));
        this.writeDetailsTo(le);
        return le;
    }
    
    private void writeDetailsTo(final CompoundTag le) {
        le.putByte("Amplifier", (byte)this.getAmplifier());
        le.putInt("Duration", this.getDuration());
        le.putBoolean("Ambient", this.isAmbient());
        le.putBoolean("ShowParticles", this.isVisible());
        le.putBoolean("ShowIcon", this.showIcon());
        if (this.hiddenEffect != null) {
            final CompoundTag le2 = new CompoundTag();
            this.hiddenEffect.save(le2);
            le.put("HiddenEffect", le2);
        }
    }
    
    public static MobEffectInstance load(final CompoundTag le) {
        final int integer2 = le.getByte("Id");
        final MobEffect aoe3 = MobEffect.byId(integer2);
        if (aoe3 == null) {
            return null;
        }
        return loadSpecifiedEffect(aoe3, le);
    }
    
    private static MobEffectInstance loadSpecifiedEffect(final MobEffect aoe, final CompoundTag le) {
        final int integer3 = le.getByte("Amplifier");
        final int integer4 = le.getInt("Duration");
        final boolean boolean5 = le.getBoolean("Ambient");
        boolean boolean6 = true;
        if (le.contains("ShowParticles", 1)) {
            boolean6 = le.getBoolean("ShowParticles");
        }
        boolean boolean7 = boolean6;
        if (le.contains("ShowIcon", 1)) {
            boolean7 = le.getBoolean("ShowIcon");
        }
        MobEffectInstance aog8 = null;
        if (le.contains("HiddenEffect", 10)) {
            aog8 = loadSpecifiedEffect(aoe, le.getCompound("HiddenEffect"));
        }
        return new MobEffectInstance(aoe, integer4, (integer3 < 0) ? 0 : integer3, boolean5, boolean6, boolean7, aog8);
    }
    
    public void setNoCounter(final boolean boolean1) {
        this.noCounter = boolean1;
    }
    
    public boolean isNoCounter() {
        return this.noCounter;
    }
    
    @Override
    public int compareTo(final MobEffectInstance aog) {
        final int integer3 = 32147;
        if ((this.getDuration() > 32147 && aog.getDuration() > 32147) || (this.isAmbient() && aog.isAmbient())) {
            return ComparisonChain.start().compare(this.isAmbient(), aog.isAmbient()).compare(this.getEffect().getColor(), aog.getEffect().getColor()).result();
        }
        return ComparisonChain.start().compare(this.isAmbient(), aog.isAmbient()).compare(this.getDuration(), aog.getDuration()).compare(this.getEffect().getColor(), aog.getEffect().getColor()).result();
    }
    
    static {
        LOGGER = LogManager.getLogger();
    }
}
