HDPlaceableUpgradeActivatable = {}
local HDPlaceableUpgradeActivatable_mt = Class(HDPlaceableUpgradeActivatable)

function HDPlaceableUpgradeActivatable.new(placeable)
    local self = setmetatable({}, HDPlaceableUpgradeActivatable_mt)
    self.placeable = placeable
    self.actionEventId = nil
    self.activateText = g_i18n:getText("hd_upgrade_action")
    return self
end

function HDPlaceableUpgradeActivatable:getIsActivatable()
    if self.placeable == nil or self.placeable.rootNode == nil or not entityExists(self.placeable.rootNode) then
        return false
    end
    if g_localPlayer == nil then
        return false
    end
    local x, y, z = getWorldTranslation(g_localPlayer.rootNode)
    local distance = self:getWorldDistance(x, y, z)
    return distance <= 30 and HDPlaceableUpgrade.canUpgrade(self.placeable, g_localPlayer.farmId)
end

function HDPlaceableUpgradeActivatable:getWorldDistance(x, y, z)
    local node = self.placeable.rootNode
    local px, py, pz = getWorldTranslation(node)
    return MathUtil.vector3Length(x - px, y - py, z - pz)
end

function HDPlaceableUpgradeActivatable:getDistance(x, y, z)
    -- The activation system normally expects small hand-tool distances. Scale
    -- building distances so large production halls remain reachable.
    return self:getWorldDistance(x, y, z) * 0.1
end

function HDPlaceableUpgradeActivatable:registerCustomInput(inputContext)
    local playerContext = (PlayerInputComponent and PlayerInputComponent.INPUT_CONTEXT_NAME) or "PLAYER"
    if inputContext ~= playerContext then
        return
    end
    local _, actionEventId = g_inputBinding:registerActionEvent(InputAction.HD_UPGRADE_BUILDING, self, self.onUpgrade, false, true, false, true)
    self.actionEventId = actionEventId
    g_inputBinding:setActionEventText(actionEventId, g_i18n:getText("hd_upgrade_action"))
    g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_HIGH)
    g_inputBinding:setActionEventTextVisibility(actionEventId, true)
end

function HDPlaceableUpgradeActivatable:removeCustomInput(inputContext)
    g_inputBinding:removeActionEventsByTarget(self)
    self.actionEventId = nil
end

function HDPlaceableUpgradeActivatable:onUpgrade()
    HDBuildingUpgradeEvent.sendRequest(self.placeable)
end

function HDPlaceableUpgradeActivatable:run()
    self:onUpgrade()
end
