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

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

import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.server.core.universe.world.chunk.BlockChunk;
import com.hypixel.hytale.math.util.MathUtil;
import com.hypixel.hytale.protocol.Packet;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.builtin.weather.resources.WeatherResource;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import javax.annotation.Nonnull;
import com.hypixel.hytale.builtin.weather.WeatherPlugin;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.protocol.packets.world.UpdateWeather;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Component;

public class WeatherTracker implements Component<EntityStore>
{
    private final UpdateWeather updateWeather;
    private final Vector3i previousBlockPosition;
    private int environmentId;
    private boolean firstSendForWorld;
    
    public static ComponentType<EntityStore, WeatherTracker> getComponentType() {
        return WeatherPlugin.get().getWeatherTrackerComponentType();
    }
    
    public WeatherTracker() {
        this.updateWeather = new UpdateWeather(0, 10.0f);
        this.previousBlockPosition = new Vector3i();
        this.firstSendForWorld = true;
    }
    
    private WeatherTracker(@Nonnull final WeatherTracker other) {
        this.updateWeather = new UpdateWeather(0, 10.0f);
        this.previousBlockPosition = new Vector3i();
        this.firstSendForWorld = true;
        this.environmentId = other.environmentId;
        this.updateWeather.weatherIndex = other.updateWeather.weatherIndex;
        this.previousBlockPosition.assign(other.previousBlockPosition);
    }
    
    public void updateWeather(@Nonnull final PlayerRef playerRef, @Nonnull final WeatherResource weatherComponent, @Nonnull final TransformComponent transformComponent, final float transitionSeconds, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final int forcedWeatherIndex = weatherComponent.getForcedWeatherIndex();
        if (forcedWeatherIndex != 0) {
            this.sendWeatherIndex(playerRef, forcedWeatherIndex, transitionSeconds);
            return;
        }
        this.updateEnvironment(transformComponent, componentAccessor);
        final int weatherIndexForEnvironment = weatherComponent.getWeatherIndexForEnvironment(this.environmentId);
        this.sendWeatherIndex(playerRef, weatherIndexForEnvironment, transitionSeconds);
    }
    
    public void sendWeatherIndex(@Nonnull final PlayerRef playerRef, int weatherIndex, final float transitionSeconds) {
        if (weatherIndex == Integer.MIN_VALUE) {
            weatherIndex = 0;
        }
        if (this.updateWeather.weatherIndex != weatherIndex) {
            this.updateWeather.weatherIndex = weatherIndex;
            this.updateWeather.transitionSeconds = transitionSeconds;
            playerRef.getPacketHandler().write(this.updateWeather);
        }
    }
    
    public boolean consumeFirstSendForWorld() {
        if (this.firstSendForWorld) {
            this.firstSendForWorld = false;
            return true;
        }
        return false;
    }
    
    public void clear() {
        this.updateWeather.weatherIndex = 0;
        this.firstSendForWorld = true;
    }
    
    public void updateEnvironment(@Nonnull final TransformComponent transformComponent, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final Vector3d vector = transformComponent.getPosition();
        final int blockX = MathUtil.floor(vector.getX());
        final int blockY = MathUtil.floor(vector.getY());
        final int blockZ = MathUtil.floor(vector.getZ());
        if (this.previousBlockPosition.getX() != blockX || this.previousBlockPosition.getY() != blockY || this.previousBlockPosition.getZ() != blockZ) {
            final Ref<ChunkStore> chunkRef = transformComponent.getChunkRef();
            if (chunkRef == null || !chunkRef.isValid()) {
                return;
            }
            final World world = componentAccessor.getExternalData().getWorld();
            final Store<ChunkStore> chunkStore = world.getChunkStore().getStore();
            final BlockChunk blockChunkComponent = chunkStore.getComponent(chunkRef, BlockChunk.getComponentType());
            assert blockChunkComponent != null;
            final int y = MathUtil.clamp(blockY, 0, 319);
            this.environmentId = blockChunkComponent.getEnvironment(blockX, y, blockZ);
        }
        this.previousBlockPosition.x = blockX;
        this.previousBlockPosition.y = blockY;
        this.previousBlockPosition.z = blockZ;
    }
    
    public int getEnvironmentId() {
        return this.environmentId;
    }
    
    public int getWeatherIndex() {
        return this.updateWeather.weatherIndex;
    }
    
    public void setWeatherIndex(@Nonnull final PlayerRef playerRef, final int weatherIndex) {
        this.updateWeather.weatherIndex = weatherIndex;
        playerRef.getPacketHandler().write(this.updateWeather);
    }
    
    @Nonnull
    @Override
    public Component<EntityStore> clone() {
        return new WeatherTracker(this);
    }
}
