--[[
    AttachableTurnOnVehicleExtension

    Reworks the attachable's behavior to be aware of attach implements manually.

	@author: 		BayernGamers
	@date: 			07.06.2025
	@version:		1.0

	History:		v1.0 @07.06.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.
]]
source(Utils.getFilename("scripts/utils/Logger.lua", g_currentModDirectory))
source(Utils.getFilename("scripts/utils/ConnectionHoseUtil.lua", g_currentModDirectory))
source(Utils.getFilename("scripts/utils/PowerTakeOffUtil.lua", g_currentModDirectory))

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

AttachableTurnOnVehicleExtension = {}
AttachableTurnOnVehicleExtension.MOD_DIRECTORY = g_currentModDirectory
AttachableTurnOnVehicleExtension.MOD_NAME = g_currentModName

function AttachableTurnOnVehicleExtension.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Attachable, specializations) and SpecializationUtil.hasSpecialization(TurnOnVehicle, specializations)
end

function AttachableTurnOnVehicleExtension.registerEventListeners(vehicleType)
    SpecializationUtil.registerEventListener(vehicleType, "onPreLoad", AttachableTurnOnVehicleExtension)
    SpecializationUtil.registerEventListener(vehicleType, "onLoad", AttachableTurnOnVehicleExtension)
    SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", AttachableTurnOnVehicleExtension)
end

function AttachableTurnOnVehicleExtension.registerOverwrittenFunctions(vehicleType)
    SpecializationUtil.registerOverwrittenFunction(vehicleType, "getTurnedOnNotAllowedWarning", AttachableTurnOnVehicleExtension.getTurnedOnNotAllowedWarning)
    SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeTurnedOn", AttachableTurnOnVehicleExtension.getCanBeTurnedOn)
end

function AttachableTurnOnVehicleExtension:onPreLoad(savegame)
    self.spec_attachableTurnOnVehicleExtension = {}
end

function AttachableTurnOnVehicleExtension:onLoad(savegame)
    local spec = self.spec_attachableTurnOnVehicleExtension

    --spec.hasPTO = false
    --spec.hasConnectionHoses = false
    spec.modSettingsManager = AttachImplementsManuallySettingsManager.getInstance()
end

function AttachableTurnOnVehicleExtension:onPostLoad(savegame)
    local spec = self.spec_attachableTurnOnVehicleExtension

    --[[
    if SpecializationUtil.hasSpecialization(PowerTakeOffs, self.specializations) then
        local spec_powerTakeOffs = self.spec_powerTakeOffs

        spec.hasPTO = #spec_powerTakeOffs.inputPowerTakeOffs > 0

        if self.getAttacherVehicle ~= nil then
            local attacherVehicle = self:getAttacherVehicle()

            if attacherVehicle ~= nil and attacherVehicle.spec_powerTakeOffs ~= nil then
                spec.hasPTO = spec.hasPTO and #attacherVehicle.spec_powerTakeOffs.outputPowerTakeOffs > 0
            end
        end
    end
    ]]

    --[[
    if SpecializationUtil.hasSpecialization(ConnectionHoses, self.specializations) then
        local spec_connectionHoses = self.spec_connectionHoses

        spec.hasConnectionHoses = #spec_connectionHoses.toolConnectorHoses > 0 or #spec_connectionHoses.hoseNodes > 0 or #spec_connectionHoses.customHoseTargets > 0 or #spec_connectionHoses.customHoses > 0 or #spec_connectionHoses.hoseSkipNodes > 0
    end
    ]]
end

function AttachableTurnOnVehicleExtension:getTurnedOnNotAllowedWarning(superFunc)
    local spec = self.spec_attachableTurnOnVehicleExtension
    local spec_turnOnVehicle = self.spec_turnOnVehicle

    if spec_turnOnVehicle ~= nil and spec_turnOnVehicle.turnedOnByAttacherVehicle then
        local attacherVehicle = self:getAttacherVehicle()

        if attacherVehicle ~= nil then
            local implementIndex = attacherVehicle:getImplementIndexByObject(self)
            local jointDescIndex = attacherVehicle:getAttacherJointIndexFromImplementIndex(implementIndex)
            local inputAttacherJointIndex = self:getActiveInputAttacherJointDescIndex()

            local hasPTO = PowerTakeOffUtil.getHasInputPTO(self, inputAttacherJointIndex) and PowerTakeOffUtil.getHasOutputPTO(attacherVehicle, jointDescIndex)

            if hasPTO then
                local attacherVehicleHasPTO = false


                if attacherVehicle.spec_powerTakeOffs ~= nil then
                    local outputPowerTakeOffs = attacherVehicle:getOutputPowerTakeOffsByJointDescIndex(jointDescIndex)
                    
                    if #outputPowerTakeOffs > 0 then
                        attacherVehicleHasPTO = true
                    end
                end

                if attacherVehicleHasPTO and jointDescIndex ~= nil and attacherVehicle.spec_attachPowerTakeOffsManually ~= nil and attacherVehicle.spec_attachPowerTakeOffsManually.attachedPTOs ~= nil then
                    if attacherVehicle.spec_attachPowerTakeOffsManually.attachedPTOs[jointDescIndex] == nil then
                        return g_i18n:getText("warning_attachPTOFirst")
                    end
                end
            end
            
            --local hasConnectionHoses = ConnectionHoseUtil.getHasInputConnectionHoses(self, inputAttacherJointIndex)
            --local hasConnectionHoses = ConnectionHoseUtil.getHasHydraulicInputConnectionHoses(self, inputAttacherJointIndex) and ConnectionHoseUtil.getHasHydraulicOutputConnectionHoses(attacherVehicle, jointDescIndex)
            local hasConnectionHoses = (ConnectionHoseUtil.getHasHydraulicInputConnectionHoses(self, inputAttacherJointIndex) and ConnectionHoseUtil.getHasHydraulicOutputConnectionHoses(attacherVehicle, jointDescIndex)) or 
                ConnectionHoseUtil.getHasCompatibleCustomHoseTypes(self, inputAttacherJointIndex)
                
            if hasConnectionHoses then
                --[[
                local implementIndex = attacherVehicle:getImplementIndexByObject(self)
                local jointDescIndex = attacherVehicle:getAttacherJointIndexFromImplementIndex(implementIndex)
                local attacherVehicleHasHoses = false

                if attacherVehicle.spec_connectionHoses ~= nil then
                    for _, hoseTarget in pairs(attacherVehicle.spec_connectionHoses.targetNodes) do
                        for _, attacherJointIndex in pairs(hoseTarget.attacherJointIndices) do
                            if attacherJointIndex == jointDescIndex then
                                attacherVehicleHasHoses = true
                                break
                            end
                        end
                    end
                end
                ]]

                if --[[attacherVehicleHasHoses and]] jointDescIndex ~= nil and attacherVehicle.spec_attachConnectionHosesManually ~= nil and attacherVehicle.spec_attachConnectionHosesManually.attachedHoses ~= nil then
                    local isSkipNodeConnected = AttachConnectionHosesManually.getHasSkipNodeConnection(self)

                    if attacherVehicle.spec_attachConnectionHosesManually.attachedHoses[jointDescIndex] == nil and not isSkipNodeConnected then
                        return g_i18n:getText("warning_attachHosesFirst")
                    end
                end
            end
        end
    end

    return superFunc(self)
end

function AttachableTurnOnVehicleExtension:getCanBeTurnedOn(superFunc, actionVehicle)
    local spec = self.spec_attachableTurnOnVehicleExtension
    local spec_turnOnVehicle = self.spec_turnOnVehicle

    if spec_turnOnVehicle ~= nil and spec_turnOnVehicle.turnedOnByAttacherVehicle then
        local attacherVehicle = self:getAttacherVehicle()
        if attacherVehicle ~= nil then
            local implementIndex = attacherVehicle:getImplementIndexByObject(self)
            local jointDescIndex = attacherVehicle:getAttacherJointIndexFromImplementIndex(implementIndex)
            local inputAttacherJointIndex = self:getActiveInputAttacherJointDescIndex()
            local hasPTO = PowerTakeOffUtil.getHasInputPTO(self, inputAttacherJointIndex) and PowerTakeOffUtil.getHasOutputPTO(attacherVehicle, jointDescIndex)

            if hasPTO then
                local attacherVehicleHasPTO = false

                if attacherVehicle.spec_powerTakeOffs ~= nil then
                    local outputPowerTakeOffs = attacherVehicle:getOutputPowerTakeOffsByJointDescIndex(jointDescIndex)
                    
                    if #outputPowerTakeOffs > 0 then
                        attacherVehicleHasPTO = true
                    end
                end

                if attacherVehicleHasPTO and jointDescIndex ~= nil and attacherVehicle.spec_attachPowerTakeOffsManually ~= nil and attacherVehicle.spec_attachPowerTakeOffsManually.attachedPTOs ~= nil then
                    if attacherVehicle.spec_attachPowerTakeOffsManually.attachedPTOs[jointDescIndex] == nil then
                        log:printDevInfo("PTO not attached, cannot turn on implement", Logger.DEBUG_LEVELS.HIGH)
                        return false
                    end
                end
            end

            --local hasConnectionHoses = ConnectionHoseUtil.getHasInputConnectionHoses(self, inputAttacherJointIndex)
            --local hasConnectionHoses = ConnectionHoseUtil.getHasHydraulicInputConnectionHoses(self, inputAttacherJointIndex) and ConnectionHoseUtil.getHasHydraulicOutputConnectionHoses(attacherVehicle, jointDescIndex)
            local hasConnectionHoses = (ConnectionHoseUtil.getHasHydraulicInputConnectionHoses(self, inputAttacherJointIndex) and ConnectionHoseUtil.getHasHydraulicOutputConnectionHoses(attacherVehicle, jointDescIndex)) or 
                ConnectionHoseUtil.getHasCompatibleCustomHoseTypes(self, inputAttacherJointIndex)
                
            if hasConnectionHoses then
                --local implementIndex = attacherVehicle:getImplementIndexByObject(self)
                --local jointDescIndex = attacherVehicle:getAttacherJointIndexFromImplementIndex(implementIndex)

                --[[
                local attacherVehicleHasHoses = false

                if attacherVehicle.spec_connectionHoses ~= nil then
                    for _, hoseTarget in pairs(attacherVehicle.spec_connectionHoses.targetNodes) do
                        for _, attacherJointIndex in pairs(hoseTarget.attacherJointIndices) do
                            if attacherJointIndex == jointDescIndex then
                                attacherVehicleHasHoses = true
                                break
                            end
                        end
                    end
                end
                ]]

                if --[[attacherVehicleHasHoses and]] jointDescIndex ~= nil and attacherVehicle.spec_attachConnectionHosesManually ~= nil and attacherVehicle.spec_attachConnectionHosesManually.attachedHoses ~= nil then
                    if attacherVehicle.spec_attachConnectionHosesManually.attachedHoses[jointDescIndex] == nil then
                        log:printDevInfo("Hoses not attached, cannot turn on implement", Logger.DEBUG_LEVELS.HIGH)
                        return false
                    end
                end
            end
        end
    end

    return superFunc(self, actionVehicle)
end