-- Returns true if the player has an usable shovel, false otherwise.
local function predicateDigGrave(item)
    return not item:isBroken() and item:hasTag("DigGrave");
end

-- Returns true if the player has an usable hammer, false otherwise.
local function predicateHammer(item)
    return not item:isBroken() and item:hasTag("Hammer");
end

-- The player should only be able to build a well if he has a usable hammer and shovel and he has read the magazine
local function CanPlaceWell(playerInv, playerObj)
    local recipeName = "build well";
    if ISBuildMenu.cheat == true or
        (playerInv:getFirstEvalRecurse(predicateHammer) and
        playerInv:getFirstEvalRecurse(predicateDigGrave) and
        playerObj:isRecipeKnown(recipeName)) then
        return true;
    else
        return false;
    end
end

-- Add build option to world context menu
local function onFillWorldObjectContextMenu(player, context, worldobjects, test)
    local playerObj = getSpecificPlayer(player);
    local playerInv = playerObj:getInventory();
    local PLANK_REQ = 2;
    local NAILS_REQ = 2;
    local METAL_PIPE_REQ = 1;
    local STONE_REQ = 30;
    local ROPE_REQ = 1;
    local BUCKET_REQ = 1;
    local CARPENTRY_REQ = 6;
    local METALWORK_REQ = 1;

    if CanPlaceWell(playerInv, playerObj) then
        -- Define the well placement function
        local function doBuildWell(worldobjects, square, player)
            local shovel = playerInv:getFirstEvalRecurse(predicateDigGrave);
            if ISBuildMenu.cheat == true or shovel then
                local well = WellObject:new("Well", "camping_01_16");
                well.modData["xp:Woodwork"] = 200;
                well.modData["need:Base.Plank"] = PLANK_REQ;
                well.modData["need:Base.Nails"] = NAILS_REQ;
                well.modData["need:Base.Stone"] = STONE_REQ;
                well.modData["need:Base.MetalPipe"] = METAL_PIPE_REQ;
                well.modData["need:Base.Rope"] = ROPE_REQ;
                well.modData["need:Base.BucketEmpty"] = BUCKET_REQ;
                well.player = player;
                well.maxTime = 2400;
                well.completionSound = "BuildFenceCairn";
                getCell():setDrag(well, player);
            end
        end

        local buildWellOption =
            context:insertOptionAfter(getText("ContextMenu_Build"), getText("ContextMenu_BuildWell"), worldobjects, doBuildWell, square, player);
        local tooltip = ISBuildMenu.canBuild(PLANK_REQ, NAILS_REQ, 0, 0, 0, CARPENTRY_REQ, buildWellOption, player);
        tooltip.description = getText("ContextMenu_BuildWellTooltipShortDesc") .. " <LINE><LINE>";

        -- Setup build requirements on tooltip
        local planks = ISBuildMenu.countMaterial(player, "Base.Plank");
        if planks < PLANK_REQ then
            tooltip.description =
                tooltip.description .. " <RGB:1,0,0>" .. getItemNameFromFullType("Base.Plank") .. " " .. planks .. "/" .. PLANK_REQ .. " <LINE>";
            if not ISBuildMenu.cheat then
                buildWellOption.onSelect = nil;
                buildWellOption.notAvailable = true;
            end
        else
            tooltip.description =
                tooltip.description .. " <RGB:1,1,1>" .. getItemNameFromFullType("Base.Plank") .. " " .. planks .. "/" .. PLANK_REQ .. " <LINE>";
        end

        local nails = ISBuildMenu.countMaterial(player, "Base.Nails");
        if nails < NAILS_REQ then
            tooltip.description =
                tooltip.description .. " <RGB:1,0,0>" .. getItemNameFromFullType("Base.Nails") .. " " .. nails .. "/" .. NAILS_REQ .. " <LINE>";
            if not ISBuildMenu.cheat then
                buildWellOption.onSelect = nil;
                buildWellOption.notAvailable = true;
            end
        else
            tooltip.description =
                tooltip.description .. " <RGB:1,1,1>" .. getItemNameFromFullType("Base.Nails") .. " " .. nails .. "/" .. NAILS_REQ .. " <LINE>";
        end

        local stones = ISBuildMenu.countMaterial(player, "Base.Stone");
        if stones < STONE_REQ then
            tooltip.description =
                tooltip.description .. " <RGB:1,0,0>" .. getItemNameFromFullType("Base.Stone") .. " " .. stones .. "/" .. STONE_REQ .. " <LINE>";
            if not ISBuildMenu.cheat then
                buildWellOption.onSelect = nil;
                buildWellOption.notAvailable = true;
            end
        else
            tooltip.description =
                tooltip.description .. " <RGB:1,1,1>" .. getItemNameFromFullType("Base.Stone") .. " " .. stones .. "/" .. STONE_REQ .. " <LINE>";
        end

        local metalPipes = ISBuildMenu.countMaterial(player, "Base.MetalPipe");
        if metalPipes < METAL_PIPE_REQ then
            tooltip.description =
                tooltip.description .. " <RGB:1,0,0>" .. getItemNameFromFullType("Base.MetalPipe") .. " " .. metalPipes .. "/" .. METAL_PIPE_REQ .. " <LINE>";
            if not ISBuildMenu.cheat then
                buildWellOption.onSelect = nil;
                buildWellOption.notAvailable = true;
            end
        else
            tooltip.description =
                tooltip.description .. " <RGB:1,1,1>" .. getItemNameFromFullType("Base.MetalPipe") .. " " .. metalPipes .. "/" .. METAL_PIPE_REQ .. " <LINE>";
        end

        local rope = ISBuildMenu.countMaterial(player, "Base.Rope");
        if rope < ROPE_REQ then
            tooltip.description =
                tooltip.description .. " <RGB:1,0,0>" .. getItemNameFromFullType("Base.Rope") .. " " .. rope .. "/" .. ROPE_REQ .. " <LINE>";
            if not ISBuildMenu.cheat then
                buildWellOption.onSelect = nil;
                buildWellOption.notAvailable = true;
            end
        else
            tooltip.description =
                tooltip.description .. " <RGB:1,1,1>" .. getItemNameFromFullType("Base.Rope") .. " " .. rope .. "/" .. ROPE_REQ .. " <LINE>";
        end

        local bucket = ISBuildMenu.countMaterial(player, "Base.BucketEmpty");
        if bucket < BUCKET_REQ then
            tooltip.description =
                tooltip.description .. " <RGB:1,0,0>" .. getItemNameFromFullType("Base.BucketEmpty") .. " " .. bucket .. "/" .. BUCKET_REQ .. " <LINE>";
            if not ISBuildMenu.cheat then
                buildWellOption.onSelect = nil;
                buildWellOption.notAvailable = true;
            end
        else
            tooltip.description =
                tooltip.description .. " <RGB:1,1,1>" .. getItemNameFromFullType("Base.BucketEmpty") .. " " .. bucket .. "/" .. BUCKET_REQ .. " <LINE>";
        end

        if playerObj:getPerkLevel(Perks.Woodwork) < CARPENTRY_REQ then
            tooltip.description =
                tooltip.description .. " <RGB:1,0,0>" .. getText("IGUI_perks_Carpentry") .. " " .. playerObj:getPerkLevel(Perks.Woodwork) .. "/" .. CARPENTRY_REQ .. " <LINE>";
            if not ISBuildMenu.cheat then
                buildWellOption.onSelect = nil;
                buildWellOption.notAvailable = true;
            end
        else
            tooltip.description =
                tooltip.description .. " <RGB:1,1,1>" .. getText("IGUI_perks_Carpentry") .. " " .. playerObj:getPerkLevel(Perks.Woodwork) .. "/" .. CARPENTRY_REQ .. " <LINE>";
        end

        if playerObj:getPerkLevel(Perks.MetalWelding) < METALWORK_REQ then
            tooltip.description =
                tooltip.description .. " <RGB:1,0,0>" .. getText("IGUI_perks_MetalWelding") .. " " .. playerObj:getPerkLevel(Perks.MetalWelding) .. "/" .. METALWORK_REQ .. " <LINE>";
            if not ISBuildMenu.cheat then
                buildWellOption.onSelect = nil;
                buildWellOption.notAvailable = true;
            end
        else
            tooltip.description =
                tooltip.description .. " <RGB:1,1,1>" .. getText("IGUI_perks_MetalWelding") .. " " .. playerObj:getPerkLevel(Perks.MetalWelding) .. "/" .. METALWORK_REQ .. " <LINE>";
        end

        tooltip:setTexture("camping_01_16");
        tooltip:setName(getText("ContextMenu_BuildWellTooltipName"));
        ISBuildMenu.requireHammer(buildWellOption);
    end
end
Events.OnFillWorldObjectContextMenu.Add(onFillWorldObjectContextMenu);