--[[
    ActivatableObjectsSystemExtension

    Extends the activatable objects system to always add AIM action Events even if the player stands in more than one trigger.

	@author: 		BayernGamers
	@date: 			04.12.2025
	@version:		1.0

	History:		v1.0 @04.12.2025 - initial implementation in FS25
                    ------------------------------------------------------------------------------------------------------

	
	License:        Terms:
                        Usage:
                            Feel free to use this work as-is as long as you adhere to the following terms:
						Attribution:
							You must give appropriate credit to the original author when using this work.
						No Derivatives:
							You may not alter, transform, or build upon this work in any way.
						Usage:
							The work may be used for personal and commercial purposes, provided it is not modified or adapted.
						Additional Clause:
							This script may not be converted, adapted, or incorporated into any other game versions or platforms except by GIANTS Software.
]]
ActivatableObjectsSystemExtension = {}

function ActivatableObjectsSystemExtension.new(mission, superFunc, customMt)
    local self = superFunc(mission, customMt)

    self.currentAttachImplementsManuallyObject = nil

    return self
end

function ActivatableObjectsSystemExtension:updateObjects(dt)
    local farmId = g_currentMission:getFarmId()
    local nearestObject = nil
    local nearestDistance = math.huge

    for _, object in pairs(self.objects) do
        if (object.getIsActivatable == nil or object:getIsActivatable(self.dirX, self.dirY, self.dirZ))
            and (object.getHasAccess == nil or object:getHasAccess(farmId)) then

            local distance = (object.getDistance == nil or self.posX == nil) and math.huge
                or object:getDistance(self.posX, self.posY, self.posZ)

            local vehicle = object.vehicle
            if vehicle ~= nil and vehicle.spec_attachImplementsManually ~= nil then
                if nearestObject == nil or distance < nearestDistance then
                    nearestDistance = distance
                    nearestObject = object
                end
            end
        end
    end

    if nearestObject ~= self.currentAttachImplementsManuallyObject then
        self:removeInput(self.inputContext)

        if self.currentAttachImplementsManuallyObject ~= nil and self.currentAttachImplementsManuallyObject.deactivate ~= nil then
            self.currentAttachImplementsManuallyObject:deactivate()
        end

        self.currentAttachImplementsManuallyObject = nearestObject

        if nearestObject ~= nil then
            if nearestObject.activate ~= nil then
                nearestObject:activate()
            end
            self:registerInput(self.inputContext)
        end
    end

    if nearestObject ~= nil then
        if nearestObject.update ~= nil then
            nearestObject:update(dt)
        end
    end
end

function ActivatableObjectsSystemExtension:registerInput(inputContext)
	local currentAttachImplementsManuallyObject = self.currentAttachImplementsManuallyObject
    if currentAttachImplementsManuallyObject ~= self.currentActivatableObject then
        if currentAttachImplementsManuallyObject ~= nil then
            if inputContext ~= nil then
                g_inputBinding:beginActionEventsModification(inputContext)
            end
            if currentAttachImplementsManuallyObject.registerCustomInput ~= nil then
                currentAttachImplementsManuallyObject:registerCustomInput(inputContext)
            end
            if inputContext ~= nil then
                g_inputBinding:endActionEventsModification()
            end
        end
    end
end

function ActivatableObjectsSystemExtension:removeInput(inputContext)
    if inputContext ~= nil then
		g_inputBinding:beginActionEventsModification(inputContext)
	end
	if self.currentAttachImplementsManuallyObject ~= nil and self.currentAttachImplementsManuallyObject.removeCustomInput ~= nil then
		self.currentAttachImplementsManuallyObject:removeCustomInput()
	end
	if inputContext ~= nil then
		g_inputBinding:endActionEventsModification()
	end
end

ActivatableObjectsSystem.new = Utils.overwrittenFunction(ActivatableObjectsSystem.new, ActivatableObjectsSystemExtension.new)
ActivatableObjectsSystem.updateObjects = Utils.appendedFunction(ActivatableObjectsSystem.updateObjects, ActivatableObjectsSystemExtension.updateObjects)
ActivatableObjectsSystem.removeInput = Utils.appendedFunction(ActivatableObjectsSystem.removeInput, ActivatableObjectsSystemExtension.removeInput)
ActivatableObjectsSystem.registerInput = Utils.prependedFunction(ActivatableObjectsSystem.registerInput, ActivatableObjectsSystemExtension.registerInput)


