#include <Decoration/Boulder/Boulder.hpp>

void Boulder::buildSphere(ISculptor &sculptor, GeneratorNode node, glm::ivec3 centerPos, int radius)
{
    glm::ivec3 pos;
    for (pos.z = -radius; pos.z <= radius; pos.z++)
    {
        for (pos.y = -radius; pos.y <= radius; pos.y++)
        {
            for (pos.x = -radius; pos.x <= radius; pos.x++)
            {
                if (pos.x * pos.x + pos.y * pos.y + pos.z * pos.z <= radius * radius)
                {
                    int posIndex = maxRadius * maxRadius * pos.z + maxRadius * pos.y + pos.x;

                    int chance = node[posIndex] % 1000;
                    const int chanceOfCopper = 16;
                    const int chanceOfIron = 8;
                    const int chanceOfBasalt = 4;
                    const int chanceOfDiamond = 2;
                    const int chanceOfUranium = 1;

                    if (chance < chanceOfCopper)
                    {
                        sculptor.place(centerPos + pos, "main:stoneCopperOre");
                    }
                    else if (chance < chanceOfCopper + chanceOfIron)
                    {
                        sculptor.place(centerPos + pos, "main:ironOre");
                    }
                    else if (chance < chanceOfCopper + chanceOfIron + chanceOfBasalt)
                    {
                        sculptor.place(centerPos + pos, "main:stoneBasalt");
                    }
                    else if (chance < chanceOfCopper + chanceOfIron + chanceOfBasalt + chanceOfDiamond)
                    {
                        sculptor.place(centerPos + pos, "main:diamondOreX");
                    }
                    else if (chance < chanceOfCopper + chanceOfIron + chanceOfBasalt + chanceOfDiamond + chanceOfUranium)
                    {
                        sculptor.place(centerPos + pos, "main:uraniumOreMantle");
                    }
                    else
                    {
                        sculptor.place(centerPos + pos, "main:stone");
                    }
                }
            }
        }
    }
}

void Boulder::build(ISculptor &sculptor, GeneratorNode node, glm::ivec3 pos)
{
    int radius = minRadius + (node.seed >> 32) % (maxRadius - minRadius);

    buildSphere(sculptor, node, pos, radius);
}

double Boulder::getAverageDensity(const TerrainGenerator::Cell &cell, GeneratorNode node)
{
    return 0.05 * (1.0 - cell.humidity) * cell.bumpiness * std::exp(-cell.height * 0.2);
}