#include <SmeltingRuleRegistry/SmeltingRuleRegistry.hpp>
#include <SmeltingRule/BasicSmeltingRule/BasicSmeltingRule.hpp>
#include <SmeltingRule/OreSmeltingRule/OreSmeltingRule.hpp>
#include <SmeltingRule/DustSmeltingRule/DustSmeltingRule.hpp>
#include <BlockRegistry/BlockRegistry.hpp>

SmeltingRuleRegistry smeltingRuleRegistry;

void SmeltingRuleRegistry::registerRule(SmeltingRule *rule)
{
    rules.push_back(rule);
}

void SmeltingRuleRegistry::registerBasicRule(ItemStack input, ItemStack output)
{
    registerRule(new BasicSmeltingRule(input, output));
}

void SmeltingRuleRegistry::shutdown()
{
    for (auto& rule : rules)
    {
        delete rule;
    }
}

void SmeltingRuleRegistry::registerAllRules()
{
    registerRule(new OreSmeltingRule());
    registerRule(new DustSmeltingRule());
    
    registerBasicRule(
        blockRegistry.getBlockByName("main:stoneCopperOre").toItemStack(),
        ItemStack("main:copperIngot")
    );

    registerBasicRule(
        blockRegistry.getBlockByName("main:stoneTinOre").toItemStack(),
        ItemStack("main:tinIngot")
    );

    registerBasicRule(
        ItemStack("main:tinCopperBundle"),
        ItemStack("main:brassIngot")
    );

    registerBasicRule(
        ItemStack("main:brassCopperBundle"),
        ItemStack("main:bronzeIngot")
    );

    registerBasicRule(
        blockRegistry.getBlockByName("main:planks").toItemStack(),
        ItemStack("main:charcoal", 2)
    );

    registerBasicRule(
        blockRegistry.getBlockByName("main:sand").toItemStack(),
        blockRegistry.getBlockByName("main:glass").toItemStack()
    );

    registerBasicRule(
        ItemStack("main:rubberTreeSap"),
        ItemStack("main:rubber")
    );
}

bool SmeltingRuleRegistry::canSmelt(ItemStack &stack)
{
    std::list<SmeltingRule*>::iterator it;
    for (it=rules.begin(); it!=rules.end(); ++it)
    {
        SmeltingRule *rule = *it;
        if (rule->canSmelt(stack))
        {
            return true;
        }
    }

    return false;
}

ItemStack SmeltingRuleRegistry::getSmeltingResult(ItemStack &input)
{
    std::list<SmeltingRule*>::iterator it;
    for (it=rules.begin(); it!=rules.end(); ++it)
    {
        SmeltingRule *rule = *it;
        if (rule->canSmelt(input))
        {
            return rule->getSmeltingResult(input);
        }
    }

    return ItemStack();
}

int SmeltingRuleRegistry::getRuleCount()
{
    return (int) rules.size();
}