package teamasm.moh.reference;

import codechicken.lib.util.ItemNBTUtils;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.WeightedRandom;
import teamasm.moh.init.ModItems;
import teamasm.moh.util.EnumFinalProduct;

import java.util.*;

/**
 * Created by brandon3055 on 6/08/2016.
 * This will be the registry that handles ALL the ores.
 */
public class OreRegistry {

    public static final OreRegistry INSTANCE = new OreRegistry();

    private List<String> oreList = new ArrayList<String>();
    private List<WeightedOre> weightedOres = new ArrayList<WeightedOre>();
    private static List<WeightedChance> weightedChance = new ArrayList<WeightedChance>();
    private Map<String, Integer> nameToGenWeight = new HashMap<String, Integer>();
    private Map<String, Integer> nameToColour = new HashMap<String, Integer>();
    private Map<String, Float> nameToMaxPurity = new HashMap<String, Float>();
    private Map<String, Float> nameToMinPurity = new HashMap<String, Float>();
    private Map<String, EnumFinalProduct> nameToProduct = new HashMap<String, EnumFinalProduct>();
    //todo Add getters as needed

    /**
     * The maximum possible ores per vein.
     */
    private static int maxOresPerOre = 5;

    static {
        for (int i = 1; i <= maxOresPerOre; i++) {
            int chance = maxOresPerOre - i;
            weightedChance.add(new WeightedChance(i, 1 + (chance * 2)));
        }
    }

    /**
     * @param oreName   The ore dictionary name of the ore.
     * @param genWeight The generation weight of the ore. Higher numbers have a higher chance to generate.
     * @param maxPurity The maximum purity this ore can spawn with. range 0 > 1. Should always be greater than 0. Purity of 1 = 4 ingots ber block.
     * @param oreColour The colour for the ore item.
     */
    public void registerOre(String oreName, int genWeight, float minPurity, float maxPurity, int oreColour, EnumFinalProduct product) {
        oreList.add(oreName);
        nameToGenWeight.put(oreName, genWeight);
        nameToColour.put(oreName, oreColour);
        weightedOres.add(new WeightedOre(oreName, genWeight));
        nameToMaxPurity.put(oreName, maxPurity);
        nameToMinPurity.put(oreName, minPurity);
        nameToProduct.put(oreName, product);
    }

    public List<String> getOreList() {
        return oreList;
    }

    public boolean isOreRegistered(String ore) {
        return oreList.contains(ore);
    }

    public ItemStack getRandomOreForSeed(Random random) { //TODO refine this and add support for purity when that mechanic gets implemented.
        int oreCount = WeightedRandom.getRandomItem(random, weightedChance).count;
        ItemStack stack = new ItemStack(ModItems.brokenOre);
        Map<String, Float> ores = new HashMap<String, Float>();

        for (int i = 0; i < oreCount; i++) {
            WeightedOre ore = WeightedRandom.getRandomItem(random, weightedOres);
            String name = ore.name;

            float min = nameToMinPurity.get(name);
            float purity = min + (random.nextFloat() * (nameToMaxPurity.get(name) - min));

            if (ores.containsKey(name)) {
                ores.put(name, ores.get(name) + purity);
            } else {
                ores.put(name, purity);
            }
        }

        NBTTagList oreList = new NBTTagList();
        for (String name : ores.keySet()) {
            NBTTagCompound oreCompound = new NBTTagCompound();
            oreCompound.setString("Name", name);
            oreCompound.setFloat("Purity", ores.get(name));
            oreList.appendTag(oreCompound);
        }

        NBTTagCompound itemCompound = ItemNBTUtils.validateTagExists(stack);
        itemCompound.setTag("Ores", oreList);

        return stack;
    }

    private static class WeightedOre extends WeightedRandom.Item {

        private final String name;

        public WeightedOre(String name, int itemWeightIn) {
            super(itemWeightIn);
            this.name = name;
        }
    }

    private static class WeightedChance extends WeightedRandom.Item {

        private final int count;

        public WeightedChance(int count, int itemWeightIn) {
            super(itemWeightIn);
            this.count = count;
        }
    }

    /**
     * Returns a map of ores contained within the given stack and their purity.
     *
     * @param stack the stack.
     * @return a map or ore name to purity.
     */
    public static Map<String, Float> getOres(ItemStack stack) {
        Map<String, Float> oreMap = new HashMap<String, Float>();
        NBTTagCompound compound = stack.getTagCompound();

        if (compound == null || !compound.hasKey("Ores")) {

            return oreMap;
        }

        NBTTagList oreList = compound.getTagList("Ores", 10);
        for (int i = 0; i < oreList.tagCount(); i++) {
            oreMap.put(oreList.getCompoundTagAt(i).getString("Name"), oreList.getCompoundTagAt(i).getFloat("Purity"));
        }

        return oreMap;
    }
}

@@ -52,25 +52,152 @@
 lib.
-util.ItemNBTUtils
+colour.Colour;%0Aimport codechicken.lib.colour.ColourARGB;%0Aimport codechicken.lib.util.ItemNBTUtils;%0Aimport com.google.common.collect.ImmutableMap
 ;%0Aim
@@ -972,38 +972,37 @@
 ate Map%3CString, 
-Intege
+Colou
 r%3E nameToColour 
@@ -1015,38 +1015,37 @@
 HashMap%3CString, 
-Intege
+Colou
 r%3E();%0A    privat
@@ -2258,16 +2258,31 @@
 reName, 
+new ColourARGB(
 oreColou
@@ -2283,16 +2283,17 @@
 eColour)
+)
 ;%0A      
@@ -2534,24 +2534,24 @@
 OreList() %7B%0A
-
         retu
@@ -2561,32 +2561,148 @@
 oreList;%0A    %7D%0A%0A
+    public ImmutableMap%3CString, Colour%3E getOreColourMap()%7B%0A        return ImmutableMap.copyOf(nameToColour);%0A    %7D%0A%0A
     public boole

Add Immutable getter for name to colour map.