--[[
    ExtendedAttachable

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

	@author: 		BayernGamers
	@date: 			01.06.2025
	@version:		1.0

	History:		v1.0 @01.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/AttachImplementsManuallySettingsManager.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, "ExtendedAttachable.lua")

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

function ExtendedAttachable.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Attachable, specializations) and SpecializationUtil.hasSpecialization(AttachImplementsManually, specializations)
end

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

function ExtendedAttachable.registerOverwrittenFunctions(vehicleType)
    SpecializationUtil.registerOverwrittenFunction(vehicleType, "isDetachAllowed", ExtendedAttachable.isDetachAllowed)
end

function ExtendedAttachable:onPreLoad(savegame)
    self.spec_extendedAttachable = {}
end

function ExtendedAttachable:onLoad(savegame)
    local spec = self.spec_extendedAttachable

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

function ExtendedAttachable:onPostLoad(savegame)
    local spec = self.spec_extendedAttachable

    --[[
    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 ExtendedAttachable:isDetachAllowed(superFunc)
    local spec = self.spec_extendedAttachable
    local spec_attachable = self.spec_attachable
    local attacherVehicle = self:getAttacherVehicle()

    if spec.modSettingsManager:getEnableAttachImplementsManually() and not AttachImplementsManually.getIsManualAttachForNexatDisabled(self) then
        
        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 implementIndex = attacherVehicle:getImplementIndexByObject(self)
                local jointDescIndex = attacherVehicle:getAttacherJointIndexFromImplementIndex(implementIndex)

                local info = {
                    attacherVehicle = attacherVehicle,
                    attachable = self,
                    attacherVehicleJointDescIndex = jointDescIndex,
                    attachableJointDescIndex = self.spec_attachable.inputAttacherJointDescIndex
                }

                if (jointDescIndex ~= nil and attacherVehicle.spec_attachPowerTakeOffsManually ~= nil and attacherVehicle.spec_attachPowerTakeOffsManually.attachedPTOs ~= nil)
                    and not AttacherJointUtil.getAttachPTOIfAttachedFromInside(info)
                then
                    if attacherVehicle.spec_attachPowerTakeOffsManually.attachedPTOs[jointDescIndex] ~= nil then
                        return false, g_i18n:getText("warning_detachPTOFirst"), true
                    end
                end
            end
            
            local hasConnectionHoses = ConnectionHoseUtil.getHasInputConnectionHoses(self, inputAttacherJointIndex)
            
            if hasConnectionHoses then
                local implementIndex = attacherVehicle:getImplementIndexByObject(self)
                local jointDescIndex = attacherVehicle:getAttacherJointIndexFromImplementIndex(implementIndex)

                if jointDescIndex ~= nil and attacherVehicle.spec_attachConnectionHosesManually ~= nil and attacherVehicle.spec_attachConnectionHosesManually.attachedHoses ~= nil then
                    local hasSkipNodeConnection = AttachConnectionHosesManually.getHasSkipNodeConnection(self)

                    local info = {
                        attacherVehicle = attacherVehicle,
                        attachable = self,
                        attacherVehicleJointDescIndex = jointDescIndex,
                        attachableJointDescIndex = self.spec_attachable.inputAttacherJointDescIndex
                    }

                    if (attacherVehicle.spec_attachConnectionHosesManually.attachedHoses[jointDescIndex] ~= nil or hasSkipNodeConnection)
                        and not AttacherJointUtil.getUsesFrontloaderToolAttacher(info, true) and not AttacherJointUtil.getAttachHosesIfAttachedFromInside(info) and not AttacherJointUtil.getUsesHookLiftAttacher(info) and not AttacherJointUtil.getUsesBigBagAttacher(info)
                    then
                        return false, g_i18n:getText("warning_detachHosesFirst"), true
                    end
                end
            end
        end
    end

    return superFunc(self)
end