package ca.recrown.islandsurvivalcraft.utilities.biomes;

import java.util.Arrays;

import org.bukkit.block.Biome;

import ca.recrown.islandsurvivalcraft.utilities.weighting.Weightable;
import ca.recrown.islandsurvivalcraft.utilities.weighting.WeightedSelector;

public enum BiomeClassifications implements Weightable {
    SNOWY(0.2f, new OceanBiomeInfo(Biome.FROZEN_OCEAN, Biome.COLD_OCEAN, Biome.DEEP_FROZEN_OCEAN),
        new LandBiomeInfo(Biome.SNOWY_TAIGA, null, Biome.SNOWY_TAIGA_HILLS, Biome.SNOWY_BEACH, 0.3f), 
        new LandBiomeInfo(Biome.SNOWY_TAIGA_MOUNTAINS, Biome.SNOWY_TAIGA, null, Biome.SNOWY_BEACH, 0.25f), 
        new LandBiomeInfo(Biome.SNOWY_TUNDRA, null, null, Biome.SNOWY_BEACH, 0.3f), 
        new LandBiomeInfo(Biome.ICE_SPIKES, null, null, Biome.SNOWY_BEACH, 0.15f)
    ),
    COLD(0.3f, new OceanBiomeInfo(Biome.COLD_OCEAN, null, Biome.DEEP_COLD_OCEAN),
        new LandBiomeInfo(Biome.MOUNTAINS, null, null, Biome.STONE_SHORE, 0.14f),
        new LandBiomeInfo(Biome.GRAVELLY_MOUNTAINS, 0.1f),
        new LandBiomeInfo(Biome.WOODED_MOUNTAINS, 0.08f),
        new LandBiomeInfo(Biome.MODIFIED_GRAVELLY_MOUNTAINS, 0.08f),
        new LandBiomeInfo(Biome.TAIGA, null, Biome.TAIGA_HILLS, Biome.BEACH, 0.15f),
        new LandBiomeInfo(Biome.TAIGA_MOUNTAINS, 0.15f),
        new LandBiomeInfo(Biome.GIANT_TREE_TAIGA, null, Biome.GIANT_TREE_TAIGA_HILLS, Biome.BEACH, 0.15f),
        new LandBiomeInfo(Biome.GIANT_SPRUCE_TAIGA, null, Biome.GIANT_SPRUCE_TAIGA_HILLS, Biome.BEACH, 0.15f)
    ),
    LUSH(0.3f, new OceanBiomeInfo(Biome.WARM_OCEAN, Biome.LUKEWARM_OCEAN, Biome.DEEP_LUKEWARM_OCEAN),
        new LandBiomeInfo(Biome.PLAINS, 0.15f),
        new LandBiomeInfo(Biome.SUNFLOWER_PLAINS, 0.075f),
        new LandBiomeInfo(Biome.FOREST, null, Biome.WOODED_HILLS, Biome.BEACH, 0.1f),
        new LandBiomeInfo(Biome.FLOWER_FOREST, 0.05f),
        new LandBiomeInfo(Biome.BIRCH_FOREST, null, Biome.BIRCH_FOREST_HILLS, Biome.BEACH, 0.1f),
        new LandBiomeInfo(Biome.TALL_BIRCH_FOREST, null, Biome.TALL_BIRCH_HILLS, Biome.BEACH, 0.075f),
        new LandBiomeInfo(Biome.DARK_FOREST, null, Biome.DARK_FOREST_HILLS, Biome.BEACH, 0.075f),
        new LandBiomeInfo(Biome.SWAMP, null, Biome.SWAMP_HILLS, null, 0.1f),
        new LandBiomeInfo(Biome.JUNGLE, Biome.JUNGLE_EDGE, Biome.JUNGLE_HILLS, Biome.BEACH, 0.075f),
        new LandBiomeInfo(Biome.MODIFIED_JUNGLE, Biome.MODIFIED_JUNGLE_EDGE, null, Biome.BEACH, 0.075f),
        new LandBiomeInfo(Biome.BAMBOO_JUNGLE, null, Biome.BAMBOO_JUNGLE_HILLS, Biome.BEACH, 0.075f),
        new LandBiomeInfo(Biome.MUSHROOM_FIELDS, null, null, Biome.MUSHROOM_FIELD_SHORE, 0.05f)
    ),
    WARM(0.2f, new OceanBiomeInfo(Biome.OCEAN, null, Biome.DEEP_OCEAN),
        new LandBiomeInfo(Biome.DESERT, null, Biome.DESERT_HILLS, Biome.BEACH, 0.2f),
        new LandBiomeInfo(Biome.SAVANNA, 0.2f),
        new LandBiomeInfo(Biome.SHATTERED_SAVANNA, 0.075f),
        new LandBiomeInfo(Biome.BADLANDS, 0.075f),
        new LandBiomeInfo(Biome.ERODED_BADLANDS, 0.075f),
        new LandBiomeInfo(Biome.WOODED_BADLANDS_PLATEAU, 0.075f),
        new LandBiomeInfo(Biome.MODIFIED_WOODED_BADLANDS_PLATEAU, 0.075f),
        new LandBiomeInfo(Biome.BADLANDS_PLATEAU, 0.075f),
        new LandBiomeInfo(Biome.SAVANNA_PLATEAU, 0.05f),
        new LandBiomeInfo(Biome.MODIFIED_BADLANDS_PLATEAU, 0.05f),
        new LandBiomeInfo(Biome.SHATTERED_SAVANNA_PLATEAU, 0.05f)
    ),
    ;
    
    private final LandBiomeInfo[] biomeInfos;
    private final float weight;
    private final OceanBiomeInfo associatedOceanBiomeInfo;
    private final WeightedSelector<LandBiomeInfo> selector;

    BiomeClassifications(float weight, OceanBiomeInfo oceanBiomeInfo, LandBiomeInfo... biomeInfos) {
        this.biomeInfos = biomeInfos;
        this.weight = weight;
        this.associatedOceanBiomeInfo = oceanBiomeInfo;
        selector = new WeightedSelector<>(Arrays.asList(biomeInfos));
    }

    /**
     * @return the biomes associated with this classification.
     */
    public LandBiomeInfo[] getBiomeInfos() {
        return biomeInfos;
    }

    @Override
    public float getWeight() {
        return weight;
    }

    /**
     * @return the associatedOceanBiomeInfo
     */
    public OceanBiomeInfo getAssociatedOceanBiomeInfo() {
        return associatedOceanBiomeInfo;
    }

    /**
     * @return the selector
     */
    public WeightedSelector<LandBiomeInfo> getSelector() {
        return selector;
    }
}