--[[

tedderImprovement.lua   -   Tedder by wetness level threshold

Wetness levels are introduced for converter target filltypes.
Tedders only down to a certain wetness level, defined by the wetness level of the first
dropped fill type. Disconnecting the Tedder resets the wetness level lock.

Author:		Alex B. (Agathodaimon)
Date:		21.10.2020
Version:	2.0.0

History:	1.0.1 - 16.10.2020 - initial version, changed name and removed some unneccessary assignments
            1.1.0 - 17.10.2020 - simplified onLoad function
            2.0.0 - 21.10.2020 - unlock wetness level only when Tedder is disconnected
                               - added some debugging functionality
            2.1.0 - 30.10.2020 - only append or overwrite functions on first load (in case the script exists in map and M+)
            2.1.1 - 09.11.2020 - fixed lua error when wetgrass does not exist in map in combination with Seasons (modelleicher)
                               - fixed locking onto wrong filltype (modelleicher)
                               - removed 2.1.0 fix, since it doesn't do anything the way it was implemented and isn't needed. People don't add this script into any other mod ffs.
]]


local DEBUG = false      -- set to true for debugging in test, false for production


-- Append to Tedder:onLoad
--  Define a wetness level for each target filltype 
--  Define new reverse converters for each wetness level 
--  Initialize wetness lock in unlocked state
local function tedderOnLoad(self, savegame)
    local spec = self.spec_tedder
    
    -- only run rest of the script if wetgrass is available (modelleicher 09.11.2020)
    if g_fillTypeManager:getFillTypeIndexByName("WETGRASS_WINDROW") == nil then
        return
    else
        spec.hasWetnessLevels = true
    end
    
    -- wetness levels for target filltypes 
    spec.fillTypeWetnessLevel = {}

    -- reverse converters for the three wetness levels    
    spec.ftConvertersReverse = {}
    spec.ftConvertersReverse[1] = spec.fillTypeConvertersReverse            -- default and backup
    spec.ftConvertersReverse[2] = {}
    spec.ftConvertersReverse[3] = {}

    
    for targetFillType, inputFillTypes in pairs(spec.fillTypeConvertersReverse) do  
        local fillTypeName = string.lower(g_fillTypeManager.indexToName[targetFillType])
        local ift = {unpack(inputFillTypes)}
        table.insert(ift, targetFillType)

        -- assign wetness level and build converter
        if string.find(fillTypeName, "semidry") ~= nil then
            spec.fillTypeWetnessLevel[targetFillType] = 2                   -- SEMIDRY target filltypes
            spec.ftConvertersReverse[2][targetFillType] = ift               -- 2: normal -> semidry & semidry -> semidry
            spec.ftConvertersReverse[3][targetFillType] = {targetFillType}  -- 3: semidry -> semidry
        elseif string.find(fillTypeName, "dry") ~= nil then
            spec.fillTypeWetnessLevel[targetFillType] = 1                   -- DRY target filltypes
            spec.ftConvertersReverse[2][targetFillType] = {targetFillType}  -- 2: dry -> dry
            spec.ftConvertersReverse[3][targetFillType] = {targetFillType}  -- 3: dry -> dry        
        else
            spec.fillTypeWetnessLevel[targetFillType] = 3                   -- NORMAL (all other) target filltypes
            spec.ftConvertersReverse[2][targetFillType] = inputFillTypes    -- 2: wet -> normal
            spec.ftConvertersReverse[3][targetFillType] = ift               -- 3: wet -> normal & normal -> normal
        end
    end
    
    -- initialize wetness level lock in unlocked state
    spec.wetnessLevelLocked = false

    if DEBUG then
        -- print information about wetness levels and reverse converters into log
        print("Wetness levels by fill type:")
        for k, v in pairs(spec.fillTypeWetnessLevel) do
            print(tostring(g_fillTypeManager.indexToName[k]) .. " -> " .. v)
        end
        print("Wetness reverse converters:")
        for i, t in pairs(spec.ftConvertersReverse) do
            print("Converter " .. i)
            for target, input in pairs(t) do
                print("  " .. tostring(g_fillTypeManager.indexToName[target]) .. " ->")        
                for k, v in pairs(input) do
                    print("    Index " .. k .. ": " .. tostring(g_fillTypeManager.indexToName[v]))        
                end
            end
        end
        print("Wetness level unlocked..")
    end
end


-- Overwrite Tedder:processTedderArea
--  Only convert target filltypes with same or higher wetness level after locking 
--  Unlocks only by disconnecting tedder (see tedderOnDeactivate()) 
local function tedderProcessTedderArea(self, superFunc, workArea, dt)
    local spec = self.spec_tedder
    
    if spec.hasWetnessLevels then

        if spec.wetnessLevelLocked then
            spec.fillTypeConvertersReverse = spec.ftConvertersReverse[spec.activeWetnessLevel]
        else
            spec.fillTypeConvertersReverse = spec.ftConvertersReverse[1]
            workArea.lastDropFillType = FillType.UNKNOWN
        end
    end

    area, _ = superFunc(self, workArea, dt)



	return area, area
end


local function tedderProcessDropArea(self, superFunc, dropArea, fillType, litersToDrop)

    local spec = self.spec_tedder	
	if spec.hasWetnessLevels then
        if not spec.wetnessLevelLocked and fillType ~= FillType.UNKNOWN then
            spec.activeWetnessLevel = spec.fillTypeWetnessLevel[fillType]
            spec.wetnessLevelLocked = true
            
            
            print("Active wetness level = " .. spec.activeWetnessLevel)
            print("Wetness level locked..")
            
        end
    end
	
	dropped = superFunc(self, dropArea, fillType, litersToDrop)
	
	return dropped
end



-- Append to Tedder.onDeactivate
-- Unlock wetness level when Tedder is disconnected 
local function tedderOnDeactivate(self)
	local spec = self.spec_tedder
    
    if spec.hasWetnessLevels then

        spec.wetnessLevelLocked = false

        -- reset workArea to Unknown and 0 so switcher doesn't use last used type as new wetness level lock in (modelleicher, 08.11.2020)
        for _, workArea in pairs(self.spec_workArea.workAreas) do
            if workArea.type == g_workAreaTypeManager:getWorkAreaTypeIndexByName("tedder") then
                workArea.lastDropFillType = FillType.UNKNOWN

                workArea.lastPickupLiters = 0
                workArea.litersToDrop = 0
        
            end
        end

        if DEBUG then
            print("Wetness level unlocked..")
        end
    end
end

Tedder.onLoad = Utils.appendedFunction(Tedder.onLoad, tedderOnLoad)
Tedder.processTedderArea = Utils.overwrittenFunction(Tedder.processTedderArea, tedderProcessTedderArea)
Tedder.processDropArea = Utils.overwrittenFunction(Tedder.processDropArea, tedderProcessDropArea)
Tedder.onDeactivate = Utils.appendedFunction(Tedder.onDeactivate, tedderOnDeactivate)


