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

package com.hypixel.hytale.server.worldgen.container;

import com.hypixel.hytale.server.worldgen.util.bounds.IChunkBounds;
import java.util.Objects;
import com.hypixel.hytale.server.core.prefab.selection.buffer.impl.IPrefabBuffer;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.server.core.prefab.PrefabRotation;
import com.hypixel.hytale.server.worldgen.util.condition.BlockMaskCondition;
import com.hypixel.hytale.server.worldgen.loader.WorldGenPrefabSupplier;
import com.hypixel.hytale.server.worldgen.prefab.PrefabCategory;
import java.util.Arrays;
import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.server.worldgen.prefab.unique.UniquePrefabConfiguration;
import java.util.Random;
import com.hypixel.hytale.math.util.FastRandom;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.worldgen.chunk.ChunkGenerator;
import javax.annotation.Nullable;
import com.hypixel.hytale.math.vector.Vector2i;
import com.hypixel.hytale.server.worldgen.prefab.unique.UniquePrefabGenerator;

public class UniquePrefabContainer
{
    protected final int seedOffset;
    protected final UniquePrefabGenerator[] generators;
    
    public UniquePrefabContainer(final int seedOffset, final UniquePrefabGenerator[] generators) {
        this.seedOffset = seedOffset;
        this.generators = generators;
    }
    
    public UniquePrefabGenerator[] getGenerators() {
        return this.generators;
    }
    
    @Nonnull
    public UniquePrefabEntry[] generate(final int seed, @Nullable final Vector2i position, @Nonnull final ChunkGenerator chunkGenerator) {
        final Random random = new FastRandom(seed + this.seedOffset);
        final UniquePrefabEntry[] entries = new UniquePrefabEntry[this.generators.length];
        for (int i = 0; i < this.generators.length; ++i) {
            final UniquePrefabGenerator generator = this.generators[i];
            final UniquePrefabConfiguration configuration = generator.getConfiguration();
            final Vector3i location = generator.generate(seed, position, chunkGenerator, random, configuration.getMaxAttempts(), entries);
            entries[i] = new UniquePrefabEntry(generator.getName(), generator.getCategory(), location, generator.generatePrefab(random), configuration.getPlacementConfiguration(), configuration.getRotation(random), configuration.getSpawnOffset(), configuration.getEnvironmentId(), configuration.isFitHeightmap(), configuration.isSubmerge(), configuration.getExclusionRadiusSquared(), configuration.isSpawnLocation(), configuration.isShowOnMap());
        }
        return entries;
    }
    
    @Nonnull
    @Override
    public String toString() {
        return "UniquePrefabContainer{seedOffset=" + this.seedOffset + ", generators=" + Arrays.toString(this.generators);
    }
    
    public static class UniquePrefabEntry
    {
        protected final String name;
        protected final PrefabCategory category;
        @Nonnull
        protected final Vector3i position;
        @Nonnull
        protected final WorldGenPrefabSupplier prefabSupplier;
        protected final BlockMaskCondition configuration;
        @Nonnull
        protected final PrefabRotation rotation;
        protected final Vector3d spawnOffset;
        protected final int lowBoundX;
        protected final int lowBoundY;
        protected final int lowBoundZ;
        protected final int highBoundX;
        protected final int highBoundY;
        protected final int highBoundZ;
        protected final int environmentId;
        protected final boolean fitHeightmap;
        protected final boolean submerge;
        protected final double exclusionRadiusSquared;
        protected final boolean spawnLocation;
        protected final boolean showOnMap;
        
        private UniquePrefabEntry(final String name, @Nonnull final PrefabCategory category, @Nonnull final Vector3i position, @Nonnull final WorldGenPrefabSupplier prefabSupplier, final BlockMaskCondition configuration, @Nonnull final PrefabRotation rotation, final Vector3d spawnOffset, final int environmentId, final boolean fitHeightmap, final boolean submergeable, final double exclusionRadiusSquared, final boolean spawnLocation, final boolean showOnMap) {
            this.name = name;
            this.category = category;
            this.position = position;
            this.prefabSupplier = prefabSupplier;
            this.configuration = configuration;
            this.rotation = rotation;
            this.spawnOffset = spawnOffset;
            this.environmentId = environmentId;
            this.fitHeightmap = fitHeightmap;
            this.submerge = submergeable;
            this.exclusionRadiusSquared = exclusionRadiusSquared;
            this.spawnLocation = spawnLocation;
            this.showOnMap = showOnMap;
            final IPrefabBuffer prefab = Objects.requireNonNull(prefabSupplier.get());
            final IChunkBounds bounds = prefabSupplier.getBounds(prefab);
            this.lowBoundY = position.y + prefab.getMinY();
            this.highBoundY = position.y + prefab.getMaxY();
            this.lowBoundX = position.x + bounds.getLowBoundX(rotation);
            this.lowBoundZ = position.z + bounds.getLowBoundZ(rotation);
            this.highBoundX = position.x + bounds.getHighBoundX(rotation);
            this.highBoundZ = position.z + bounds.getHighBoundZ(rotation);
        }
        
        public String getName() {
            return this.name;
        }
        
        @Nonnull
        public PrefabCategory getCategory() {
            return this.category;
        }
        
        @Nonnull
        public Vector3i getPosition() {
            return this.position;
        }
        
        @Nonnull
        public WorldGenPrefabSupplier getPrefabSupplier() {
            return this.prefabSupplier;
        }
        
        public BlockMaskCondition getConfiguration() {
            return this.configuration;
        }
        
        @Nonnull
        public PrefabRotation getRotation() {
            return this.rotation;
        }
        
        public Vector3d getSpawnOffset() {
            return this.spawnOffset;
        }
        
        public int getLowBoundX() {
            return this.lowBoundX;
        }
        
        public int getLowBoundY() {
            return this.lowBoundY;
        }
        
        public int getLowBoundZ() {
            return this.lowBoundZ;
        }
        
        public int getHighBoundX() {
            return this.highBoundX;
        }
        
        public int getHighBoundY() {
            return this.highBoundY;
        }
        
        public int getHighBoundZ() {
            return this.highBoundZ;
        }
        
        public int getEnvironmentId() {
            return this.environmentId;
        }
        
        public boolean isFitHeightmap() {
            return this.fitHeightmap;
        }
        
        public boolean isSubmerge() {
            return this.submerge;
        }
        
        public double getExclusionRadiusSquared() {
            return this.exclusionRadiusSquared;
        }
        
        public boolean isSpawnLocation() {
            return this.spawnLocation;
        }
        
        public boolean isShowOnMap() {
            return this.showOnMap;
        }
        
        @Nonnull
        @Override
        public String toString() {
            return "UniquePrefabEntry{position=" + String.valueOf(this.position) + ", prefabSupplier=" + String.valueOf(this.prefabSupplier) + ", configuration=" + String.valueOf(this.configuration) + ", rotation=" + String.valueOf(this.rotation) + ", lowBoundX=" + this.lowBoundX + ", lowBoundZ=" + this.lowBoundZ + ", highBoundX=" + this.highBoundX + ", highBoundZ=" + this.highBoundZ + ", fitHeightmap=" + this.fitHeightmap + ", submerge=" + this.submerge + ", exclusionRadiusSquared=" + this.exclusionRadiusSquared + ", spawnLocation=" + this.spawnLocation;
        }
    }
}
