package net.minecraft.world.level.chunk;

import net.minecraft.world.level.TickNextTickData;
import java.util.stream.Stream;
import net.minecraft.world.level.TickPriority;
import it.unimi.dsi.fastutil.shorts.ShortListIterator;
import net.minecraft.core.BlockPos;
import java.util.function.Function;
import net.minecraft.world.level.chunk.storage.ChunkSerializer;
import net.minecraft.nbt.ListTag;
import it.unimi.dsi.fastutil.shorts.ShortList;
import net.minecraft.world.level.ChunkPos;
import java.util.function.Predicate;
import net.minecraft.world.level.TickList;

public class ProtoTickList<T> implements TickList<T> {
    protected final Predicate<T> ignore;
    private final ChunkPos chunkPos;
    private final ShortList[] toBeTicked;
    
    public ProtoTickList(final Predicate<T> predicate, final ChunkPos bjh) {
        this(predicate, bjh, new ListTag());
    }
    
    public ProtoTickList(final Predicate<T> predicate, final ChunkPos bjh, final ListTag jz) {
        this.toBeTicked = new ShortList[16];
        this.ignore = predicate;
        this.chunkPos = bjh;
        for (int integer5 = 0; integer5 < jz.size(); ++integer5) {
            final ListTag jz2 = jz.getList(integer5);
            for (int integer6 = 0; integer6 < jz2.size(); ++integer6) {
                ChunkAccess.getOrCreateOffsetList(this.toBeTicked, integer5).add(jz2.getShort(integer6));
            }
        }
    }
    
    public ListTag save() {
        return ChunkSerializer.packOffsets(this.toBeTicked);
    }
    
    public void copyOut(final TickList<T> bkl, final Function<BlockPos, T> function) {
        for (int integer4 = 0; integer4 < this.toBeTicked.length; ++integer4) {
            if (this.toBeTicked[integer4] != null) {
                for (final Short short6 : this.toBeTicked[integer4]) {
                    final BlockPos fk7 = ProtoChunk.unpackOffsetCoordinates(short6, integer4, this.chunkPos);
                    bkl.scheduleTick(fk7, function.apply(fk7), 0);
                }
                this.toBeTicked[integer4].clear();
            }
        }
    }
    
    @Override
    public boolean hasScheduledTick(final BlockPos fk, final T object) {
        return false;
    }
    
    @Override
    public void scheduleTick(final BlockPos fk, final T object, final int integer, final TickPriority bkn) {
        ChunkAccess.getOrCreateOffsetList(this.toBeTicked, fk.getY() >> 4).add(ProtoChunk.packOffsetCoordinates(fk));
    }
    
    @Override
    public boolean willTickThisTick(final BlockPos fk, final T object) {
        return false;
    }
    
    @Override
    public void addAll(final Stream<TickNextTickData<T>> stream) {
        stream.forEach(bkm -> this.scheduleTick(bkm.pos, bkm.getType(), 0, bkm.priority));
    }
}
