#ifndef FARM_LAND_HPP_
#define FARM_LAND_HPP_

#include <Block/SpriteBlock/SpriteBlock.hpp>

/**
 * @brief Represents the farm land block.
 * 
 * It is made by raking dirt or grass, with different nutrition levels.
 */
class FarmLand : public SpriteBlock
{
private:
    static std::vector<Sprite> makeSprites();

    static constexpr int waterUnitsPerLevel = 16;

    static constexpr int waterWaitMin = 60 * 1;
    static constexpr int waterWaitRange = 60 * 1;

    static constexpr uint32_t sigCheckWater = 1;

public:
    /*

        #            Farmland Meta Byte
        +-------+---+---+---+---+---+---+---+---+
        | Bit   | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
        +-------+---+---+---+---+---+---+---+---+
        | Field |   |   |   | a | water |  nut  |
        +-------+---+---+---+---+---+---+---+---+

        nut
            The nutrition level of the soil.
        
        water
            The water level in the soil.
        
        a
            The axis through which the lines run (X=0, Y=1).
    */

    FarmLand(std::string name);

    /**
     * @brief Get the water level of farm land given metadata.
     */
    static int getWaterLevelFromMeta(uint8_t meta);

    /**
     * @brief Get the nutrition level of farl land given metadata.
     */
    static int getNutritionFromMeta(uint8_t meta);

    /**
     * @brief Create a new metadata value based on an old one, with the specified properties.
     */
    static uint8_t makeUpdatedMeta(uint8_t oldMeta, int nutrition, int waterLevel);

    /**
     * @brief Schedule a water level check.
     */
    static void scheduleWaterCheck(LocalWorld &world, glm::ivec3 pos);

    virtual bool canManuallyDig() override;
    virtual bool isFluidInteractable() override;
    virtual void getCollisionBoxes(World &world, glm::ivec3 pos, std::vector<BoundingBox<wfixed>> &boxes) override;
    virtual void getHarvestedStacks(LocalWorld &world, glm::ivec3 pos, std::vector<ItemStack> &stacks) override;
    virtual void onInteract(LocalWorld &world, Player &player, glm::ivec3 pos, Side side, const RGBABytes &collisionKey) override;
    virtual void onPlaced(LocalWorld &world, Chunk &chunk, glm::ivec3 pos) override;
    virtual void onSignal(LocalWorld &world, glm::ivec3 pos, uint32_t code) override;
    virtual void onNeighborUpdated(LocalWorld &world, glm::ivec3 pos, Side side) override;
};

#endif