--[[
    ConnectionHoseUtil

    Utilities for connection hoses

	@author: 		BayernGamers
	@date: 			05.12.2025
	@version:		1.0

	History:		v1.0 @05.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.
                        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, "ConnectionHoseUtil.lua")

ConnectionHoseUtil = {}

local function hasOutputTargetNodeForAttacherJoint(targetNodes, attacherJointIndex)
    for _, targetNode in pairs(targetNodes) do
        for _, jointIndex in pairs(targetNode.attacherJointIndices) do
            if jointIndex == attacherJointIndex then
                return true
            end
        end
    end

    return false
end

function ConnectionHoseUtil.getCustomHosesByInputAttacherJoint(vehicle, inputJointDescIndex)
    if vehicle == nil or vehicle.spec_connectionHoses == nil then
        return {}
    end

    local spec_connectionHoses = vehicle.spec_connectionHoses
    return spec_connectionHoses.customHosesByInputAttacher[inputJointDescIndex] == nil and {} or spec_connectionHoses.customHosesByInputAttacher[inputJointDescIndex]
end

function ConnectionHoseUtil.getCustomHoseTargetsByInputAttacherJoint(vehicle, inputJointDescIndex)
    if vehicle == nil or vehicle.spec_connectionHoses == nil then
        return {}
    end

    local spec_connectionHoses = vehicle.spec_connectionHoses
    return spec_connectionHoses.customHoseTargetsByInputAttacher[inputJointDescIndex] == nil and {} or spec_connectionHoses.customHoseTargetsByInputAttacher[inputJointDescIndex]
end

function ConnectionHoseUtil.getCustomHosesByAttacherJoint(vehicle, attacherJointDescIndex)
    if vehicle == nil or vehicle.spec_connectionHoses == nil then
        return {}
    end

    local spec_connectionHoses = vehicle.spec_connectionHoses
    return spec_connectionHoses.customHosesByAttacher[attacherJointDescIndex] == nil and {} or spec_connectionHoses.customHosesByAttacher[attacherJointDescIndex]
end

function ConnectionHoseUtil.getCustomHoseTargetsByAttacherJoint(vehicle, attacherJointDescIndex)
    if vehicle == nil or vehicle.spec_connectionHoses == nil then
        return {}
    end

    local spec_connectionHoses = vehicle.spec_connectionHoses
    return spec_connectionHoses.customHoseTargetsByAttacher[attacherJointDescIndex] == nil and {} or spec_connectionHoses.customHoseTargetsByAttacher[attacherJointDescIndex]
end

function ConnectionHoseUtil.getHasInputConnectionHoses(vehicle, inputAttacherJointIndex, checkSkipNodes)
    if checkSkipNodes ~= false then
        checkSkipNodes = true
    end

    if vehicle ~= nil and vehicle.spec_connectionHoses ~= nil and inputAttacherJointIndex ~= nil then
        if #vehicle.spec_connectionHoses.toolConnectorHoses > 0 then
            return true
        end

        local hoseNodes = vehicle:getConnectionHosesByInputAttacherJoint(inputAttacherJointIndex)
        if #hoseNodes > 0 then
            return true
        end

        local customHoseTargets = ConnectionHoseUtil.getCustomHoseTargetsByInputAttacherJoint(vehicle, inputAttacherJointIndex)
        if #customHoseTargets > 0 then
            return true
        end

        local customHoses = ConnectionHoseUtil.getCustomHosesByInputAttacherJoint(vehicle, inputAttacherJointIndex)
        if #customHoses > 0 then
            return true
        end

        if checkSkipNodes then
            for _, hoseSkipNode in pairs(vehicle.spec_connectionHoses.hoseSkipNodes) do
                if hoseSkipNode.inputAttacherJointIndex == inputAttacherJointIndex then
                    return true
                end
            end
        end
    end

    return false
end

function ConnectionHoseUtil.getHasElecticInputConnectionHoses(vehicle, inputAttacherJointIndex)
    if vehicle ~= nil and vehicle.spec_connectionHoses ~= nil and inputAttacherJointIndex ~= nil then
        local connectionHoses = vehicle:getConnectionHosesByInputAttacherJoint(inputAttacherJointIndex)

        for _, hose in pairs(connectionHoses) do
            if hose.type == "electric" then
                return true
            end
        end
    end

    return false
end

function ConnectionHoseUtil.getHasElectricOutputConnectionHoses(vehicle, attacherJointIndex)
    if vehicle ~= nil and vehicle.spec_connectionHoses ~= nil and attacherJointIndex ~= nil then
        local attacherJoint = vehicle:getAttacherJointByJointDescIndex(attacherJointIndex)
        local targetNodes = vehicle.spec_connectionHoses.targetNodesByType["electric"] or {}

        for _, targetNode in pairs(targetNodes) do
            for _, jointIndex in pairs(targetNode.attacherJointIndices) do
                if jointIndex == attacherJointIndex then
                    return true
                end
            end
        end
    end

    return false
end

function ConnectionHoseUtil.getHasHydraulicInputConnectionHoses(vehicle, inputAttacherJointIndex)
    if vehicle ~= nil and vehicle.spec_connectionHoses ~= nil and inputAttacherJointIndex ~= nil then
        local connectionHoses = vehicle:getConnectionHosesByInputAttacherJoint(inputAttacherJointIndex)

        for _, hose in pairs(connectionHoses) do
            if hose.type:find("hydraulic") then
                return true
            end
        end
    end

    return false
end

function ConnectionHoseUtil.getHasHydraulicOutputConnectionHoses(vehicle, attacherJointIndex)
    if vehicle ~= nil and vehicle.spec_connectionHoses ~= nil and attacherJointIndex ~= nil then
        local targetNodesByType = vehicle.spec_connectionHoses.targetNodesByType
        local targetNodesIn = targetNodesByType["hydraulicIn"] or {}
        local targetNodesOut = targetNodesByType["hydraulicOut"] or {}

        if hasOutputTargetNodeForAttacherJoint(targetNodesIn, attacherJointIndex) then
            return true
        end

        if hasOutputTargetNodeForAttacherJoint(targetNodesOut, attacherJointIndex) then
            return true
        end
    end

    return false
end

function ConnectionHoseUtil.getHasAirInputConnectionHoses(vehicle, inputAttacherJointIndex)
    if vehicle ~= nil and vehicle.spec_connectionHoses ~= nil and inputAttacherJointIndex ~= nil then
        local connectionHoses = vehicle:getConnectionHosesByInputAttacherJoint(inputAttacherJointIndex)

        for _, hose in pairs(connectionHoses) do
            if hose.type:find("air") then
                return true
            end
        end
    end

    return false
end

function ConnectionHoseUtil.getHasAirOutputConnectionHoses(vehicle, attacherJointIndex)
    if vehicle ~= nil and vehicle.spec_connectionHoses ~= nil and attacherJointIndex ~= nil then
        local targetNodesByType = vehicle.spec_connectionHoses.targetNodesByType
        local targetNodesAirRed = targetNodesByType["airDoubleRed"] or {}
        local targetNodesAirYellow = targetNodesByType["airDoubleYellow"] or {}

        if hasOutputTargetNodeForAttacherJoint(targetNodesAirRed, attacherJointIndex) then
            return true
        end

        if hasOutputTargetNodeForAttacherJoint(targetNodesAirYellow, attacherJointIndex) then
            return true
        end
    end

    return false
end

function ConnectionHoseUtil.getHasAttacherVehicleElecticOutputHoses(vehicle)
    local hasAttacherVehicleHoses = false

    if vehicle ~= nil and vehicle.getAttacherVehicle ~= nil then
        local attacherVehicle = vehicle:getAttacherVehicle()
        local implementIndex = attacherVehicle:getImplementIndexByObject(vehicle)
        local jointDescIndex = attacherVehicle:getAttacherJointIndexFromImplementIndex(implementIndex)
        hasAttacherVehicleHoses = ConnectionHoseUtil.getHasElectricOutputConnectionHoses(attacherVehicle, jointDescIndex)
    end

    return hasAttacherVehicleHoses
end

function ConnectionHoseUtil.getHasAttacherVehicleHydraulicOutputHoses(vehicle)
    local hasAttacherVehicleHoses = false

    if vehicle ~= nil and vehicle.getAttacherVehicle ~= nil then
        local attacherVehicle = vehicle:getAttacherVehicle()
        local implementIndex = attacherVehicle:getImplementIndexByObject(vehicle)
        local jointDescIndex = attacherVehicle:getAttacherJointIndexFromImplementIndex(implementIndex)
        hasAttacherVehicleHoses = ConnectionHoseUtil.getHasHydraulicOutputConnectionHoses(attacherVehicle, jointDescIndex)
    end

    return hasAttacherVehicleHoses
end

--[[
function ConnectionHoseUtil.getHasCustomHoseInputsByAttacherJoint(vehicle, inputAttacherJointIndex)
    if vehicle ~= nil and vehicle.spec_connectionHoses ~= nil and inputAttacherJointIndex ~= nil then
        local customHoseTargets = ConnectionHoseUtil.getCustomHoseTargetsByInputAttacherJoint(vehicle, inputAttacherJointIndex)
        if #customHoseTargets > 0 then
            return true
        end

        local customHoses = ConnectionHoseUtil.getCustomHosesByInputAttacherJoint(vehicle, inputAttacherJointIndex)
        if #customHoses > 0 then
            return true
        end
    end
end

function ConnectionHoseUtil.getHasCustomHoseOutputsByAttacherJoint(vehicle, attacherJointIndex)
    if vehicle ~= nil and vehicle.spec_connectionHoses ~= nil and attacherJointIndex ~= nil then
        local customHoseTargets = ConnectionHoseUtil.getCustomHoseTargetsByAttacherJoint(vehicle, attacherJointIndex)
        if #customHoseTargets > 0 then
            return true
        end

        local customHoses = ConnectionHoseUtil.getCustomHosesByAttacherjoint(vehicle, attacherJointIndex)
        if #customHoses > 0 then
            return true
        end
    end
end
]]

function ConnectionHoseUtil.getCompatibleCustomHoseTypes(vehicle, inputAttacherJointIndex)
    local compatibleConnectionTypes = {}

    if vehicle ~= nil and vehicle.spec_connectionHoses ~= nil and vehicle.getAttacherVehicle ~= nil and inputAttacherJointIndex ~= nil then
        local attacherVehicle = vehicle:getAttacherVehicle()

        if attacherVehicle ~= nil then
            local implementIndex = attacherVehicle:getImplementIndexByObject(vehicle)
            local attacherJointDescIndex = attacherVehicle:getAttacherJointIndexFromImplementIndex(implementIndex)

            local inputCustomHoseTargets = ConnectionHoseUtil.getCustomHoseTargetsByInputAttacherJoint(vehicle, inputAttacherJointIndex)
            local outputCustomHoses = ConnectionHoseUtil.getCustomHosesByAttacherJoint(attacherVehicle, attacherJointDescIndex)

            for _, inputHoseTarget in pairs(inputCustomHoseTargets) do
                for _, outputHose in pairs(outputCustomHoses) do
                    if inputHoseTarget.type == outputHose.type then
                        table.insert(compatibleConnectionTypes, inputHoseTarget.type)
                    end
                end
            end

            local inputCustomHoses = ConnectionHoseUtil.getCustomHosesByInputAttacherJoint(vehicle, inputAttacherJointIndex)
            local outputCustomHoseTargets = ConnectionHoseUtil.getCustomHoseTargetsByAttacherJoint(attacherVehicle, attacherJointDescIndex)

            for _, inputHose in pairs(inputCustomHoses) do
                for _, outputHoseTarget in pairs(outputCustomHoseTargets) do
                    if inputHose.type == outputHoseTarget.type then
                        table.insert(compatibleConnectionTypes, inputHose.type)
                    end
                end
            end
        end
    end

    return compatibleConnectionTypes
end

function ConnectionHoseUtil.getHasCompatibleCustomHoseTypes(vehicle, inputAttacherJointIndex)
    local compatibleConnectionTypes = ConnectionHoseUtil.getCompatibleCustomHoseTypes(vehicle, inputAttacherJointIndex)

    return #compatibleConnectionTypes > 0
end