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

package com.hypixel.hytale.server.worldgen.cave.element;

import java.util.Arrays;
import com.hypixel.hytale.math.util.ChunkUtil;
import java.util.function.LongConsumer;
import com.hypixel.hytale.math.util.MathUtil;
import com.hypixel.hytale.server.worldgen.util.bounds.IWorldBounds;
import com.hypixel.hytale.server.worldgen.util.bounds.IChunkBounds;
import com.hypixel.hytale.math.vector.Vector3d;
import java.util.ArrayList;
import javax.annotation.Nullable;
import java.util.List;
import com.hypixel.hytale.server.worldgen.util.bounds.WorldBounds;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.worldgen.cave.shape.CaveNodeShape;
import com.hypixel.hytale.server.worldgen.cave.CaveNodeType;

public class CaveNode implements CaveElement
{
    private final CaveNodeType caveNodeType;
    @Nonnull
    private final CaveNodeShape shape;
    @Nonnull
    private final WorldBounds bounds;
    private final int seedOffset;
    private final float pitch;
    private final float yaw;
    @Nullable
    private List<CavePrefab> rawCavePrefabs;
    private CavePrefab[] cavePrefabs;
    
    public CaveNode(final int seedOffset, final CaveNodeType caveNodeType, @Nonnull final CaveNodeShape shape, final float yaw, final float pitch) {
        this.seedOffset = seedOffset;
        this.rawCavePrefabs = new ArrayList<CavePrefab>();
        this.caveNodeType = caveNodeType;
        this.shape = shape;
        this.yaw = yaw;
        this.pitch = pitch;
        this.bounds = new WorldBounds(shape.getBounds());
    }
    
    public int getSeedOffset() {
        return this.seedOffset;
    }
    
    public CaveNodeType getCaveNodeType() {
        return this.caveNodeType;
    }
    
    @Nonnull
    public CaveNodeShape getShape() {
        return this.shape;
    }
    
    public CavePrefab[] getCavePrefabs() {
        return this.cavePrefabs;
    }
    
    public float getYaw() {
        return this.yaw;
    }
    
    public float getPitch() {
        return this.pitch;
    }
    
    public Vector3d getEnd() {
        return this.shape.getEnd();
    }
    
    public void addPrefab(@Nonnull final CavePrefab prefab) {
        this.rawCavePrefabs.add(prefab);
        this.bounds.include(prefab.getBounds());
    }
    
    @Nonnull
    @Override
    public IWorldBounds getBounds() {
        return this.bounds;
    }
    
    public int getFloorPosition(final int seed, final double x, final double z) {
        return MathUtil.floor(this.shape.getFloorPosition(seed, x, z));
    }
    
    public int getCeilingPosition(final int seed, final double x, final double z) {
        return MathUtil.floor(this.shape.getCeilingPosition(seed, x, z));
    }
    
    public void forEachChunk(@Nonnull final LongConsumer consumer) {
        final int lowZ = this.bounds.getLowChunkZ();
        final int highX = this.bounds.getHighChunkX();
        final int highZ = this.bounds.getHighChunkZ();
        for (int x = this.bounds.getLowChunkX(); x <= highX; ++x) {
            for (int z = lowZ; z <= highZ; ++z) {
                consumer.accept(ChunkUtil.indexChunk(x, z));
            }
        }
    }
    
    public void compile() {
        this.cavePrefabs = this.rawCavePrefabs.toArray(CavePrefab[]::new);
        this.rawCavePrefabs = null;
    }
    
    @Nonnull
    @Override
    public String toString() {
        return "CaveNode{cavePrefabs=" + Arrays.toString(this.cavePrefabs) + "rawCavePrefabs=" + Arrays.toString(this.cavePrefabs) + ", caveNodeType=" + String.valueOf(this.caveNodeType) + ", shape=" + String.valueOf(this.shape) + ", bounds=" + String.valueOf(this.bounds) + ", seedOffset=" + this.seedOffset + ", pitch=" + this.pitch + ", yaw=" + this.yaw;
    }
}
