-- Copyright ©2024-2025 by Todd Hundersmarck (ThundR) 
-- All Rights Reserved

--[[

Unauthorized use and/or distribution of this work entitles myself, the author, to unlimited free and unrestricted use, access, and distribution of any works related to the unauthorized user and/or distributor.

--]]

local thModName = g_thPFConfig.coreData.mod.name
THVSpec_XTSprayTypes = {}
THVSpec_XTSprayTypes.CLASS_NAME = "THVSpec_XTSprayTypes"
THVSpec_XTSprayTypes.SPEC_NAME = "thXTSprayTypes"
THVSpec_XTSprayTypes.SPEC_KEY = string.format("spec_%s.%s", thModName, THVSpec_XTSprayTypes.SPEC_NAME)
THVSpec_XTSprayTypes.DEBUG_UPDATE_TIME = 100
local debugFlagId = THUtils.createDebugFlagId(THVSpec_XTSprayTypes.CLASS_NAME)
local isScriptInitialized = false
local function getSpecTable(parent)
    return THUtils.call(function()
        if parent ~= nil then
            return parent[THVSpec_XTSprayTypes.SPEC_KEY]
        end
    end)
end
THVSpec_XTSprayTypes.getSpecTable = getSpecTable
function THVSpec_XTSprayTypes.initScript()
    if not isScriptInitialized then
        local pfData = g_thPFConfig.precisionFarming
        if pfData.isFound then
            local pfModEnv = pfData.mod.environment
            local ExtendedSprayer = pfModEnv.ExtendedSprayer
            THUtils.overwriteFunction(ExtendedSprayer, "onChangedFillType", false, true, nil, THVSpec_XTSprayTypes.gOverwrite_onChangedFillType)
            THUtils.overwriteFunction(ExtendedSprayer, "onEndWorkAreaProcessing", false, true, nil, THVSpec_XTSprayTypes.gOverwrite_onEndWorkAreaProcessing)
        end
        isScriptInitialized = true
    end
    return true
end
function THVSpec_XTSprayTypes.prerequisitesPresent(specializations)
    if SpecializationUtil.hasSpecialization(FillUnit, specializations)
        or SpecializationUtil.hasSpecialization(Sprayer, specializations)
    then
        return true
    end
    return false
end
function THVSpec_XTSprayTypes.registerEventListeners(vehicleType)
    local specializations = vehicleType.specializations
    THUtils.pcall(function()
        if SpecializationUtil.hasSpecialization(Sprayer, specializations) then
            SpecializationUtil.registerEventListener(vehicleType, "onPreLoad", THVSpec_XTSprayTypes)
            SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", THVSpec_XTSprayTypes)
        end
    end)
end
function THVSpec_XTSprayTypes.registerOverwrittenFunctions(vehicleType)
    local specializations = vehicleType.specializations
    THUtils.pcall(function()
        if SpecializationUtil.hasSpecialization(FillUnit, specializations) then
            SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadFillUnitFromXML", THVSpec_XTSprayTypes.sInj_loadFillUnitFromXML)
        end
        if SpecializationUtil.hasSpecialization(Sprayer, specializations) then
            SpecializationUtil.registerOverwrittenFunction(vehicleType, "getFillUnitAllowsFillType", THVSpec_XTSprayTypes.sInj_getFillUnitAllowsFillType)
            SpecializationUtil.registerOverwrittenFunction(vehicleType, "getSprayerUsage", THVSpec_XTSprayTypes.sInj_getSprayerUsage)
            SpecializationUtil.registerOverwrittenFunction(vehicleType, "getExternalFill", THVSpec_XTSprayTypes.sInj_getExternalFill)
            SpecializationUtil.registerOverwrittenFunction(vehicleType, "updateExtendedSprayerNozzleEffectState", THVSpec_XTSprayTypes.sInj_updateExtendedSprayerNozzleEffectState)
        end
        if SpecializationUtil.hasSpecialization(SowingMachine, specializations) then
            SpecializationUtil.registerOverwrittenFunction(vehicleType, "processSowingMachineArea", THVSpec_XTSprayTypes.sInj_processSowingMachineArea)
        end
        local pfData = g_thPFConfig.precisionFarming
        if pfData.isFound then
            local pfModEnv = pfData.mod.environment
            local ExtendedSprayer = pfModEnv.ExtendedSprayer
            if SpecializationUtil.hasSpecialization(ExtendedSprayer, specializations) then
                SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCurrentSprayerMode", THVSpec_XTSprayTypes.sInj_getCurrentSprayerMode)
            end
        end
    end)
end
function THVSpec_XTSprayTypes.onPreLoad(self)
    THUtils.pcall(function()
        local specTable = getSpecTable(self)
        specTable.sprayerTypeFlags = {
            default = {
                isFertilizerSprayer = false,
                isSlurryTanker = false,
                isManureSpreader = false
            },
            previous = {}
        }
        specTable.pfSprayerTypeFlags = {
            default = {
                isSolidFertilizerSprayer = false,
                isLiquidFertilizerSprayer = false,
                isManureSpreader = false,
                isSlurryTanker = false
            },
            previous = {}
        }
        specTable.allowedSprayTypeGroups = {}
        specTable.isSolidSprayer = false
        specTable.isLiquidSprayer = false
        specTable.isSprayerTypeInitialized = false
    end)
end
function THVSpec_XTSprayTypes.onPostLoad(self)
    THUtils.pcall(function()
        local pfData = g_thPFConfig.precisionFarming
        local specTable = getSpecTable(self)
        local sprayerSpec = self.spec_sprayer
        if sprayerSpec ~= nil then
            for sprayerTypeFlagKey in pairs(specTable.sprayerTypeFlags.default) do
                local isActive = sprayerSpec[sprayerTypeFlagKey]
                if type(isActive) ~= THValueType.BOOLEAN then
                    if THUtils.getIsDebugEnabled() then
                        THUtils.objectErrorMsg(self, nil, "Missing/invalid sprayer specialization flag: %s", sprayerTypeFlagKey)
                    end
                else
                    specTable.sprayerTypeFlags.default[sprayerTypeFlagKey] = isActive
                end
            end
            if pfData.isFound then
                local pfModEnv = pfData.mod.environment
                local ExtendedSprayer = pfModEnv.ExtendedSprayer
                local pfExtSprayerSpec = self[ExtendedSprayer.SPEC_TABLE_NAME]
                if pfExtSprayerSpec ~= nil then
                    specTable.pfExtendedSprayer = ExtendedSprayer
                    specTable.pfExtSprayerSpec = pfExtSprayerSpec
                    for sprayerTypeFlagKey in pairs(specTable.pfSprayerTypeFlags.default) do
                        local isActive = pfExtSprayerSpec[sprayerTypeFlagKey]
                        if type(isActive) ~= THValueType.BOOLEAN then
                            if THUtils.getIsDebugEnabled() then
                                THUtils.objectErrorMsg(self, nil, "Missing/invalid extended sprayer specialization flag: %s [%s]", sprayerTypeFlagKey, isActive)
                            end
                        else
                            specTable.pfSprayerTypeFlags.default[sprayerTypeFlagKey] = isActive
                        end
                    end
                end
            end
            if THUtils.getIsDebugEnabled() then
                THUtils.objectDisplayMsg(self, "XTSprayTypes information:")
                THUtils.printTableValues(specTable, 2)
            end
        end
    end)
end
function THVSpec_XTSprayTypes.getSprayerFillType(self)
    local specTable = getSpecTable(self)
    local sprayerSpec = self.spec_sprayer
    local pfExtSprayerSpec = specTable.pfExtSprayerSpec
    if pfExtSprayerSpec ~= nil then
        local sourceVehicle, sourceFillUnitIndex = specTable.pfExtendedSprayer.getFillTypeSourceVehicle(self)
        if sourceVehicle ~= nil and sourceFillUnitIndex ~= nil then
            return sourceVehicle:getFillUnitFillType(sourceFillUnitIndex), sourceFillUnitIndex, sourceVehicle
        end
    end
    if sprayerSpec ~= nil then
        local sprayerFillUnitIndex = self:getSprayerFillUnitIndex()
        if sprayerFillUnitIndex ~= nil then
            local fillUnitFillLevel = self:getFillUnitFillLevel(sprayerFillUnitIndex)
            local fillUnitFillType = self:getFillUnitFillType(sprayerFillUnitIndex)
            if fillUnitFillLevel ~= nil and fillUnitFillLevel > 0
                and fillUnitFillType ~= nil
            then
                return fillUnitFillType, sprayerFillUnitIndex, self
            end
        end
        if sprayerSpec.supportedSprayTypes ~= nil then
            for supportedIndex = 1, #sprayerSpec.supportedSprayTypes do
                local sprayTypeIndex = sprayerSpec.supportedSprayTypes[supportedIndex]
                local fillTypeSources = sprayerSpec.fillTypeSources[sprayTypeIndex]
                if fillTypeSources ~= nil then
                    for sourceIndex = 1, #fillTypeSources do
                        local sourceData = fillTypeSources[sourceIndex]
                        local sourceVehicle = sourceData.vehicle
                        if sourceVehicle ~= nil and sourceData.fillUnitIndex ~= nil
                            and sourceVehicle.getFillUnitFillLevel ~= nil
                            and sourceVehicle.getFillUnitFillType ~= nil
                        then
                            local fillUnitFillLevel = sourceVehicle:getFillUnitFillLevel(sourceData.fillUnitIndex)
                            local fillUnitFillType = sourceVehicle:getFillUnitFillType(sourceData.fillUnitIndex)
                            if fillUnitFillLevel ~= nil and fillUnitFillLevel > 0
                                and fillUnitFillType ~= nil
                            then
                                return fillUnitFillType, sourceData.fillUnitIndex, sourceVehicle
                            end
                        end
                    end
                end
            end
        end
        return FillType.UNKNOWN, sprayerFillUnitIndex, self
    end
end
function THVSpec_XTSprayTypes.setCurrentSprayerType(self, fillType, altDebugFlagId, altDebugLevel)
    altDebugFlagId = altDebugFlagId or debugFlagId
    local specTable = getSpecTable(self)
    local sprayerSpec = self.spec_sprayer
    local pfExtSprayerSpec = specTable.pfExtSprayerSpec
    local xtSprayTypeData = g_thSprayTypes:getExtendedSprayTypeByFillType(fillType)
    if xtSprayTypeData ~= nil then
        local isDebugEnabled = THUtils.getIsDebugEnabled(altDebugFlagId, altDebugLevel)
        if sprayerSpec ~= nil then
            for flagKey in pairs(specTable.sprayerTypeFlags.default) do
                specTable.sprayerTypeFlags.previous[flagKey] = sprayerSpec[flagKey]
                sprayerSpec[flagKey] = false
            end
        end
        if pfExtSprayerSpec ~= nil then
            for flagKey in pairs(specTable.pfSprayerTypeFlags.default) do
                specTable.pfSprayerTypeFlags.previous[flagKey] = pfExtSprayerSpec[flagKey]
                pfExtSprayerSpec[flagKey] = false
            end
        end
        if xtSprayTypeData.groupIndex == THSprayTypes.SPRAY_TYPE_GROUP.FERTILIZER
            or xtSprayTypeData.groupIndex == THSprayTypes.SPRAY_TYPE_GROUP.LIME
        then
            if sprayerSpec ~= nil then
                sprayerSpec.isFertilizerSprayer = true
            end
            if pfExtSprayerSpec ~= nil then
                if xtSprayTypeData.subTypeIndex == THSprayTypes.SPRAY_SUB_TYPE.LIQUID then
                    pfExtSprayerSpec.isLiquidFertilizerSprayer = true
                else
                    pfExtSprayerSpec.isSolidFertilizerSprayer = true
                end
            end
        elseif xtSprayTypeData.groupIndex == THSprayTypes.SPRAY_TYPE_GROUP.MANURE
            or xtSprayTypeData.groupIndex == THSprayTypes.SPRAY_TYPE_GROUP.DIGESTATE
        then
            if sprayerSpec ~= nil then
                if xtSprayTypeData.subTypeIndex == THSprayTypes.SPRAY_SUB_TYPE.LIQUID then
                    sprayerSpec.isSlurryTanker = true
                else
                    sprayerSpec.isManureSpreader = true
                end
            end
            if pfExtSprayerSpec ~= nil then
                if xtSprayTypeData.subTypeIndex == THSprayTypes.SPRAY_SUB_TYPE.LIQUID then
                    pfExtSprayerSpec.isSlurryTanker = true
                else
                    pfExtSprayerSpec.isManureSpreader = true
                end
            end
        end
        if isDebugEnabled then
            if sprayerSpec ~= nil then
                THUtils.objectDisplayMsg(self, "Sprayer: updated type flags:")
                for flagKey, isActive in pairs(specTable.sprayerTypeFlags.default) do
                    THUtils.displayMsg("- %s: %s > %s", flagKey, isActive, sprayerSpec[flagKey])
                end
                printCallstack()
            end
            if pfExtSprayerSpec ~= nil then
                THUtils.objectDisplayMsg(self, "ExtendedSprayer: updated type flags:")
                for flagKey, isActive in pairs(specTable.pfSprayerTypeFlags.default) do
                    THUtils.displayMsg("- %s: %s > %s", flagKey, isActive, pfExtSprayerSpec[flagKey])
                end
                printCallstack()
            end
        end
    else
        THVSpec_XTSprayTypes.resetSprayerTypes(self, altDebugFlagId, altDebugLevel)
    end
end
function THVSpec_XTSprayTypes.resetSprayerTypes(self, altDebugFlagId, altDebugLevel)
    altDebugFlagId = altDebugFlagId or debugFlagId
    local specTable = getSpecTable(self)
    local sprayerSpec = self.spec_sprayer
    local pfExtSprayerSpec = specTable.pfExtSprayerSpec
    local isSprayerReset, isExtendedSprayerReset = false, false
    local isDebugEnabled = THUtils.getIsDebugEnabled(altDebugFlagId, altDebugLevel)
    if sprayerSpec ~= nil then
        for flagKey, isActive in pairs(specTable.sprayerTypeFlags.default) do
            local lastIsActive = sprayerSpec[flagKey]
            local prevIsActive = specTable.sprayerTypeFlags.previous[flagKey]
            if prevIsActive ~= nil then
                sprayerSpec[flagKey] = prevIsActive
                specTable.sprayerTypeFlags.previous[flagKey] = nil
            else
                sprayerSpec[flagKey] = isActive
            end
            if sprayerSpec[flagKey] ~= lastIsActive then
                if not isSprayerReset then
                    if isDebugEnabled then
                        THUtils.objectDisplayMsg(self, "Sprayer: resetting type flags:")
                    end
                    isSprayerReset = true
                end
                if isDebugEnabled then
                    THUtils.displayMsg("- %s: %s > %s", flagKey, lastIsActive, sprayerSpec[flagKey])
                end
            end
        end
    end
    if pfExtSprayerSpec ~= nil then
        for flagKey, isActive in pairs(specTable.pfSprayerTypeFlags.default) do
            local lastIsActive = pfExtSprayerSpec[flagKey]
            local prevIsActive = specTable.pfSprayerTypeFlags.previous[flagKey]
            if prevIsActive ~= nil then
                pfExtSprayerSpec[flagKey] = prevIsActive
                specTable.pfSprayerTypeFlags.previous[flagKey] = nil
            else
                pfExtSprayerSpec[flagKey] = isActive
            end
            if pfExtSprayerSpec[flagKey] ~= lastIsActive then
                if not isExtendedSprayerReset then
                    if isDebugEnabled then
                        THUtils.objectDisplayMsg(self, "ExtendedSprayer: resetting type flags:")
                    end
                    isExtendedSprayerReset = true
                end
                if isDebugEnabled then
                    THUtils.displayMsg("- %s: %s > %s", flagKey, lastIsActive, pfExtSprayerSpec[flagKey])
                end
            end
        end
    end
    if isDebugEnabled and (isSprayerReset or isExtendedSprayerReset) then
        printCallstack()
    end
end
function THVSpec_XTSprayTypes.mapExtendedSprayTypeConstants(_, fillTypeId, mapSprayType, mapFillType, altDebugFlagId, altDebugLevel)
    local xtSprayTypeData = g_thSprayTypes:getExtendedSprayTypeByFillType(fillTypeId)
    if xtSprayTypeData ~= nil then
        local isSprayTypeMapped, isFillTypeMapped = xtSprayTypeData:activateMapping(mapSprayType, mapFillType, altDebugFlagId, altDebugLevel)
        return xtSprayTypeData, isSprayTypeMapped, isFillTypeMapped
    end
    return nil, false, false
end
function THVSpec_XTSprayTypes.sInj_loadFillUnitFromXML(self, superFunc, xmlFile, xmlKey, ...)
    THUtils.pcall(function()
        local wrappedXML = THUtils.wrapXMLFile(xmlFile)
        if wrappedXML ~= nil then
            local fillTypeNames = wrappedXML:getString(xmlKey .. "#fillTypes")
            local fillTypeCategories = wrappedXML:getString(xmlKey .. "#fillTypeCategories")
            if (fillTypeNames ~= nil and fillTypeNames ~= "")
                or (fillTypeCategories ~= nil and fillTypeCategories ~= "")
            then
                local newFillTypeNames = g_thSprayTypes:addExtendedSprayTypesToFillTypeList(fillTypeNames, fillTypeCategories, nil, true, true)
                if newFillTypeNames ~= nil then
                    if THUtils.getIsDebugEnabled() then
                        local vehicleName = self:getName() or THVSpec_XTSprayTypes.CLASS_NAME
                        THUtils.displayMsg("%s >> updated fill unit fill types: %s", vehicleName, newFillTypeNames)
                    end
                    wrappedXML:setValue(xmlKey .. "#fillTypes", newFillTypeNames)
                    if fillTypeCategories ~= nil then
                        wrappedXML:removeProperty(xmlKey .. "#fillTypeCategories")
                    end
                end
            end
        end
    end)
    return superFunc(self, xmlFile, xmlKey, ...)
end
function THVSpec_XTSprayTypes.sInj_getFillUnitAllowsFillType(self, superFunc, fillUnitIndex, fillTypeIndex, ...)
    local specTable = getSpecTable(self)
    local function appendFunc(rSuccess, ...)
        if fillUnitIndex ~= nil and fillTypeIndex ~= nil then
            THUtils.pcall(function()
                local xtSprayTypeData = g_thSprayTypes:getExtendedSprayTypeByFillType(fillTypeIndex)
                if xtSprayTypeData ~= nil then
                    if not specTable.isSprayerTypeInitialized then
                        local xtSprayTypes, xtNumSprayTypes = g_thSprayTypes:getExtendedSprayTypes()
                        if xtSprayTypes ~= nil and xtNumSprayTypes > 0 then
                            for xtSprayIndex = 1, xtNumSprayTypes do
                                local xtOtherSprayTypeData = xtSprayTypes[xtSprayIndex]
                                if superFunc(self, fillUnitIndex, xtOtherSprayTypeData.fillType.index) then
                                    if xtOtherSprayTypeData.subTypeIndex == THSprayTypes.SPRAY_SUB_TYPE.LIQUID then
                                        specTable.isLiquidSprayer = true
                                    else
                                        specTable.isSolidSprayer = true
                                    end
                                    specTable.allowedSprayTypeGroups[xtOtherSprayTypeData.groupIndex] = true
                                end
                            end
                        end
                        if THUtils.getIsDebugEnabled() then
                            THUtils.objectDisplayMsg(self, "Initialized sprayer type:")
                            THUtils.displayMsg("- isLiquidSprayer: %s", specTable.isLiquidSprayer)
                            THUtils.displayMsg("- isSolidSprayer: %s", specTable.isSolidSprayer)
                            THUtils.displayMsg("- allowed spray type groups:")
                            THUtils.printTableValues(specTable.allowedSprayTypeGroups)
                        end
                        specTable.isSprayerTypeInitialized = true
                    end
                end
            end)
        end
        return rSuccess, ...
    end
    return appendFunc(superFunc(self, fillUnitIndex, fillTypeIndex, ...))
end
function THVSpec_XTSprayTypes.sInj_getSprayerUsage(self, superFunc, fillTypeIndex, ...)
    local specTable = getSpecTable(self)
    local lastPHMapUsageSprayType, isPHMapUsageSet = nil, false
    if specTable ~= nil and fillTypeIndex ~= nil then
        THUtils.pcall(function()
            local xtSprayTypeData = g_thSprayTypes:getExtendedSprayTypeByFillType(fillTypeIndex)
            if xtSprayTypeData ~= nil then
                local pfExtSprayerSpec = specTable.pfExtSprayerSpec
                if xtSprayTypeData.groupIndex == THSprayTypes.SPRAY_TYPE_GROUP.LIME then
                    if pfExtSprayerSpec ~= nil then
                        local thPHMapData = THSprayTypes.PHMap.getCustomData(pfExtSprayerSpec.pHMap)
                        if thPHMapData ~= nil then
                            lastPHMapUsageSprayType = thPHMapData:setUsageSprayType(xtSprayTypeData.sprayType.index)
                            isPHMapUsageSet = true
                        end
                    end
                end
            end
        end)
    end
    local function appendFunc(...)
        if isPHMapUsageSet and specTable ~= nil then
            THUtils.pcall(function()
                local pfExtSprayerSpec = specTable.pfExtSprayerSpec
                if pfExtSprayerSpec ~= nil then
                    local thPHMapData = THSprayTypes.PHMap.getCustomData(pfExtSprayerSpec.pHMap)
                    if thPHMapData ~= nil then
                        thPHMapData:setUsageSprayType(lastPHMapUsageSprayType)
                    end
                end
            end)
        end
        return ...
    end
    return appendFunc(superFunc(self, fillTypeIndex, ...))
end
function THVSpec_XTSprayTypes.sInj_getExternalFill(self, superFunc, fillTypeIndex, dt, ...)
    local prependSuccess = false
    if fillTypeIndex ~= nil then
        THUtils.pcall(function()
            THVSpec_XTSprayTypes.mapExtendedSprayTypeConstants(self, fillTypeIndex, true, true, debugFlagId, THDebugLevel.LOOP)
            prependSuccess = true
        end)
    end
    local function appendFunc(...)
        if prependSuccess then
            THUtils.pcall(function()
                g_thSprayTypes:resetExtendedSprayTypeConstants(debugFlagId, THDebugLevel.LOOP)
            end)
        end
        return ...
    end
    return appendFunc(superFunc(self, fillTypeIndex, dt, ...))
end
function THVSpec_XTSprayTypes.sInj_getCurrentSprayerMode(self, superFunc, ...)
    local specTable = getSpecTable(self)
    local prependSuccess = false
    if specTable ~= nil then
        THUtils.pcall(function()
            local pfExtSprayerSpec = specTable.pfExtSprayerSpec
            if pfExtSprayerSpec ~= nil then
                local spraySourceVehicle, sourceFillUnitIndex = specTable.pfExtendedSprayer.getFillTypeSourceVehicle(self)
                if spraySourceVehicle ~= nil and sourceFillUnitIndex ~= nil then
                    local sourceFillType = spraySourceVehicle:getFillUnitLastValidFillType(sourceFillUnitIndex)
                    if sourceFillType ~= nil and sourceFillType ~= FillType.UNKNOWN then
                        THVSpec_XTSprayTypes.mapExtendedSprayTypeConstants(self, sourceFillType, true, true, debugFlagId, THDebugLevel.LOOP)
                        prependSuccess = true
                    end
                end
            end
        end)
    end
    local function appendFunc(rIsLiming, rIsFertilizing, ...)
        if prependSuccess then
            THUtils.pcall(function()
                g_thSprayTypes:resetExtendedSprayTypeConstants(debugFlagId, THDebugLevel.LOOP)
                if THUtils.getIsDebugEnabled(debugFlagId, THDebugLevel.UPDATE) then
                    THUtils.objectDisplayMsg(self, "Current sprayer mode:")
                    THUtils.displayMsg("- isLiming: %s", rIsLiming == true)
                    THUtils.displayMsg("- isFertilizing: %s", rIsFertilizing == true)
                    printCallstack()
                end
            end)
        end
        return rIsLiming, rIsFertilizing, ...
    end
    return appendFunc(superFunc(self, ...))
end
function THVSpec_XTSprayTypes.sInj_processSowingMachineArea(self, superFunc, ...)
    local sprayerSpec = self.spec_sprayer
    local prependSuccess = false
    if sprayerSpec ~= nil then
        THUtils.pcall(function()
            local sprayFillType = sprayerSpec.workAreaParameters.sprayFillType
            if sprayFillType ~= nil and sprayFillType ~= FillType.UNKNOWN then
                THVSpec_XTSprayTypes.mapExtendedSprayTypeConstants(self, sprayFillType, true, true, debugFlagId, THDebugLevel.UPDATE)
                prependSuccess = true
            end
        end)
    end
    local function appendFunc(...)
        if prependSuccess then
            THUtils.pcall(function()
                g_thSprayTypes:resetExtendedSprayTypeConstants(debugFlagId, THDebugLevel.UPDATE)
            end)
        end
        return ...
    end
    return appendFunc(superFunc(self, ...))
end
function THVSpec_XTSprayTypes.sInj_updateExtendedSprayerNozzleEffectState(self, superFunc, ...)
    local sprayerSpec = self.spec_sprayer
    local prependSuccess = false
    if sprayerSpec ~= nil then
        THUtils.pcall(function()
            local sprayFillType = sprayerSpec.workAreaParameters.sprayFillType
            if sprayFillType ~= nil and sprayFillType ~= FillType.UNKNOWN then
                THVSpec_XTSprayTypes.mapExtendedSprayTypeConstants(self, sprayFillType, true, true, debugFlagId, THDebugLevel.LOOP)
                prependSuccess = true
            end
        end)
    end
    local function appendFunc(...)
        if prependSuccess then
            THUtils.pcall(function()
                g_thSprayTypes:resetExtendedSprayTypeConstants(debugFlagId, THDebugLevel.LOOP)
            end)
        end
        return ...
    end
    return appendFunc(superFunc(self, ...))
end
function THVSpec_XTSprayTypes.gOverwrite_onChangedFillType(self, superFunc, arg2, fillTypeIndex, ...)
    local specTable = getSpecTable(self)
    local prependSuccess = false
    if specTable ~= nil then
        THUtils.pcall(function()
            local pfExtSprayerSpec = specTable.pfExtSprayerSpec
            local xtSprayTypeData = g_thSprayTypes:getExtendedSprayTypeByFillType(fillTypeIndex)
            if xtSprayTypeData ~= nil then
                THVSpec_XTSprayTypes.mapExtendedSprayTypeConstants(self, xtSprayTypeData.fillType.index, true, true, debugFlagId, THDebugLevel.UPDATE)
                THVSpec_XTSprayTypes.setCurrentSprayerType(self, xtSprayTypeData.fillType.index)
                if pfExtSprayerSpec ~= nil then
                    if xtSprayTypeData.groupIndex == THSprayTypes.SPRAY_TYPE_GROUP.LIME then
                        pfExtSprayerSpec.isSolidFertilizerSprayer = true
                    end
                end
                prependSuccess = true
            end
        end)
    end
    local function appendFunc(...)
        if prependSuccess then
            THUtils.pcall(function()
                g_thSprayTypes:resetExtendedSprayTypeConstants(debugFlagId, THDebugLevel.UPDATE)
                THVSpec_XTSprayTypes.resetSprayerTypes(self)
            end)
        end
        return ...
    end
    return appendFunc(superFunc(self, arg2, fillTypeIndex, ...))
end
function THVSpec_XTSprayTypes.gOverwrite_onEndWorkAreaProcessing(self, superFunc, ...)
    local sprayerSpec = self.spec_sprayer
    local prependSuccess = false
    THUtils.pcall(function()
        if sprayerSpec ~= nil then
            local sprayFillType = sprayerSpec.workAreaParameters.sprayFillType
            if sprayFillType ~= nil and sprayFillType ~= FillType.UNKNOWN then
                THVSpec_XTSprayTypes.mapExtendedSprayTypeConstants(self, sprayFillType, true, true, debugFlagId, THDebugLevel.UPDATE)
                prependSuccess = true
            end
        end
    end)
    local function appendFunc(...)
        if prependSuccess then
            THUtils.pcall(function()
                g_thSprayTypes:resetExtendedSprayTypeConstants(debugFlagId, THDebugLevel.UPDATE)
            end)
        end
        return ...
    end
    return appendFunc(superFunc(self, ...))
end