package net.minecraft.world.entity.boss.enderdragon;

import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
import net.minecraft.network.protocol.Packet;
import javax.annotation.Nullable;
import net.minecraft.world.level.dimension.end.EndDragonFight;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.nbt.Tag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.dimension.end.TheEndDimension;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.EntityType;
import net.minecraft.core.BlockPos;
import java.util.Optional;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.world.entity.Entity;

public class EndCrystal extends Entity {
    private static final EntityDataAccessor<Optional<BlockPos>> DATA_BEAM_TARGET;
    private static final EntityDataAccessor<Boolean> DATA_SHOW_BOTTOM;
    public int time;
    
    public EndCrystal(final EntityType<? extends EndCrystal> aku, final Level bjw) {
        super(aku, bjw);
        this.blocksBuilding = true;
        this.time = this.random.nextInt(100000);
    }
    
    public EndCrystal(final Level bjw, final double double2, final double double3, final double double4) {
        this(EntityType.END_CRYSTAL, bjw);
        this.setPos(double2, double3, double4);
    }
    
    @Override
    protected boolean isMovementNoisy() {
        return false;
    }
    
    @Override
    protected void defineSynchedData() {
        this.getEntityData().<Optional<BlockPos>>define(EndCrystal.DATA_BEAM_TARGET, Optional.<BlockPos>empty());
        this.getEntityData().<Boolean>define(EndCrystal.DATA_SHOW_BOTTOM, true);
    }
    
    @Override
    public void tick() {
        ++this.time;
        if (!this.level.isClientSide) {
            final BlockPos fk2 = new BlockPos(this);
            if (this.level.dimension instanceof TheEndDimension && this.level.getBlockState(fk2).isAir()) {
                this.level.setBlockAndUpdate(fk2, Blocks.FIRE.defaultBlockState());
            }
        }
    }
    
    @Override
    protected void addAdditionalSaveData(final CompoundTag jt) {
        if (this.getBeamTarget() != null) {
            jt.put("BeamTarget", NbtUtils.writeBlockPos(this.getBeamTarget()));
        }
        jt.putBoolean("ShowBottom", this.showsBottom());
    }
    
    @Override
    protected void readAdditionalSaveData(final CompoundTag jt) {
        if (jt.contains("BeamTarget", 10)) {
            this.setBeamTarget(NbtUtils.readBlockPos(jt.getCompound("BeamTarget")));
        }
        if (jt.contains("ShowBottom", 1)) {
            this.setShowBottom(jt.getBoolean("ShowBottom"));
        }
    }
    
    @Override
    public boolean isPickable() {
        return true;
    }
    
    @Override
    public boolean hurt(final DamageSource ajz, final float float2) {
        if (this.isInvulnerableTo(ajz)) {
            return false;
        }
        if (ajz.getEntity() instanceof EnderDragon) {
            return false;
        }
        if (!this.removed && !this.level.isClientSide) {
            this.remove();
            if (!ajz.isExplosion()) {
                this.level.explode(null, this.getX(), this.getY(), this.getZ(), 6.0f, Explosion.BlockInteraction.DESTROY);
            }
            this.onDestroyedBy(ajz);
        }
        return true;
    }
    
    @Override
    public void kill() {
        this.onDestroyedBy(DamageSource.GENERIC);
        super.kill();
    }
    
    private void onDestroyedBy(final DamageSource ajz) {
        if (this.level.dimension instanceof TheEndDimension) {
            final TheEndDimension cbn3 = (TheEndDimension)this.level.dimension;
            final EndDragonFight cbm4 = cbn3.getDragonFight();
            if (cbm4 != null) {
                cbm4.onCrystalDestroyed(this, ajz);
            }
        }
    }
    
    public void setBeamTarget(@Nullable final BlockPos fk) {
        this.getEntityData().<Optional<BlockPos>>set(EndCrystal.DATA_BEAM_TARGET, Optional.<BlockPos>ofNullable(fk));
    }
    
    @Nullable
    public BlockPos getBeamTarget() {
        return this.getEntityData().<Optional<BlockPos>>get(EndCrystal.DATA_BEAM_TARGET).orElse(null);
    }
    
    public void setShowBottom(final boolean boolean1) {
        this.getEntityData().<Boolean>set(EndCrystal.DATA_SHOW_BOTTOM, boolean1);
    }
    
    public boolean showsBottom() {
        return this.getEntityData().<Boolean>get(EndCrystal.DATA_SHOW_BOTTOM);
    }
    
    @Override
    public boolean shouldRenderAtSqrDistance(final double double1) {
        return super.shouldRenderAtSqrDistance(double1) || this.getBeamTarget() != null;
    }
    
    @Override
    public Packet<?> getAddEntityPacket() {
        return new ClientboundAddEntityPacket(this);
    }
    
    static {
        DATA_BEAM_TARGET = SynchedEntityData.<Optional<BlockPos>>defineId(EndCrystal.class, EntityDataSerializers.OPTIONAL_BLOCK_POS);
        DATA_SHOW_BOTTOM = SynchedEntityData.<Boolean>defineId(EndCrystal.class, EntityDataSerializers.BOOLEAN);
    }
}
