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

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

import com.hypixel.hytale.component.dependency.SystemDependency;
import com.hypixel.hytale.server.core.modules.entity.teleport.TeleportSystems;
import com.hypixel.hytale.component.dependency.Order;
import com.hypixel.hytale.component.Component;
import javax.annotation.Nullable;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.dependency.Dependency;
import java.util.Set;
import com.hypixel.hytale.server.core.modules.entity.teleport.Teleport;
import com.hypixel.hytale.component.system.RefChangeSystem;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.ArchetypeChunk;
import com.hypixel.hytale.common.map.IWeightedMap;
import com.hypixel.hytale.assetstore.JsonAsset;
import java.util.Iterator;
import com.hypixel.hytale.assetstore.map.IndexedLookupTableAssetMap;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import java.util.Random;
import com.hypixel.hytale.server.core.asset.type.environment.config.WeatherForecast;
import java.util.Map;
import com.hypixel.hytale.server.core.asset.type.environment.config.Environment;
import java.util.concurrent.ThreadLocalRandom;
import com.hypixel.hytale.server.core.modules.time.WorldTimeResource;
import com.hypixel.hytale.component.system.tick.ArchetypeTickingSystem;
import com.hypixel.hytale.component.system.tick.EntityTickingSystem;
import com.hypixel.hytale.component.Archetype;
import com.hypixel.hytale.component.RemoveReason;
import com.hypixel.hytale.component.AddReason;
import com.hypixel.hytale.component.Holder;
import com.hypixel.hytale.component.query.Query;
import com.hypixel.hytale.builtin.weather.components.WeatherTracker;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.system.HolderSystem;
import com.hypixel.hytale.component.Store;
import javax.annotation.Nonnull;
import com.hypixel.hytale.builtin.weather.resources.WeatherResource;
import com.hypixel.hytale.component.ResourceType;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.system.StoreSystem;

public class WeatherSystem
{
    private static final float JOIN_TRANSITION_SECONDS = 0.5f;
    private static final float WEATHERCHANGE_TRANSITION_SECONDS = 10.0f;
    
    public static class WorldAddedSystem extends StoreSystem<EntityStore>
    {
        @Nonnull
        private final ResourceType<EntityStore, WeatherResource> weatherResourceType;
        
        public WorldAddedSystem() {
            this.weatherResourceType = WeatherResource.getResourceType();
        }
        
        @Override
        public void onSystemAddedToStore(@Nonnull final Store<EntityStore> store) {
            final String forcedWeather = store.getExternalData().getWorld().getWorldConfig().getForcedWeather();
            store.getResource(this.weatherResourceType).setForcedWeather(forcedWeather);
        }
        
        @Override
        public void onSystemRemovedFromStore(@Nonnull final Store<EntityStore> store) {
        }
    }
    
    public static class PlayerAddedSystem extends HolderSystem<EntityStore>
    {
        private static final ComponentType<EntityStore, PlayerRef> PLAYER_REF_COMPONENT_TYPE;
        private static final ComponentType<EntityStore, TransformComponent> TRANSFORM_COMPONENT_TYPE;
        private static final ComponentType<EntityStore, WeatherTracker> WEATHER_TRACKER_COMPONENT_TYPE;
        private static final Query<EntityStore> QUERY;
        
        @Override
        public Query<EntityStore> getQuery() {
            return PlayerAddedSystem.QUERY;
        }
        
        @Override
        public void onEntityAdd(@Nonnull final Holder<EntityStore> holder, @Nonnull final AddReason reason, @Nonnull final Store<EntityStore> store) {
            holder.ensureComponent(PlayerAddedSystem.WEATHER_TRACKER_COMPONENT_TYPE);
        }
        
        @Override
        public void onEntityRemoved(@Nonnull final Holder<EntityStore> holder, @Nonnull final RemoveReason reason, @Nonnull final Store<EntityStore> store) {
            final WeatherTracker weatherTrackerComponent = holder.ensureAndGetComponent(PlayerAddedSystem.WEATHER_TRACKER_COMPONENT_TYPE);
            weatherTrackerComponent.clear();
        }
        
        static {
            PLAYER_REF_COMPONENT_TYPE = PlayerRef.getComponentType();
            TRANSFORM_COMPONENT_TYPE = TransformComponent.getComponentType();
            WEATHER_TRACKER_COMPONENT_TYPE = WeatherTracker.getComponentType();
            QUERY = Archetype.of(PlayerAddedSystem.PLAYER_REF_COMPONENT_TYPE, PlayerAddedSystem.TRANSFORM_COMPONENT_TYPE);
        }
    }
    
    public static class TickingSystem extends EntityTickingSystem<EntityStore>
    {
        private static final ComponentType<EntityStore, PlayerRef> PLAYER_REF_COMPONENT_TYPE;
        private static final ComponentType<EntityStore, TransformComponent> TRANSFORM_COMPONENT_TYPE;
        private static final ComponentType<EntityStore, WeatherTracker> WEATHER_TRACKER_COMPONENT_TYPE;
        private static final ResourceType<EntityStore, WeatherResource> WEATHER_RESOURCE_TYPE;
        private static final Query<EntityStore> QUERY;
        
        @Override
        public Query<EntityStore> getQuery() {
            return TickingSystem.QUERY;
        }
        
        @Override
        public void tick(final float dt, final int systemIndex, @Nonnull final Store<EntityStore> store) {
            final WeatherResource weatherResource = store.getResource(TickingSystem.WEATHER_RESOURCE_TYPE);
            if (weatherResource.consumeForcedWeatherChange()) {
                weatherResource.playerUpdateDelay = 1.0f;
                store.tick(this, dt, systemIndex);
                return;
            }
            if (weatherResource.getForcedWeatherIndex() == 0) {
                final WorldTimeResource worldTimeResource = store.getResource(WorldTimeResource.getResourceType());
                final int currentHour = worldTimeResource.getCurrentHour();
                if (weatherResource.compareAndSwapHour(currentHour)) {
                    final Int2IntMap environmentWeather = weatherResource.getEnvironmentWeather();
                    final ThreadLocalRandom random = ThreadLocalRandom.current();
                    final IndexedLookupTableAssetMap<String, Environment> assetMap = Environment.getAssetMap();
                    for (final Map.Entry<String, Environment> entry : assetMap.getAssetMap().entrySet()) {
                        final String key = entry.getKey();
                        final int index = assetMap.getIndex(key);
                        if (index == Integer.MIN_VALUE) {
                            throw new IllegalArgumentException("Unknown key! " + key);
                        }
                        final IWeightedMap<WeatherForecast> weatherForecast = entry.getValue().getWeatherForecast(currentHour);
                        final int selectedWeatherIndex = weatherForecast.get(random).getWeatherIndex();
                        environmentWeather.put(index, selectedWeatherIndex);
                    }
                }
            }
            final WeatherResource weatherResource2 = weatherResource;
            weatherResource2.playerUpdateDelay -= dt;
            if (weatherResource.playerUpdateDelay <= 0.0f) {
                weatherResource.playerUpdateDelay = 1.0f;
                store.tick(this, dt, systemIndex);
            }
        }
        
        @Override
        public boolean isParallel(final int archetypeChunkSize, final int taskCount) {
            return false;
        }
        
        @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 WeatherResource weatherResource = store.getResource(TickingSystem.WEATHER_RESOURCE_TYPE);
            final PlayerRef playerRefComponent = archetypeChunk.getComponent(index, TickingSystem.PLAYER_REF_COMPONENT_TYPE);
            assert playerRefComponent != null;
            final TransformComponent transformComponent = archetypeChunk.getComponent(index, TickingSystem.TRANSFORM_COMPONENT_TYPE);
            assert transformComponent != null;
            final WeatherTracker weatherTrackerComponent = archetypeChunk.getComponent(index, TickingSystem.WEATHER_TRACKER_COMPONENT_TYPE);
            assert weatherTrackerComponent != null;
            final float transitionSeconds = weatherTrackerComponent.consumeFirstSendForWorld() ? 0.5f : 10.0f;
            weatherTrackerComponent.updateWeather(playerRefComponent, weatherResource, transformComponent, transitionSeconds, commandBuffer);
        }
        
        static {
            PLAYER_REF_COMPONENT_TYPE = PlayerRef.getComponentType();
            TRANSFORM_COMPONENT_TYPE = TransformComponent.getComponentType();
            WEATHER_TRACKER_COMPONENT_TYPE = WeatherTracker.getComponentType();
            WEATHER_RESOURCE_TYPE = WeatherResource.getResourceType();
            QUERY = Archetype.of(TickingSystem.PLAYER_REF_COMPONENT_TYPE, TickingSystem.TRANSFORM_COMPONENT_TYPE, TickingSystem.WEATHER_TRACKER_COMPONENT_TYPE);
        }
    }
    
    public static class InvalidateWeatherAfterTeleport extends RefChangeSystem<EntityStore, Teleport>
    {
        @Nonnull
        private static final Query<EntityStore> QUERY;
        @Nonnull
        private static final Set<Dependency<EntityStore>> DEPENDENCIES;
        
        @Nonnull
        @Override
        public ComponentType<EntityStore, Teleport> componentType() {
            return Teleport.getComponentType();
        }
        
        @Override
        public void onComponentAdded(@Nonnull final Ref<EntityStore> ref, @Nonnull final Teleport component, @Nonnull final Store<EntityStore> store, @Nonnull final CommandBuffer<EntityStore> commandBuffer) {
            final WeatherTracker weatherTrackerComponent = commandBuffer.getComponent(ref, WeatherTracker.getComponentType());
            assert weatherTrackerComponent != null;
            weatherTrackerComponent.clear();
        }
        
        @Override
        public void onComponentSet(@Nonnull final Ref<EntityStore> ref, @Nullable final Teleport oldComponent, @Nonnull final Teleport newComponent, @Nonnull final Store<EntityStore> store, @Nonnull final CommandBuffer<EntityStore> commandBuffer) {
        }
        
        @Override
        public void onComponentRemoved(@Nonnull final Ref<EntityStore> ref, @Nonnull final Teleport component, @Nonnull final Store<EntityStore> store, @Nonnull final CommandBuffer<EntityStore> commandBuffer) {
        }
        
        @Nullable
        @Override
        public Query<EntityStore> getQuery() {
            return InvalidateWeatherAfterTeleport.QUERY;
        }
        
        @Nonnull
        @Override
        public Set<Dependency<EntityStore>> getDependencies() {
            return InvalidateWeatherAfterTeleport.DEPENDENCIES;
        }
        
        static {
            QUERY = WeatherTracker.getComponentType();
            DEPENDENCIES = Set.of(new SystemDependency(Order.AFTER, TeleportSystems.PlayerMoveSystem.class));
        }
    }
}
