#include <BlockRegistry/BlockRegistry.hpp>
#include <GraphicsContext/GraphicsContext.hpp>
#include <Material/Material.hpp>
#include <Milestone/BrickByBrickMilestone/BrickByBrickMilestone.hpp>
#include <Milestone/BronzeAgeMilestone/BronzeAgeMilestone.hpp>
#include <Milestone/ElectronicsMilestone/ElectronicsMilestone.hpp>
#include <Milestone/CarpentryMilestone/CarpentryMilestone.hpp>
#include <Color/Color.hpp>
#include <Milestone/HydraulicsMilestone/HydraulicsMilestone.hpp>
#include <Milestone/MetalWorkingMilestone/MetalWorkingMilestone.hpp>

const std::string ElectronicsMilestone::ID = "main:Electronics";

ElectronicsMilestone::ElectronicsMilestone() :
    Milestone(
        Material::battery,
        Material::chargedBattery,
        "Electronics"
    )
{
    addAchievement(
        MakeCopperWire,
        blockRegistry.getBlockByName("main:copperWire").iconMaterial,
        blockRegistry.getBlockByName("main:copperWire").iconMaterial,
        "Make copper wire",
        "*{action|Construct} {block|main:copperWire|16}.\n"
        "@constructTable|main:copperWire|16|main:copperIngot|3\n",
        Dependency{BronzeAgeMilestone::ID, BronzeAgeMilestone::MineCopper}
    );

    addAchievement(
        MakeTinCasing,
        blockRegistry.getBlockByName("main:tinCasing").iconMaterial,
        blockRegistry.getBlockByName("main:tinCasing").iconMaterial,
        "Make tin casing",
        "*{action|Construct} {block|main:tinCasing|3}.\n"
        "@constructTable|main:tinCasing|3|main:tinIngot|3|main:ironIngot|1\n",
        Dependency{MetalWorkingMilestone::ID, MetalWorkingMilestone::MineIron}
    );

    addAchievement(
        MakeBattery,
        Material::battery,
        Material::chargedBattery,
        "Make a battery",
        "*{action|Construct} {item|main:battery}.\n"
        "@constructTable|main:battery|1|main:tinIngot|6|main:copperWire|2|main:nickelIngot|1|main:ironIngot|1\n",
        Dependency{ID, MakeCopperWire},
        Dependency{MetalWorkingMilestone::ID, MetalWorkingMilestone::MineIron},
        Dependency{MetalWorkingMilestone::ID, MetalWorkingMilestone::MineNickel}
    );

    addAchievement(
        MakeSteamGenerator,
        Material::steamGeneratorTodo,
        Material::steamGeneratorDone,
        "Steam generator",
        "*{action|Construct} a {block|main:steamGenerator}.\n"
        "@constructTable|main:steamGenerator|1"
        "|main:brick|32"
        "|main:ironIngot|4"
        "|main:battery|1"
        "|main:glass|3"
        "|main:copperWire|2"
        "|main:fluidPipe|2\n"
        "*Place the {machine|main:steamGenerator} and open it.\n",
        Dependency{ID, MakeBattery},
        Dependency{BrickByBrickMilestone::ID, BrickByBrickMilestone::MakeBrickItem},
        Dependency{BrickByBrickMilestone::ID, BrickByBrickMilestone::MakeGlass},
        Dependency{HydraulicsMilestone::ID, HydraulicsMilestone::MakeFluidPipe}
    );

    addAchievement(
        ChargeBattery,
        Material::battery,
        Material::chargedBattery,
        "Charge a battery",
        "*Open a {block|main:steamGenerator}.\n"
        "*Add water by placing a {action|capsule} in the {inputSlot}, or by"
        " using a {block|main:pump}.\n"
        "*Add fuel by placing a fuel in the {fuelSlot} (the fuels are the same"
        " as in a pot).\n"
        "*Watch the water be consumed and energy added to the generator.\n"
        "*Place a {item|main:battery} in the {rechargeSlot} to charge it.\n"
        "*Pick up the charged {item|main:battery}.",
        Dependency{ID, MakeBattery},
        Dependency{ID, MakeSteamGenerator}
    );

    addAchievement(
        MakeCoil,
        Material::coil,
        Material::coil,
        "Make a coil",
        "*{action|Construct} {item|main:coil|1}.\n"
        "@constructTable|main:coil|1|main:ironIngot|1|main:copperWire|3\n",
        Dependency{MetalWorkingMilestone::ID, MetalWorkingMilestone::MineIron},
        Dependency{ID, MakeCopperWire}
    );

    addAchievement(
        MakeChemicalReactor,
        blockRegistry.getBlockByName("main:tinCasing").iconMaterial,
        blockRegistry.getBlockByName("main:chemicalReactor").iconMaterial,
        "Make the chemical reactor block",
        "*{action|Construct} {block|main:chemicalReactor}.\n"
        "@constructTable|main:chemicalReactor|1|main:tinCasing|1|main:glass|3\n",
        Dependency{ID, MakeTinCasing},
        Dependency{BrickByBrickMilestone::ID, BrickByBrickMilestone::MakeGlass}
    );

    addAchievement(
        BuildChemicalReactor,
        Material::chemicalReactorTodo,
        Material::chemicalReactorDone,
        "Build a chemical reactor",
        "*Build a hollow {menu|5x5x5} cube of {block|main:tinCasing}.\n"
        "*Break the {menu|middle block} of one of the walls.\n"
        "*Place a {block|main:chemicalReactor} in the hole.\n",
        Dependency{ID, MakeChemicalReactor}
    );

    addAchievement(
        EngineeringTable,
        blockRegistry.getBlockByName("main:engineeringTable").iconMaterial,
        blockRegistry.getBlockByName("main:engineeringTable").iconMaterial,
        "Engineering table",
        "*{action|Construct} {block|main:engineeringTable}.\n"
        "@constructTable|main:engineeringTable|1"
        "|main:silverIngot|2"
        "|main:steelIngot|6"
        "|main:battery|1"
        "|main:copperWire|3\n"
        "*Place the {machine|main:engineeringTable} and open it.\n",
        Dependency{MetalWorkingMilestone::ID, MetalWorkingMilestone::MineSilver},
        Dependency{MetalWorkingMilestone::ID, MetalWorkingMilestone::MakeSteel}
    );

    addAchievement(
        MakeSolarPanel,
        blockRegistry.getBlockByName("main:solarPanel").iconMaterial,
        blockRegistry.getBlockByName("main:solarPanel").iconMaterial,
        "Make a solar panel",
        "*Open an {machine|main:engineeringTable}.\n"
        "*In the {icon|recipeBookIcon}{menu|Recipes} tab, {action|SET} the {block|main:solarPanel} recipe.\n"
        "*Place the ingredients into the input slots on the left.\n"
        "*Power the engineering table by placing a {item|main:battery} in the {rechargeSlot},"
        " or by connecting power through {block|main:copperWire}.\n"
        "*Wait for {block|main:solarPanel} to be constructed, and pick it up.\n"
        "@engTable|main:solarPanel|1"
        "|main:steelIngot|8"
        "|main:siliconSheet|4"
        "|main:copperIngot|1"
        "|main:glass|1",
        Dependency{ID, EngineeringTable},
        Dependency{MetalWorkingMilestone::ID, MetalWorkingMilestone::MakeSteel},
        Dependency{BrickByBrickMilestone::ID, BrickByBrickMilestone::MakeGlass},
        Dependency{MetalWorkingMilestone::ID, MetalWorkingMilestone::MakeSiliconSheet}
    );

    addAchievement(
        GenerateSolarEnergy,
        blockRegistry.getBlockByName("main:solarPanel").iconMaterial,
        blockRegistry.getBlockByName("main:solarPanel").iconMaterial,
        "Generate solar energy",
        "*Place a {block|main:solarPanel} in an open, sunny area, on top of {block|main:copperWire}.\n"
        "*Connect it to the {icon|electricInputIcon}{menu|electric input} of a machine.\n"
        "*Make the machine consume energy.\n"
        "*You will get this achievement when power is drained from the solar panel.\n",
        Dependency{ID, MakeSolarPanel}
    );

    addAchievement(
        MakeSteelCasing,
        blockRegistry.getBlockByName("main:steelCasing").iconMaterial,
        blockRegistry.getBlockByName("main:steelCasing").iconMaterial,
        "Make steel casing",
        "*{action|Construct} {block|main:steelCasing|3}.\n"
        "@constructTable|main:steelCasing|3|main:steelIngot|3|main:nickelIngot|1\n",
        Dependency{MetalWorkingMilestone::ID, MetalWorkingMilestone::MineNickel},
        Dependency{MetalWorkingMilestone::ID, MetalWorkingMilestone::MakeSteel}
    );

    addAchievement(
        MakeMacerator,
        blockRegistry.getBlockByName("main:steelCasing").iconMaterial,
        blockRegistry.getBlockByName("main:macerator").iconMaterial,
        "Make a macerator block",
        "*In the {icon|recipeBookIcon}{menu|Recipes} tab, {action|SET} the {block|main:macerator} recipe.\n"
        "*Place the ingredients into the input slots on the left.\n"
        "*Power the engineering table by placing a {item|main:battery} in the {rechargeSlot},"
        " or by connecting power through {block|main:copperWire}.\n"
        "*Wait for {block|main:macerator} to be constructed, and pick it up.\n"
        "@engTable|main:macerator|1|main:steelCasing|1|main:battery|1|main:goldIngot|4|main:leadIngot|2\n",
        Dependency{ID, EngineeringTable},
        Dependency{ID, MakeSteelCasing},
        Dependency{MetalWorkingMilestone::ID, MetalWorkingMilestone::MineGold},
        Dependency{MetalWorkingMilestone::ID, MetalWorkingMilestone::MineLead},
        Dependency{ID, MakeBattery}
    );

    addAchievement(
        BuildMacerator,
        blockRegistry.getBlockByName("main:macerator").iconMaterial,
        Material::maceratorDone,
        "Build a macerator",
        "*Build a hollow {menu|3x3x3} cube of {block|main:steelCasing}.\n"
        "*Break the {menu|middle block} of one of the walls.\n"
        "*Place a {block|main:macerator} in the hole.\n",
        Dependency{ID, MakeMacerator}
    );

    addAchievement(
        MakeElectricFurnace,
        blockRegistry.getBlockByName("main:tinCasing").iconMaterial,
        blockRegistry.getBlockByName("main:electricFurnace").iconMaterial,
        "Make an electric furnace block",
        "*In the {icon|recipeBookIcon}{menu|Recipes} tab, {action|SET} the {block|main:electricFurnace} recipe.\n"
        "*Place the ingredients into the input slots on the left.\n"
        "*Power the engineering table by placing a {item|main:battery} in the {rechargeSlot},"
        " or by connecting power through {block|main:copperWire}.\n"
        "*Wait for {block|main:electricFurnace} to be constructed, and pick it up.\n"
        "@engTable|main:electricFurnace|1|main:tinCasing|1|main:glass|4|main:battery|1|main:coil|20\n",
        Dependency{ID, EngineeringTable},
        Dependency{ID, MakeTinCasing},
        Dependency{BrickByBrickMilestone::ID, BrickByBrickMilestone::MakeGlass},
        Dependency{ID, MakeBattery},
        Dependency{ID, MakeCoil}
    );

    addAchievement(
        MakeDynamo,
        blockRegistry.getBlockByName("main:dynamo").iconMaterial,
        blockRegistry.getBlockByName("main:dynamo").iconMaterial,
        "Make a dynamo",
        "*{action|Construct} a {block|main:dynamo}.\n"
        "@constructTable|main:dynamo|1|main:tinIngot|6|main:nickelIngot|1|main:coil|1\n",
        Dependency{ID, MakeCoil},
        Dependency{MetalWorkingMilestone::ID, MetalWorkingMilestone::MineNickel},
        Dependency{MetalWorkingMilestone::ID, BronzeAgeMilestone::MineTin}
    );

    addAchievement(
        GenerateDynamoEnergy,
        blockRegistry.getBlockByName("main:dynamo").iconMaterial,
        blockRegistry.getBlockByName("main:dynamo").iconMaterial,
        "Generate energy from a dynamo",
        "*Place a {block|main:dynamo} on top of {block|main:copperWire}.\n"
        "*Connect it to the {icon|electricInputIcon}{menu|electric input} of a machine.\n"
        "*Make the machine consume energy.\n"
        "*Right-click the {block|main:dynamo} to generate energy.\n"
        "*You will get this achievement when power is drained from the dynamo.\n",
        Dependency{ID, MakeDynamo}
    );

    addAchievement(
        BuildElectricFurnace,
        blockRegistry.getBlockByName("main:electricFurnace").iconMaterial,
        Material::electricFurnaceDone,
        "Build an electric furnace",
        "*Build a hollow {menu|3x3x3} cube of {block|main:tinCasing}.\n"
        "*Break the {menu|middle block} of one of the walls.\n"
        "*Place a {block|main:electricFurnace} in the hole.\n",
        Dependency{ID, MakeElectricFurnace}
    );

    addAchievement(
        MakeAccumulator,
        blockRegistry.getBlockByName("main:accumulator").iconMaterial,
        blockRegistry.getBlockByName("main:accumulator").iconMaterial,
        "Make an accumulator",
        "*{action|Construct} an {block|main:accumulator}.\n"
        "@constructTable|main:accumulator|1|main:bronzeIngot|6|main:battery|3|main:copperWire|2\n",
        Dependency{ID, EngineeringTable},
        Dependency{BronzeAgeMilestone::ID, BronzeAgeMilestone::MakeBronze},
        Dependency{ID, MakeBattery},
        Dependency{ID, MakeCopperWire}
    );

    addAchievement(
        FullyChargeAccumulator,
        blockRegistry.getBlockByName("main:accumulator").iconMaterial,
        blockRegistry.getBlockByName("main:accumulator").iconMaterial,
        "Fully charge an accumulator",
        "*Open an {machine|main:accumulator}.\n"
        "*Place a {item|main:battery} in the {inputSlot}.\n"
        "OR\n"
        "*Connect {block|main:copperWire} to the {icon|electricInputIcon}{menu|electric input} side of the accumulator"
        " and supply power to it.\n"
        "*Wait for the energy to be transferred to the accumulator.\n"
        "*You will get this achievement when the accumulator is fully charged.\n",
        Dependency{ID, MakeAccumulator}
    );
}