--[[
    FrontloaderAttacherTypeConfig

    Adds the Frontloader Attacher Type Configuration to all vehicles.

	@author: 		BayernGamers
	@date: 			09.11.2025
	@version:		1.0

	History:		v1.0 @09.11.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.
]]
FrontloaderAttacherTypeConfig = {}
FrontloaderAttacherTypeConfig.SAVE_IDS = {
    MANUAL = "MANUAL",
    SEMI_AUTOMATIC = "SEMI_AUTOMATIC",
    AUTOMATIC = "AUTOMATIC"
}

function FrontloaderAttacherTypeConfig.getIsFrontloaderVehicle(xmlFile)

    if not xmlFile:hasProperty("vehicle.attacherJoints") then
        return false
    end

    local isFrontloaderVehicle = false
    local frontloaderAttacherJoints = {}

    if xmlFile:hasProperty("vehicle.attacherJoints") then
        xmlFile:iterate("vehicle.attacherJoints.attacherJoint", function(index, key)
            local jointTypeName = xmlFile:getValue(key .. "#jointType", nil)

            if jointTypeName ~= nil then
                local jointType = AttacherJoints.jointTypeNameToInt[jointTypeName]
                local isCustomFrontloaderJointType = g_attachImplementsManuallyManager.customFrontloaderJointTypeIndices[jointType] ~= nil

                if jointType == AttacherJoints.JOINTTYPE_FRONTLOADER or jointType == AttacherJoints.JOINTTYPE_TELEHANDLER or jointType == AttacherJoints.JOINTTYPE_WHEELLOADER or jointType == AttacherJoints.JOINTTYPE_SKIDSTEER or isCustomFrontloaderJointType then
                    isFrontloaderVehicle = true
                    table.insert(frontloaderAttacherJoints, index)
                end
            end
        end)
    end

    if xmlFile:hasProperty("vehicle.attacherJoints.attacherJointConfigurations") then
        xmlFile:iterate("vehicle.attacherJoints.attacherJointConfigurations.attacherJointConfiguration", function(xmlConfigIndex, configKey)
            xmlFile:iterate(configKey .. ".attacherJoint", function(index, key)
                local jointTypeName = xmlFile:getValue(key .. "#jointType", nil)

                if jointTypeName ~= nil then
                    local jointType = AttacherJoints.jointTypeNameToInt[jointTypeName]
                    local isCustomFrontloaderJointType = g_attachImplementsManuallyManager.customFrontloaderJointTypeIndices[jointType] ~= nil

                    if jointType == AttacherJoints.JOINTTYPE_FRONTLOADER or jointType == AttacherJoints.JOINTTYPE_TELEHANDLER or jointType == AttacherJoints.JOINTTYPE_WHEELLOADER or jointType == AttacherJoints.JOINTTYPE_SKIDSTEER or isCustomFrontloaderJointType then
                        isFrontloaderVehicle = true
                        table.insert(frontloaderAttacherJoints, index)
                    end
                end
            end)
        end)
    end

    return isFrontloaderVehicle, frontloaderAttacherJoints
end

function FrontloaderAttacherTypeConfig.getHasConnectionHoses(xmlFile, frontloaderAttacherJoints)
    local hasConnectionHoses = false

    if not xmlFile:hasProperty("vehicle.connectionHoses") then
        return false
    else
        xmlFile:iterate("vehicle.connectionHoses.target", function(index, key)
            local attacherJointIndices = xmlFile:getValue(key .. "#attacherJointIndices", nil, true)

            if attacherJointIndices ~= nil and #attacherJointIndices > 0 then
                for _, attacherJointIndex in ipairs(attacherJointIndices) do
                    for _, frontloaderAttacherJointIndex in ipairs(frontloaderAttacherJoints) do
                        if attacherJointIndex == frontloaderAttacherJointIndex then
                            hasConnectionHoses = true
                            return false
                        end
                    end
                end
            end
        end)
    end

    if xmlFile:hasProperty("vehicle.connectionHoses.connectionHoseConfigurations") then
        xmlFile:iterate("vehicle.connectionHoses.connectionHoseConfigurations.connectionHoseConfiguration", function(xmlConfigIndex, configKey)
            xmlFile:iterate(configKey .. ".target", function(index, key)
                local attacherJointIndices = xmlFile:getValue(key .. "#attacherJointIndices", nil, true)

                if attacherJointIndices ~= nil and #attacherJointIndices > 0 then
                    for _, attacherJointIndex in ipairs(attacherJointIndices) do
                        for _, frontloaderAttacherJointIndex in ipairs(frontloaderAttacherJoints) do
                            if attacherJointIndex == frontloaderAttacherJointIndex then
                                hasConnectionHoses = true
                                return false
                            end
                        end
                    end
                end
            end)
        end)
    end

    return hasConnectionHoses
end

function FrontloaderAttacherTypeConfig.getDefaultConfigurationId(xmlFile)
    if not xmlFile:hasProperty("vehicle.attachImplementsManually.defaultFrontloaderAttacherType") then
        return FrontloaderAttacherTypeConfig.SAVE_IDS.MANUAL
    end

    local defaultConfigIndex = xmlFile:getValue("vehicle.attachImplementsManually.defaultFrontloaderAttacherType#type", "MANUAL")

    local found = FrontloaderAttacherTypeConfig.SAVE_IDS[defaultConfigIndex] ~= nil

    if not found then
        return FrontloaderAttacherTypeConfig.SAVE_IDS.MANUAL
    end

    return defaultConfigIndex
end

function FrontloaderAttacherTypeConfig.getAllowSelection(xmlFile)
    if not xmlFile:hasProperty("vehicle.attachImplementsManually.defaultFrontloaderAttacherType") then
        return true
    end

    return xmlFile:getValue("vehicle.attachImplementsManually.defaultFrontloaderAttacherType#allowSelection", true)
end

function FrontloaderAttacherTypeConfig.getAvailableConfigurations(xmlFile)
    local availableConfigurations = {}

    if not xmlFile:hasProperty("vehicle.attachImplementsManually.defaultFrontloaderAttacherType") then
        availableConfigurations = { FrontloaderAttacherTypeConfig.SAVE_IDS.MANUAL, FrontloaderAttacherTypeConfig.SAVE_IDS.SEMI_AUTOMATIC, FrontloaderAttacherTypeConfig.SAVE_IDS.AUTOMATIC }
    end

    local configIndices = xmlFile:getValue("vehicle.attachImplementsManually.defaultFrontloaderAttacherType#allowedTypes", nil, true)

    if configIndices ~= nil and #configIndices > 0 then
        for _, configIndex in ipairs(configIndices) do
            if FrontloaderAttacherTypeConfig.SAVE_IDS[configIndex] ~= nil then
                table.insert(availableConfigurations, configIndex)
            end
        end
    end
    
    return availableConfigurations
end

function FrontloaderAttacherTypeConfig.getConfigurationsFromXML(configurationManager, superFunc, xmlFile, baseKey, configs, customEnv, isMod, storeItem)
    local configurations, defaultConfigIds = superFunc(configurationManager, xmlFile, baseKey, configs, customEnv, isMod, storeItem)
    local isFrontloaderVehicle, frontloaderAttacherJoints = FrontloaderAttacherTypeConfig.getIsFrontloaderVehicle(xmlFile)

    -- Overwrite propably user defined configurations as FrontloaderAttacherTypeConfig is not intended to support custom configs.
    if configurations ~= nil and configurations["frontloaderAttacherType"] ~= nil then
        configurations["frontloaderAttacherType"] = nil
    end

    if isFrontloaderVehicle then
        local hasConnectionHoses = FrontloaderAttacherTypeConfig.getHasConnectionHoses(xmlFile, frontloaderAttacherJoints)
        local defaultConfigId = FrontloaderAttacherTypeConfig.getDefaultConfigurationId(xmlFile)
        local allowSelection = FrontloaderAttacherTypeConfig.getAllowSelection(xmlFile)
        local availableConfigurations = FrontloaderAttacherTypeConfig.getAvailableConfigurations(xmlFile)

        configurations = configurations == nil and {} or configurations
        defaultConfigIds = defaultConfigIds == nil and {} or defaultConfigIds
        local frontloaderAttacherTypeConfigs = {}

        local frontloaderAttacherFullyManual = VehicleConfigurationItem.new("frontloaderAttacherType")
        frontloaderAttacherFullyManual.isDefault = defaultConfigId == FrontloaderAttacherTypeConfig.SAVE_IDS.MANUAL
        frontloaderAttacherFullyManual.name = g_i18n:getText("configuration_frontloaderAttacherType_manual")
        frontloaderAttacherFullyManual.index = 1
        frontloaderAttacherFullyManual.saveId = FrontloaderAttacherTypeConfig.SAVE_IDS.MANUAL
        frontloaderAttacherFullyManual.price = 0
        frontloaderAttacherFullyManual.isSelectable = (allowSelection and (#availableConfigurations == 0 or table.find(availableConfigurations, FrontloaderAttacherTypeConfig.SAVE_IDS.MANUAL))) or (not allowSelection and frontloaderAttacherFullyManual.isDefault)
        table.insert(frontloaderAttacherTypeConfigs, frontloaderAttacherFullyManual)

        local frontloaderAttacherSemiAutomatic = VehicleConfigurationItem.new("frontloaderAttacherType")
        frontloaderAttacherSemiAutomatic.isDefault = defaultConfigId == FrontloaderAttacherTypeConfig.SAVE_IDS.SEMI_AUTOMATIC
        frontloaderAttacherSemiAutomatic.name = g_i18n:getText("configuration_frontloaderAttacherType_semiAutomatic")
        frontloaderAttacherSemiAutomatic.index = 2
        frontloaderAttacherSemiAutomatic.saveId = FrontloaderAttacherTypeConfig.SAVE_IDS.SEMI_AUTOMATIC
        frontloaderAttacherSemiAutomatic.price = 250
        frontloaderAttacherSemiAutomatic.isSelectable = (allowSelection and (#availableConfigurations == 0 or table.find(availableConfigurations, FrontloaderAttacherTypeConfig.SAVE_IDS.SEMI_AUTOMATIC))) or (not allowSelection and frontloaderAttacherSemiAutomatic.isDefault)
        table.insert(frontloaderAttacherTypeConfigs, frontloaderAttacherSemiAutomatic)

        local frontloaderAttacherAutomatic = VehicleConfigurationItem.new("frontloaderAttacherType")
        frontloaderAttacherAutomatic.isDefault = defaultConfigId == FrontloaderAttacherTypeConfig.SAVE_IDS.AUTOMATIC
        frontloaderAttacherAutomatic.name = g_i18n:getText("configuration_frontloaderAttacherType_automatic")
        frontloaderAttacherAutomatic.index = 3
        frontloaderAttacherAutomatic.saveId = FrontloaderAttacherTypeConfig.SAVE_IDS.AUTOMATIC
        frontloaderAttacherAutomatic.price = 500
        frontloaderAttacherAutomatic.isSelectable = hasConnectionHoses and ((allowSelection and (#availableConfigurations == 0 or table.find(availableConfigurations, FrontloaderAttacherTypeConfig.SAVE_IDS.AUTOMATIC))) or (not allowSelection and frontloaderAttacherAutomatic.isDefault))
        table.insert(frontloaderAttacherTypeConfigs, frontloaderAttacherAutomatic)

        defaultConfigIds.frontloaderAttacherType = ConfigurationUtil.getDefaultConfigIdFromItems(frontloaderAttacherTypeConfigs)
        configurations.frontloaderAttacherType = frontloaderAttacherTypeConfigs
    end

    return configurations, defaultConfigIds
end

ConfigurationUtil.getConfigurationsFromXML = Utils.overwrittenFunction(ConfigurationUtil.getConfigurationsFromXML, FrontloaderAttacherTypeConfig.getConfigurationsFromXML)