--
-- FieldInfoDisplayExtension
--
-- @author Stefan Maurus
-- @date 13/08/2020
--
-- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved.


FieldInfoDisplayExtension = {}

FieldInfoDisplayExtension.MOD_NAME = g_currentModName

local FieldInfoDisplayExtension_mt = Class(FieldInfoDisplayExtension)

function FieldInfoDisplayExtension.new(customMt)
    local self = setmetatable({}, customMt or FieldInfoDisplayExtension_mt)

    self.startInsertIndex = 1

    return self
end

function FieldInfoDisplayExtension:loadFromXML(xmlFile, key, baseDirectory, configFileName, mapFilename)
    return true
end

function FieldInfoDisplayExtension:delete()
end

function FieldInfoDisplayExtension:addFieldInfo(text, object, updateFunc, prio)
    local fieldInfo = {
        text = text,
        object = object,
        updateFunc = updateFunc,
        prio = prio or 100,
        lastValue = nil,
    }

    table.insert(self.fieldInfos, fieldInfo)
end

function FieldInfoDisplayExtension:overwriteGameFunctions(pfModule)
    pfModule:overwriteGameFunction(FieldInfoDisplay, "setupRows", function(superFunc, fieldInfoDisplay)
        superFunc(fieldInfoDisplay)

        -- remove fertilizer and lime rows
        for infoType, infoTypeRow in pairs(fieldInfoDisplay.rows) do
            if infoType == FieldInfoDisplay.INFO_TYPE.FERTILIZATION or infoType == FieldInfoDisplay.INFO_TYPE.LIME_STATE then
                infoTypeRow.infoType = FieldInfoDisplay.INFO_TYPE.CUSTOM
                self.startInsertIndex = math.max(self.startInsertIndex, infoType + 1)
            end
        end

        self.fieldInfoDisplay = fieldInfoDisplay

        self.fieldInfos = {}
        pfModule:collectFieldInfos(self)

        table.sort(self.fieldInfos, function(a, b) return a.prio < b.prio end)
    end)

    pfModule:overwriteGameFunction(FieldInfoDisplay, "update", function(superFunc, fieldInfoDisplay, dt)
        if fieldInfoDisplay.isEnabled and fieldInfoDisplay.player ~= nil and fieldInfoDisplay.player.isEntered and not fieldInfoDisplay.requestedFieldData then
            local posX, _, posZ, rotY = fieldInfoDisplay.player:getPositionData()

            local sizeX, sizeZ = 5, 5
            local distance = 2

            local dirX, dirZ = MathUtil.getDirectionFromYRotation(rotY)
            local sideX,_,sideZ = MathUtil.crossProduct(dirX, 0, dirZ, 0, 1, 0)

            local startWorldX,  startWorldZ  = posX - sideX*sizeX*0.5 - dirX*distance,         posZ - sideZ*sizeX*0.5 - dirZ*distance
            local widthWorldX,  widthWorldZ  = posX + sideX*sizeX*0.5 - dirX*distance,         posZ + sideZ*sizeX*0.5 - dirZ*distance
            local heightWorldX, heightWorldZ = posX - sideX*sizeX*0.5 - dirX*(distance+sizeZ), posZ - sideZ*sizeX*0.5 - dirZ*(distance+sizeZ)

            local isColorBlindMode = g_gameSettings:getValue(GameSettings.SETTING.USE_COLORBLIND_MODE) or false

            for i=1, #self.fieldInfos do
                g_asyncManager:addTask(function()
                    local fieldInfo = self.fieldInfos[i]

                    local value, color, additionalText = fieldInfo.updateFunc(fieldInfo.object, startWorldX, startWorldZ, widthWorldX, widthWorldZ, heightWorldX, heightWorldZ, isColorBlindMode)

                    if fieldInfo.fieldInfoIndex ~= nil then
                        local row = fieldInfoDisplay.rows[fieldInfo.fieldInfoIndex]
                        if row ~= nil then
                            if value ~= nil then
                                if fieldInfo.lastValue == nil then
                                    fieldInfoDisplay.needResize = true
                                end

                                row.leftText = fieldInfo.text

                                if additionalText ~= nil then
                                    row.leftText = row.leftText .. string.format(" (%s)", additionalText)
                                end

                                row.rightText = value

                                for ci = 1, 4 do
                                    row.leftColor[ci] = (color or FieldInfoDisplay.COLOR.TEXT_DEFAULT)[ci]
                                end
                            else
                                if fieldInfo.lastValue ~= nil then
                                    fieldInfoDisplay:clearInfoRow(row)
                                    fieldInfoDisplay.needResize = true
                                    fieldInfo.fieldInfoIndex = nil
                                end
                            end
                            fieldInfo.lastValue = value
                        end
                    elseif value ~= nil then
                        -- temporary block the removed fertilize and lime level, so be have the precision farming stuff always at the bottom
                        -- also block specific slots based on the info index which represents the prio, so they are always sorted correctly
                        for tempIndex = 1, FieldInfoDisplay.MAX_ROW_COUNT do
                            local tempRow = self.fieldInfoDisplay.rows[tempIndex]
                            if tempIndex < self.startInsertIndex + (i-1) then
                                if tempRow.infoType == FieldInfoDisplay.INFO_TYPE.CUSTOM and tempRow.leftText == "" and tempRow.rightText == "" then
                                    tempRow.leftText = "PA_TEMP_BLOCKED"

                                    -- while seasons is active we only block one slot to put the soil type in the next slot
                                    -- otherwise we would overlap with slot 10 which is used by seasons
                                    if pfModule:getIsSeasonsActive() then
                                        break
                                    end
                                end
                            end
                        end

                        fieldInfo.fieldInfoIndex = self.fieldInfoDisplay:addCustomText(fieldInfo.text, value, color or FieldInfoDisplay.COLOR.TEXT_DEFAULT)

                        for tempIndex = 1, FieldInfoDisplay.MAX_ROW_COUNT do
                            local tempRow = self.fieldInfoDisplay.rows[tempIndex]
                            if tempRow.leftText == "PA_TEMP_BLOCKED" then
                                tempRow.leftText = ""
                            end
                        end
                    end
                end)
            end
        end

        superFunc(fieldInfoDisplay, dt)
    end)

    -- ignore default fertilizer and lime state
    pfModule:overwriteGameFunction(FieldInfoDisplay, "setFertilization", function(superFunc, fieldInfoDisplay, fertilizationFactor) end)
    pfModule:overwriteGameFunction(FieldInfoDisplay, "setLimeRequired", function(superFunc, fieldInfoDisplay, isRequired) end)
end
