--[[
    PowerTakeOffUtil.lua

    Utilities for power take-offs

	@author: 		BayernGamers
	@date: 			27.05.2026
	@version:		1.1

	History:		v1.0 @05.12.2025 - initial implementation in FS25
                    ------------------------------------------------------------------------------------------------------
                    v1.1 @ 27.05.2026 - fixed LUA Call stacks

	
	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.
                        Non-Compete:
                            This script may not be used in any scripts or mods that can be considered to be a direct competitor to the mod this script is part of.
						Additional Clause:
							This script may not be converted, adapted, or incorporated into any other game versions or platforms except by GIANTS Software.
]]
source(Utils.getFilename("scripts/utils/Logger.lua", g_currentModDirectory))

local log = Logger.new(true, Logger.DEBUG_LEVELS.HIGH, "PowerTakeOffUtil.lua")

PowerTakeOffUtil = {}

function PowerTakeOffUtil.getHasOutputPTO(vehicle, inputAttacherJointIndex)
    log:printDevInfo("Checking for output PTO", Logger.DEBUG_LEVELS.LOW)
    log:printDevInfo("vehicle: " .. tostring(vehicle), Logger.DEBUG_LEVELS.LOW)
    log:printDevInfo("vehicle.spec_powerTakeOffs: " .. tostring(vehicle ~= nil and vehicle.spec_powerTakeOffs or nil), Logger.DEBUG_LEVELS.LOW)
    log:printDevInfo("attacherJointIndex: " .. tostring(inputAttacherJointIndex), Logger.DEBUG_LEVELS.LOW)
    if vehicle ~= nil and vehicle.spec_powerTakeOffs ~= nil and inputAttacherJointIndex ~= nil and vehicle.getOutputPowerTakeOffsByJointDescIndex ~= nil then
        log:printDevInfo("Checking for output PTO on vehicle: " .. tostring(vehicle:getName()) .. " at joint index: " .. tostring(inputAttacherJointIndex), Logger.DEBUG_LEVELS.LOW)
        local powerTakeOffs = vehicle:getOutputPowerTakeOffsByJointDescIndex(inputAttacherJointIndex)
        if powerTakeOffs == nil then
            return false
        end

        log:printDevInfo("Found " .. tostring(#powerTakeOffs) .. " output PTO(s)", Logger.DEBUG_LEVELS.LOW)
        if #powerTakeOffs > 0 then
            return true
        end
    end

    return false
end

function PowerTakeOffUtil.getHasInputPTO(vehicle, inputAttacherJointDescIndex)
    if vehicle == nil or inputAttacherJointDescIndex == nil then
        return false
    end

    local spec = vehicle.spec_powerTakeOffs
    if spec == nil then
        return false
    end

    if spec.inputPowerTakeOffs == nil or spec.outputPowerTakeOffs == nil then
        return false
    end
    
    for _, input in pairs(spec.inputPowerTakeOffs) do
        if input.inputAttacherJointIndices ~= nil and input.inputAttacherJointIndices[inputAttacherJointDescIndex] ~= nil then
            return true
        end
    end
    
    for _, output in pairs(spec.outputPowerTakeOffs) do
        if output.skipToInputAttacherIndex == inputAttacherJointDescIndex then
            if output.attacherJointIndices == nil then
                return false
            end

            for attacherJointIndex, _ in pairs(output.attacherJointIndices) do
                local implement = nil
                if vehicle.getImplementFromAttacherJointIndex ~= nil then
                    implement = vehicle:getImplementFromAttacherJointIndex(attacherJointIndex)
                end

                if implement ~= nil and implement.object ~= nil and implement.object.getHasInputPTO ~= nil then
                    if implement.object:getHasInputPTO(implement.inputJointDescIndex) then
                        return true
                    end
                end
            end
        end
    end
    
    return false
end
