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 aki) {
        this(aki, 0, 0);
    }
    
    public MobEffectInstance(final MobEffect aki, final int integer) {
        this(aki, integer, 0);
    }
    
    public MobEffectInstance(final MobEffect aki, final int integer2, final int integer3) {
        this(aki, integer2, integer3, false, true);
    }
    
    public MobEffectInstance(final MobEffect aki, final int integer2, final int integer3, final boolean boolean4, final boolean boolean5) {
        this(aki, integer2, integer3, boolean4, boolean5, boolean5);
    }
    
    public MobEffectInstance(final MobEffect aki, final int integer2, final int integer3, final boolean boolean4, final boolean boolean5, final boolean boolean6) {
        this(aki, integer2, integer3, boolean4, boolean5, boolean6, null);
    }
    
    public MobEffectInstance(final MobEffect aki, final int integer2, final int integer3, final boolean boolean4, final boolean boolean5, final boolean boolean6, @Nullable final MobEffectInstance akk) {
        this.effect = aki;
        this.duration = integer2;
        this.amplifier = integer3;
        this.ambient = boolean4;
        this.visible = boolean5;
        this.showIcon = boolean6;
        this.hiddenEffect = akk;
    }
    
    public MobEffectInstance(final MobEffectInstance akk) {
        this.effect = akk.effect;
        this.setDetailsFrom(akk);
    }
    
    void setDetailsFrom(final MobEffectInstance akk) {
        this.duration = akk.duration;
        this.amplifier = akk.amplifier;
        this.ambient = akk.ambient;
        this.visible = akk.visible;
        this.showIcon = akk.showIcon;
    }
    
    public boolean update(final MobEffectInstance akk) {
        if (this.effect != akk.effect) {
            MobEffectInstance.LOGGER.warn("This method should only be called for matching effects!");
        }
        boolean boolean3 = false;
        if (akk.amplifier > this.amplifier) {
            if (akk.duration < this.duration) {
                final MobEffectInstance akk2 = this.hiddenEffect;
                this.hiddenEffect = new MobEffectInstance(this);
                this.hiddenEffect.hiddenEffect = akk2;
            }
            this.amplifier = akk.amplifier;
            this.duration = akk.duration;
            boolean3 = true;
        }
        else if (akk.duration > this.duration) {
            if (akk.amplifier == this.amplifier) {
                this.duration = akk.duration;
                boolean3 = true;
            }
            else if (this.hiddenEffect == null) {
                this.hiddenEffect = new MobEffectInstance(akk);
            }
            else {
                this.hiddenEffect.update(akk);
            }
        }
        if ((!akk.ambient && this.ambient) || boolean3) {
            this.ambient = akk.ambient;
            boolean3 = true;
        }
        if (akk.visible != this.visible) {
            this.visible = akk.visible;
            boolean3 = true;
        }
        if (akk.showIcon != this.showIcon) {
            this.showIcon = akk.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 akz, final Runnable runnable) {
        if (this.duration > 0) {
            if (this.effect.isDurationEffectTick(this.duration, this.amplifier)) {
                this.applyEffect(akz);
            }
            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 akz) {
        if (this.duration > 0) {
            this.effect.applyEffectTick(akz, 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 akk3 = (MobEffectInstance)object;
            return this.duration == akk3.duration && this.amplifier == akk3.amplifier && this.splash == akk3.splash && this.ambient == akk3.ambient && this.effect.equals(akk3.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 jt) {
        jt.putByte("Id", (byte)MobEffect.getId(this.getEffect()));
        this.writeDetailsTo(jt);
        return jt;
    }
    
    private void writeDetailsTo(final CompoundTag jt) {
        jt.putByte("Amplifier", (byte)this.getAmplifier());
        jt.putInt("Duration", this.getDuration());
        jt.putBoolean("Ambient", this.isAmbient());
        jt.putBoolean("ShowParticles", this.isVisible());
        jt.putBoolean("ShowIcon", this.showIcon());
        if (this.hiddenEffect != null) {
            final CompoundTag jt2 = new CompoundTag();
            this.hiddenEffect.save(jt2);
            jt.put("HiddenEffect", jt2);
        }
    }
    
    public static MobEffectInstance load(final CompoundTag jt) {
        final int integer2 = jt.getByte("Id");
        final MobEffect aki3 = MobEffect.byId(integer2);
        if (aki3 == null) {
            return null;
        }
        return loadSpecifiedEffect(aki3, jt);
    }
    
    private static MobEffectInstance loadSpecifiedEffect(final MobEffect aki, final CompoundTag jt) {
        final int integer3 = jt.getByte("Amplifier");
        final int integer4 = jt.getInt("Duration");
        final boolean boolean5 = jt.getBoolean("Ambient");
        boolean boolean6 = true;
        if (jt.contains("ShowParticles", 1)) {
            boolean6 = jt.getBoolean("ShowParticles");
        }
        boolean boolean7 = boolean6;
        if (jt.contains("ShowIcon", 1)) {
            boolean7 = jt.getBoolean("ShowIcon");
        }
        MobEffectInstance akk8 = null;
        if (jt.contains("HiddenEffect", 10)) {
            akk8 = loadSpecifiedEffect(aki, jt.getCompound("HiddenEffect"));
        }
        return new MobEffectInstance(aki, integer4, (integer3 < 0) ? 0 : integer3, boolean5, boolean6, boolean7, akk8);
    }
    
    public void setNoCounter(final boolean boolean1) {
        this.noCounter = boolean1;
    }
    
    public boolean isNoCounter() {
        return this.noCounter;
    }
    
    @Override
    public int compareTo(final MobEffectInstance akk) {
        final int integer3 = 32147;
        if ((this.getDuration() > 32147 && akk.getDuration() > 32147) || (this.isAmbient() && akk.isAmbient())) {
            return ComparisonChain.start().compare(this.isAmbient(), akk.isAmbient()).compare(this.getEffect().getColor(), akk.getEffect().getColor()).result();
        }
        return ComparisonChain.start().compare(this.isAmbient(), akk.isAmbient()).compare(this.getDuration(), akk.getDuration()).compare(this.getEffect().getColor(), akk.getEffect().getColor()).result();
    }
    
    static {
        LOGGER = LogManager.getLogger();
    }
}
