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

package com.hypixel.hytale.builtin.ambience.systems;

import java.util.logging.Level;
import com.hypixel.hytale.builtin.ambience.AmbiencePlugin;
import com.hypixel.hytale.component.ArchetypeChunk;
import com.hypixel.hytale.component.system.tick.EntityTickingSystem;
import javax.annotation.Nullable;
import com.hypixel.hytale.component.NonSerialized;
import com.hypixel.hytale.server.core.asset.type.soundevent.config.SoundEvent;
import com.hypixel.hytale.server.core.modules.entity.component.AudioComponent;
import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.system.RefSystem;
import com.hypixel.hytale.component.RemoveReason;
import com.hypixel.hytale.server.core.prefab.PrefabCopyableComponent;
import com.hypixel.hytale.server.core.modules.entity.component.Intangible;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.server.core.modules.entity.tracker.NetworkId;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.AddReason;
import javax.annotation.Nonnull;
import com.hypixel.hytale.component.Holder;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.builtin.ambience.components.AmbientEmitterComponent;
import com.hypixel.hytale.component.query.Query;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.system.HolderSystem;

public class AmbientEmitterSystems
{
    public static class EntityAdded extends HolderSystem<EntityStore>
    {
        private final Query<EntityStore> query;
        
        public EntityAdded() {
            this.query = (Query<EntityStore>)Query.and(AmbientEmitterComponent.getComponentType(), TransformComponent.getComponentType());
        }
        
        @Override
        public void onEntityAdd(@Nonnull final Holder<EntityStore> holder, @Nonnull final AddReason reason, @Nonnull final Store<EntityStore> store) {
            if (!holder.getArchetype().contains(NetworkId.getComponentType())) {
                holder.addComponent(NetworkId.getComponentType(), new NetworkId(store.getExternalData().takeNextNetworkId()));
            }
            holder.ensureComponent(Intangible.getComponentType());
            holder.ensureComponent(PrefabCopyableComponent.getComponentType());
        }
        
        @Override
        public void onEntityRemoved(@Nonnull final Holder<EntityStore> holder, @Nonnull final RemoveReason reason, @Nonnull final Store<EntityStore> store) {
        }
        
        @Override
        public Query<EntityStore> getQuery() {
            return this.query;
        }
    }
    
    public static class EntityRefAdded extends RefSystem<EntityStore>
    {
        private final Query<EntityStore> query;
        
        public EntityRefAdded() {
            this.query = (Query<EntityStore>)Query.and(AmbientEmitterComponent.getComponentType(), TransformComponent.getComponentType());
        }
        
        @Override
        public void onEntityAdded(@Nonnull final Ref<EntityStore> ref, @Nonnull final AddReason reason, @Nonnull final Store<EntityStore> store, @Nonnull final CommandBuffer<EntityStore> commandBuffer) {
            final AmbientEmitterComponent emitterComponent = store.getComponent(ref, AmbientEmitterComponent.getComponentType());
            assert emitterComponent != null;
            final TransformComponent transformComponent = store.getComponent(ref, TransformComponent.getComponentType());
            assert transformComponent != null;
            final Holder<EntityStore> emitterHolder = EntityStore.REGISTRY.newHolder();
            emitterHolder.addComponent(TransformComponent.getComponentType(), transformComponent.clone());
            final AudioComponent audioComponent = new AudioComponent();
            audioComponent.addSound(SoundEvent.getAssetMap().getIndex(emitterComponent.getSoundEventId()));
            emitterHolder.addComponent(AudioComponent.getComponentType(), audioComponent);
            emitterHolder.addComponent(NetworkId.getComponentType(), new NetworkId(store.getExternalData().takeNextNetworkId()));
            emitterHolder.ensureComponent(Intangible.getComponentType());
            emitterHolder.addComponent(EntityStore.REGISTRY.getNonSerializedComponentType(), NonSerialized.get());
            emitterComponent.setSpawnedEmitter(commandBuffer.addEntity(emitterHolder, AddReason.SPAWN));
        }
        
        @Override
        public void onEntityRemove(@Nonnull final Ref<EntityStore> ref, @Nonnull final RemoveReason reason, @Nonnull final Store<EntityStore> store, @Nonnull final CommandBuffer<EntityStore> commandBuffer) {
            if (reason == RemoveReason.REMOVE) {
                final AmbientEmitterComponent emitterComponent = store.getComponent(ref, AmbientEmitterComponent.getComponentType());
                assert emitterComponent != null;
                final Ref<EntityStore> emitterRef = emitterComponent.getSpawnedEmitter();
                if (emitterRef != null) {
                    commandBuffer.removeEntity(emitterRef, RemoveReason.REMOVE);
                }
            }
        }
        
        @Nullable
        @Override
        public Query<EntityStore> getQuery() {
            return this.query;
        }
    }
    
    public static class Ticking extends EntityTickingSystem<EntityStore>
    {
        private final Query<EntityStore> query;
        
        public Ticking() {
            this.query = (Query<EntityStore>)Query.and(AmbientEmitterComponent.getComponentType(), TransformComponent.getComponentType());
        }
        
        @Override
        public void tick(final float dt, final int index, @Nonnull final ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull final Store<EntityStore> store, @Nonnull final CommandBuffer<EntityStore> commandBuffer) {
            final AmbientEmitterComponent emitter = archetypeChunk.getComponent(index, AmbientEmitterComponent.getComponentType());
            assert emitter != null;
            final TransformComponent transform = archetypeChunk.getComponent(index, TransformComponent.getComponentType());
            assert transform != null;
            if (emitter.getSpawnedEmitter() == null || !emitter.getSpawnedEmitter().isValid()) {
                AmbiencePlugin.get().getLogger().at(Level.WARNING).log("Ambient emitter lost at %s: %d %s", transform.getPosition(), archetypeChunk.getReferenceTo(index).getIndex(), emitter.getSoundEventId());
                commandBuffer.removeEntity(archetypeChunk.getReferenceTo(index), RemoveReason.REMOVE);
                return;
            }
            final TransformComponent ownedEmitterTransform = store.getComponent(emitter.getSpawnedEmitter(), TransformComponent.getComponentType());
            if (transform.getPosition().distanceSquaredTo(ownedEmitterTransform.getPosition()) > 1.0) {
                ownedEmitterTransform.setPosition(transform.getPosition());
            }
        }
        
        @Nullable
        @Override
        public Query<EntityStore> getQuery() {
            return this.query;
        }
    }
}
