package me.km.blocks;

import me.km.blocks.cookingpot.BlockCookingPot;
import net.minecraft.block.Block;
import net.minecraft.block.Block.Properties;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.material.MaterialColor;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.FireBlock;
import net.minecraft.block.LeavesBlock;
import net.minecraft.block.SlabBlock;
import net.minecraft.item.Item;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemGroup;
import net.minecraftforge.registries.IForgeRegistry;

public class ModBlocks {
    // ores + blocks
    public static Block copperOre;
    public static Block copperBlock;

    public static Block tinOre;
    public static Block tinBlock;

    public static Block bronzeBlock;

    public static Block silverOre;
    public static Block silverBlock;

    // misc
    public static Block guildblock;
    public static Block artefact;
    public static Block realHayBlock;
    public static Block realHayBed;

    public static Block crateAcacia;
    public static Block crateBigOak;
    public static Block crateBirch;
    public static Block crateJungle;
    public static Block crateOak;
    public static Block crateSpruce;

    public static Block cookingPotCopper;

    public static Block lantern;

    public static Block tallGrass;

    // traps
    public static Block spikesCopper;
    public static Block spikesBronze;
    public static Block spikesGold;
    public static Block spikesIron;

    // slabs
    public static Block gravelSlab;
    public static Block coarseDirtSlab;

    // leaves
    public static Block cherryLeaves;
    public static Block apricotLeaves;
    public static Block pearLeaves;
    public static Block plumLeaves;

    // saplings
    public static Block cherrySapling;
    public static Block apricotSapling;
    public static Block pearSapling;
    public static Block plumSapling;

    // bookshelves
    public static Block bookshelfAcacia;
    public static Block bookshelfBirch;
    public static Block bookshelfDarkOak;
    public static Block bookshelfJungle;
    public static Block bookshelfSpruce;

    private static Block create(String registry, Material m, float hardness, float resistance) {
        Block b = new Block(Properties.create(m).hardnessAndResistance(hardness, resistance));
        b.setRegistryName(registry);
        return b;
    }

    private static Block createCrate(String registry) {
        Block b = new Block(Properties.create(Material.WOOD).hardnessAndResistance(2.0f, 5.0f).sound(SoundType.WOOD));
        b.setRegistryName(registry);
        return b;
    }

    private static Block createOre(String registry, int harvestLevel) {
        Block b = new BlockOre(Properties.create(Material.ROCK).hardnessAndResistance(3.0f, 3.0f), harvestLevel);
        b.setRegistryName(registry);
        return b;
    }

    private static Block createOreBlock(String registry, MaterialColor mc, float hardness, float resistance, int harvestLevel) {
        Block b = new BlockOre(Properties.create(Material.IRON, mc).hardnessAndResistance(hardness, resistance), harvestLevel);
        b.setRegistryName(registry);
        return b;
    }

    private static Block createLeaves(String registry) {
        Block b = new LeavesBlock(Block.Properties.create(Material.LEAVES).hardnessAndResistance(0.2f).tickRandomly().sound(SoundType.PLANT).notSolid());
        b.setRegistryName(registry);
        return b;
    }

    private static Block createSapling(String registry, BlockState wood, BlockState leaves) {
        ModTree tree = new ModTree();
        BlockModSapling b = new BlockModSapling(tree);
        tree.setConfig(wood, leaves, b);
        b.setRegistryName(registry);
        return b;
    }

    private static Block createBookshelf(String registry) {
        Block b = new BlockBookshelf();
        b.setRegistryName(registry);
        return b;
    }

    public static void initBlocks(IForgeRegistry<Block> r) {
        // ores + blocks
        copperOre = register(r, createOre("copper_ore", 1));
        tinOre = register(r, createOre("tin_ore", 1));
        silverOre = register(r, createOre("silver_ore", 2));

        copperBlock = register(r, createOreBlock("copper_block", MaterialColor.BROWN, 3.0f, 6.0f, 1));
        tinBlock = register(r, createOreBlock("tin_block", MaterialColor.IRON, 3.0f, 6.0f, 1));
        silverBlock = register(r, createOreBlock("silver_block", MaterialColor.IRON, 5.0f, 6.0f, 2));
        bronzeBlock = register(r, createOreBlock("bronze_block", MaterialColor.YELLOW, 5.0f, 6.0f, 2));

        // misc
        guildblock = register(r, create("guild_block", Material.IRON, 50.0f, 2000.0f));
        artefact = register(r, create("artefact", Material.IRON, 50.0f, 2000.0f));
        realHayBlock = register(r, new BlockHay("real_hay_block"));
        realHayBed = register(r, new BlockHayBed("real_hay_bed"));

        crateAcacia = register(r, createCrate("crate_acacia"));
        crateBigOak = register(r, createCrate("crate_big_oak"));
        crateBirch = register(r, createCrate("crate_birch"));
        crateJungle = register(r, createCrate("crate_jungle"));
        crateOak = register(r, createCrate("crate_oak"));
        crateSpruce = register(r, createCrate("crate_spruce"));

        cookingPotCopper = register(r, new BlockCookingPot("cooking_pot_copper"));

        lantern = register(r, new BlockLantern("lantern"));

        tallGrass = register(r, new BlockResistantTallGrass("rtall_grass"));

        // traps
        spikesCopper = register(r, new BlockSpikes("spikes_copper", Properties.create(Material.IRON, MaterialColor.BROWN).hardnessAndResistance(3.0f, 6.0f)));
        spikesBronze = register(r, new BlockSpikes("spikes_bronze", Properties.create(Material.IRON, MaterialColor.YELLOW).hardnessAndResistance(5.0f, 6.0f)));
        spikesGold = register(r, new BlockSpikes("spikes_gold", Properties.create(Material.IRON, MaterialColor.GOLD).hardnessAndResistance(3.0f, 6.0f)));
        spikesIron = register(r, new BlockSpikes("spikes_iron", Properties.create(Material.IRON).hardnessAndResistance(5.0f, 6.0f)));

        // slabs
        gravelSlab = register(r, new BlockGravelSlab(Properties.create(Material.SAND, MaterialColor.STONE)
                .sound(SoundType.GROUND).hardnessAndResistance(0.6f)).setRegistryName("gravel_slab"));
        coarseDirtSlab = register(r, new SlabBlock(Properties.create(Material.EARTH, MaterialColor.DIRT)
                .sound(SoundType.GROUND).hardnessAndResistance(0.5f)).setRegistryName("coarse_dirt_slab"));

        // leaves
        cherryLeaves = register(r, createLeaves("cherry_leaves"));
        apricotLeaves = register(r, createLeaves("apricot_leaves"));
        pearLeaves = register(r, createLeaves("pear_leaves"));
        plumLeaves = register(r, createLeaves("plum_leaves"));

        // saplings
        cherrySapling = register(r, createSapling("cherry_sapling", Blocks.OAK_LOG.getDefaultState(), cherryLeaves.getDefaultState()));
        apricotSapling = register(r, createSapling("apricot_sapling", Blocks.OAK_LOG.getDefaultState(), apricotLeaves.getDefaultState()));
        pearSapling = register(r, createSapling("pear_sapling", Blocks.OAK_LOG.getDefaultState(), pearLeaves.getDefaultState()));
        plumSapling = register(r, createSapling("plum_sapling", Blocks.OAK_LOG.getDefaultState(), plumLeaves.getDefaultState()));

        // bookshelves
        bookshelfAcacia = register(r, createBookshelf("bookshelf_acacia"));
        bookshelfBirch = register(r, createBookshelf("bookshelf_birch"));
        bookshelfDarkOak = register(r, createBookshelf("bookshelf_dark_oak"));
        bookshelfJungle = register(r, createBookshelf("bookshelf_jungle"));
        bookshelfSpruce = register(r, createBookshelf("bookshelf_spruce"));

        FireBlock fireblock = (FireBlock) Blocks.FIRE;
        fireblock.setFireInfo(bookshelfAcacia, 30, 20);
        fireblock.setFireInfo(bookshelfBirch, 30, 20);
        fireblock.setFireInfo(bookshelfDarkOak, 30, 20);
        fireblock.setFireInfo(bookshelfJungle, 30, 20);
        fireblock.setFireInfo(bookshelfSpruce, 30, 20);
        fireblock.setFireInfo(cherryLeaves, 30, 60);
        fireblock.setFireInfo(apricotLeaves, 30, 60);
        fireblock.setFireInfo(pearLeaves, 30, 60);
        fireblock.setFireInfo(plumLeaves, 30, 60);
        fireblock.setFireInfo(crateAcacia, 5, 5);
        fireblock.setFireInfo(crateBigOak, 5, 5);
        fireblock.setFireInfo(crateBirch, 5, 5);
        fireblock.setFireInfo(crateJungle, 5, 5);
        fireblock.setFireInfo(crateOak, 5, 5);
        fireblock.setFireInfo(crateSpruce, 5, 5);
    }

    public static void initItemBlocks(IForgeRegistry<Item> r) {
        // ores + blocks
        register(r, copperOre, getItemBlock(copperOre, ItemGroup.BUILDING_BLOCKS));
        register(r, copperBlock, getItemBlock(copperBlock, ItemGroup.BUILDING_BLOCKS));

        register(r, tinOre, getItemBlock(tinOre, ItemGroup.BUILDING_BLOCKS));
        register(r, tinBlock, getItemBlock(tinBlock, ItemGroup.BUILDING_BLOCKS));

        register(r, bronzeBlock, getItemBlock(bronzeBlock, ItemGroup.BUILDING_BLOCKS));

        register(r, silverOre, getItemBlock(silverOre, ItemGroup.BUILDING_BLOCKS));
        register(r, silverBlock, getItemBlock(silverBlock, ItemGroup.BUILDING_BLOCKS));

        // misc
        register(r, guildblock, getItemBlock(guildblock, ItemGroup.BUILDING_BLOCKS));
        register(r, artefact, getItemBlock(artefact, ItemGroup.BUILDING_BLOCKS));

        register(r, realHayBlock, getItemBlock(realHayBlock, ItemGroup.BUILDING_BLOCKS));

        register(r, crateAcacia, getItemBlock(crateAcacia, ItemGroup.DECORATIONS));
        register(r, crateBigOak, getItemBlock(crateBigOak, ItemGroup.DECORATIONS));
        register(r, crateBirch, getItemBlock(crateBirch, ItemGroup.DECORATIONS));
        register(r, crateJungle, getItemBlock(crateJungle, ItemGroup.DECORATIONS));
        register(r, crateOak, getItemBlock(crateOak, ItemGroup.DECORATIONS));
        register(r, crateSpruce, getItemBlock(crateSpruce, ItemGroup.DECORATIONS));

        register(r, cookingPotCopper, getItemBlock(cookingPotCopper, ItemGroup.BREWING));

        register(r, lantern, getItemBlock(lantern, ItemGroup.DECORATIONS));
        register(r, tallGrass, getItemBlock(tallGrass, ItemGroup.DECORATIONS));

        // traps
        register(r, spikesCopper, getItemBlock(spikesCopper, ItemGroup.DECORATIONS));
        register(r, spikesBronze, getItemBlock(spikesBronze, ItemGroup.DECORATIONS));
        register(r, spikesGold, getItemBlock(spikesGold, ItemGroup.DECORATIONS));
        register(r, spikesIron, getItemBlock(spikesIron, ItemGroup.DECORATIONS));

        // slabs
        register(r, gravelSlab, getItemBlock(gravelSlab, ItemGroup.BUILDING_BLOCKS));
        register(r, coarseDirtSlab, getItemBlock(coarseDirtSlab, ItemGroup.BUILDING_BLOCKS));

        // leaves
        register(r, cherryLeaves, getItemBlock(cherryLeaves, ItemGroup.BUILDING_BLOCKS));
        register(r, apricotLeaves, getItemBlock(apricotLeaves, ItemGroup.BUILDING_BLOCKS));
        register(r, pearLeaves, getItemBlock(pearLeaves, ItemGroup.BUILDING_BLOCKS));
        register(r, plumLeaves, getItemBlock(plumLeaves, ItemGroup.BUILDING_BLOCKS));

        // saplings
        register(r, cherrySapling, getItemBlock(cherrySapling, ItemGroup.BUILDING_BLOCKS));
        register(r, apricotSapling, getItemBlock(apricotSapling, ItemGroup.BUILDING_BLOCKS));
        register(r, pearSapling, getItemBlock(pearSapling, ItemGroup.BUILDING_BLOCKS));
        register(r, plumSapling, getItemBlock(plumSapling, ItemGroup.BUILDING_BLOCKS));

        // bookshelves
        register(r, bookshelfAcacia, getItemBlock(bookshelfAcacia, ItemGroup.BUILDING_BLOCKS));
        register(r, bookshelfBirch, getItemBlock(bookshelfBirch, ItemGroup.BUILDING_BLOCKS));
        register(r, bookshelfDarkOak, getItemBlock(bookshelfDarkOak, ItemGroup.BUILDING_BLOCKS));
        register(r, bookshelfJungle, getItemBlock(bookshelfJungle, ItemGroup.BUILDING_BLOCKS));
        register(r, bookshelfSpruce, getItemBlock(bookshelfSpruce, ItemGroup.BUILDING_BLOCKS));
    }

    private static void register(IForgeRegistry<Item> r, Block block, Item itemBlock) {
        r.register(itemBlock);
    }

    private static Block register(IForgeRegistry<Block> r, Block block) {
        r.register(block);
        return block;
    }

    private static BlockItem getItemBlock(Block block, ItemGroup group) {
        BlockItem itemBlock = new BlockItem(block, new Item.Properties().group(group));
        itemBlock.setRegistryName(block.getRegistryName());
        return itemBlock;
    }
}
