// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.spawning.suppression.system;

import java.util.List;
import java.util.Map;
import com.hypixel.hytale.server.spawning.suppression.component.ChunkSuppressionQueue;
import com.hypixel.hytale.component.system.tick.TickingSystem;
import com.hypixel.hytale.component.RemoveReason;
import com.hypixel.hytale.server.core.universe.world.World;
import java.util.logging.Level;
import com.hypixel.hytale.server.spawning.SpawningPlugin;
import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.AddReason;
import javax.annotation.Nonnull;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.query.Query;
import com.hypixel.hytale.server.spawning.suppression.component.SpawnSuppressionController;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.ResourceType;
import com.hypixel.hytale.server.spawning.suppression.component.ChunkSuppressionEntry;
import com.hypixel.hytale.server.core.universe.world.chunk.BlockChunk;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import com.hypixel.hytale.component.system.RefSystem;

public class ChunkSuppressionSystems
{
    public static class ChunkAdded extends RefSystem<ChunkStore>
    {
        private static final ComponentType<ChunkStore, BlockChunk> COMPONENT_TYPE;
        private final ComponentType<ChunkStore, ChunkSuppressionEntry> chunkSuppressionEntryComponentType;
        private final ResourceType<EntityStore, SpawnSuppressionController> spawnSuppressionControllerResourceType;
        
        public ChunkAdded(final ComponentType<ChunkStore, ChunkSuppressionEntry> chunkSuppressionEntryComponentType, final ResourceType<EntityStore, SpawnSuppressionController> spawnSuppressionControllerResourceType) {
            this.chunkSuppressionEntryComponentType = chunkSuppressionEntryComponentType;
            this.spawnSuppressionControllerResourceType = spawnSuppressionControllerResourceType;
        }
        
        @Override
        public Query<ChunkStore> getQuery() {
            return ChunkAdded.COMPONENT_TYPE;
        }
        
        @Override
        public void onEntityAdded(@Nonnull final Ref<ChunkStore> reference, @Nonnull final AddReason reason, @Nonnull final Store<ChunkStore> store, @Nonnull final CommandBuffer<ChunkStore> commandBuffer) {
            final World world = store.getExternalData().getWorld();
            final SpawnSuppressionController spawnSuppressionController = world.getEntityStore().getStore().getResource(this.spawnSuppressionControllerResourceType);
            final BlockChunk blockChunk = commandBuffer.getComponent(reference, ChunkAdded.COMPONENT_TYPE);
            final long index = blockChunk.getIndex();
            final ChunkSuppressionEntry entry = spawnSuppressionController.getChunkSuppressionMap().get(index);
            if (entry != null) {
                commandBuffer.addComponent(reference, this.chunkSuppressionEntryComponentType, entry);
                SpawningPlugin.get().getLogger().at(Level.FINEST).log("Annotated chunk index %s on load", index);
            }
        }
        
        @Override
        public void onEntityRemove(@Nonnull final Ref<ChunkStore> reference, @Nonnull final RemoveReason reason, @Nonnull final Store<ChunkStore> store, @Nonnull final CommandBuffer<ChunkStore> commandBuffer) {
        }
        
        static {
            COMPONENT_TYPE = BlockChunk.getComponentType();
        }
    }
    
    public static class Ticking extends TickingSystem<ChunkStore>
    {
        private final ComponentType<ChunkStore, ChunkSuppressionEntry> chunkSuppressionEntryComponentType;
        private final ResourceType<ChunkStore, ChunkSuppressionQueue> chunkSuppressionQueueResourceType;
        
        public Ticking(final ComponentType<ChunkStore, ChunkSuppressionEntry> chunkSuppressionEntryComponentType, final ResourceType<ChunkStore, ChunkSuppressionQueue> chunkSuppressionQueueResourceType) {
            this.chunkSuppressionEntryComponentType = chunkSuppressionEntryComponentType;
            this.chunkSuppressionQueueResourceType = chunkSuppressionQueueResourceType;
        }
        
        @Override
        public void tick(final float dt, final int systemIndex, @Nonnull final Store<ChunkStore> store) {
            final ChunkSuppressionQueue queue = store.getResource(this.chunkSuppressionQueueResourceType);
            final List<Map.Entry<Ref<ChunkStore>, ChunkSuppressionEntry>> addQueue = queue.getToAdd();
            if (!addQueue.isEmpty()) {
                for (int i = 0; i < addQueue.size(); ++i) {
                    final Map.Entry<Ref<ChunkStore>, ChunkSuppressionEntry> entry = addQueue.get(i);
                    final Ref<ChunkStore> ref = entry.getKey();
                    store.putComponent(ref, this.chunkSuppressionEntryComponentType, entry.getValue());
                    SpawningPlugin.get().getLogger().at(Level.FINEST).log("Annotated chunk %s from queue", ref);
                }
                addQueue.clear();
            }
            final List<Ref<ChunkStore>> removeQueue = queue.getToRemove();
            if (!removeQueue.isEmpty()) {
                for (int j = 0; j < removeQueue.size(); ++j) {
                    final Ref<ChunkStore> ref = removeQueue.get(j);
                    store.tryRemoveComponent(ref, this.chunkSuppressionEntryComponentType);
                    SpawningPlugin.get().getLogger().at(Level.FINEST).log("Removed annotation from chunk %s from queue", ref);
                }
                removeQueue.clear();
            }
        }
    }
}
