#pragma once

#include <cstdint>

enum class BlockType : std::uint8_t {
    Air = 0,

    Grass,
    Dirt,
    Stone,

    Sand,
    Gravel,
    Snow,

    Wood,
    Leaves,

    Sandstone,
    Ice,

    Water        = 11,

    Stick        = 12,
    WoodPickaxe  = 13,
    StonePickaxe = 14,
    WoodAxe      = 15,
    StoneAxe     = 16,
    WoodSword    = 17,
    StoneSword   = 18,
};

inline bool isSolid(BlockType type) {
    switch (type) {
        case BlockType::Air:
        case BlockType::Water:
        case BlockType::Stick:
        case BlockType::WoodPickaxe:
        case BlockType::StonePickaxe:
        case BlockType::WoodAxe:
        case BlockType::StoneAxe:
        case BlockType::WoodSword:
        case BlockType::StoneSword:
            return false;
        default:
            return true;
    }
}

inline bool isItem(BlockType t) {
    return static_cast<uint8_t>(t) >= 12;
}

inline float blockHardness(BlockType t) {
    switch(t) {
        case BlockType::Grass: return 0.6f;
        case BlockType::Dirt:  return 0.5f;
        case BlockType::Stone: return 4.0f;
        case BlockType::Sand:  return 0.5f;
        case BlockType::Gravel:return 0.6f;
        case BlockType::Snow:  return 0.3f;
        case BlockType::Wood:  return 2.0f;
        case BlockType::Leaves:return 0.2f;
        case BlockType::Sandstone: return 2.0f;
        case BlockType::Ice:   return 0.5f;
        default: return 999.0f; // unbreakable
    }
}

inline float toolSpeedMultiplier(BlockType tool, BlockType block) {
    bool isPickTarget = (block==BlockType::Stone||block==BlockType::Gravel||block==BlockType::Sandstone||block==BlockType::Ice);
    bool isAxeTarget  = (block==BlockType::Wood||block==BlockType::Leaves);
    if (tool==BlockType::WoodPickaxe && isPickTarget) return 3.0f;
    if (tool==BlockType::StonePickaxe && isPickTarget) return 6.0f;
    if (tool==BlockType::WoodAxe && isAxeTarget) return 3.0f;
    if (tool==BlockType::StoneAxe && isAxeTarget) return 6.0f;
    return 1.0f;
}

inline bool isTransparent(BlockType type) {
    switch (type) {
        case BlockType::Air:
        case BlockType::Leaves:
        case BlockType::Ice:
        case BlockType::Water:
            return true;
        default:
            return false;
    }
}

inline bool isFluid(BlockType type) {
    return type == BlockType::Water;
}