--[[
Interface: 1.6.0.0 b9173

Copyright (C) GtX (Andy), 2018

Author: GtX | Andy
Date: 09.12.2018
Version: 1.0.0.0

Contact:
https://forum.giants-software.com
https://github.com/GtX-Andy

History:
V 1.1.0.0 @ 17.07.2019 - Added support to position 'waterAddon' parts on unsupported mods.
V 1.2.0.0 @ 25.09.2020 - Code optimisations, added support to position 'milkAddon' parts on unsupported mods, added new setting options.

Important:
Not to be added to any mods / maps or modified from its current release form.
No changes are to be made to this script without permission from GtX | Andy

Darf nicht zu Mods / Maps hinzugefügt oder von der aktuellen Release-Form geändert werden.
An diesem Skript dürfen ohne Genehmigung von GtX | Andy keine Änderungen vorgenommen werden
]]


local manager
local loadError

local modName = g_currentModName
local modDirectory = g_currentModDirectory

local buildId = 2
local versionString = "0.0.0.0"

local function AnimalHusbandry_inj_load(husbandry, superFunc, xmlFilename, x, y, z, rx, ry, rz, initRandom)
    if not superFunc(husbandry, xmlFilename, x, y, z, rx, ry, rz, initRandom) then
        return false
    end

    if g_animalPenExtensionManager ~= nil then
        local isMod = true
        local key = "placeable.animalPenExtension"

        if husbandry.customEnvironment == nil or husbandry.customEnvironment == "" then
            local i3dFilenameLower = husbandry.i3dFilename:lower()
            key = manager.baseBuildings[i3dFilenameLower]

            if key ~= nil then
                isMod = false
                xmlFilename = manager.baseBuildingsXMLFilename
            else
                key = "placeable.animalPenExtension"
            end
        end

        local xmlFile = loadXMLFile("TempXML", xmlFilename)
        if xmlFile ~= nil and xmlFile ~= 0 then
            if hasXMLProperty(xmlFile, key) then
                local extension = manager.animalPenExtension:new(husbandry.isServer, husbandry.isClient)
                extension:setOwnerFarmId(husbandry:getOwnerFarmId(), false)

                if extension:load(husbandry, xmlFile, key, isMod, false, manager.baseDirectory, manager.texts) then
                    extension:register(true)
                    husbandry.animalPenExtension = extension
                else
                    extension:delete()
                    extension = nil
                end
            else
                delete(xmlFile)

                if husbandry.modulesByName["water"] ~= nil then
                    xmlFile = loadXMLFile("TempUniversalXML", manager.universalPartsXMLFilename)

                    if xmlFile ~= nil and xmlFile ~= 0 then
                        local extension = manager.animalPenExtension:new(husbandry.isServer, husbandry.isClient)
                        extension:setOwnerFarmId(husbandry:getOwnerFarmId(), false)
                        if extension:load(husbandry, xmlFile, "animalPenExtension.universalParts", false, true, manager.baseDirectory, manager.texts) then
                            extension:register(true)
                            husbandry.animalPenExtension = extension
                        else
                            extension:delete()
                            extension = nil
                        end

                        delete(xmlFile)
                    end
                end
            end
        end
    end

    return true
end

local function AnimalHusbandry_inj_delete(husbandry)
    if husbandry.animalPenExtension ~= nil then
        husbandry.animalPenExtension:delete()
        husbandry.animalPenExtension = nil
    end
end

local function AnimalHusbandry_inj_saveToXMLFile(husbandry, xmlFile, key, usedModNames)
    if husbandry.animalPenExtension ~= nil then
        husbandry.animalPenExtension:saveToXMLFile(xmlFile, key .. ".animalPenExtension", usedModNames)
    end
end

local function AnimalHusbandry_inj_setOwnerFarmId(husbandry, farmId, noEventSend)
    if husbandry.animalPenExtension ~= nil then
        husbandry.animalPenExtension:setOwnerFarmId(farmId, noEventSend)
    end
end

local function AnimalHusbandry_inj_loadFromXMLFile(husbandry, superFunc, xmlFile, key)
    if superFunc(husbandry, xmlFile, key) then
        if husbandry.animalPenExtension ~= nil then
            return husbandry.animalPenExtension:loadFromXMLFile(xmlFile, key .. ".animalPenExtension")
        end

        return true
    end

    return false
end

local function AnimalHusbandry_inj_readStream(husbandry, streamId, connection)
    if husbandry.animalPenExtension ~= nil then
        if connection:getIsServer() then
            husbandry.animalPenExtension:readStream(streamId, connection)
        end
    end
end

local function AnimalHusbandry_inj_writeStream(husbandry, streamId, connection)
    if husbandry.animalPenExtension ~= nil then
        if not connection:getIsServer() then
            husbandry.animalPenExtension:writeStream(streamId, connection)
        end
    end
end

local function FSBaseMission_inj_loadMapFinished(mission)
    if manager ~= nil then
        if manager:load() then
            AnimalHusbandry.load = Utils.overwrittenFunction(AnimalHusbandry.load, AnimalHusbandry_inj_load)
            AnimalHusbandry.delete = Utils.prependedFunction(AnimalHusbandry.delete, AnimalHusbandry_inj_delete)

            AnimalHusbandry.saveToXMLFile = Utils.appendedFunction(AnimalHusbandry.saveToXMLFile, AnimalHusbandry_inj_saveToXMLFile)
            AnimalHusbandry.setOwnerFarmId = Utils.appendedFunction(AnimalHusbandry.setOwnerFarmId, AnimalHusbandry_inj_setOwnerFarmId)
            AnimalHusbandry.loadFromXMLFile = Utils.overwrittenFunction(AnimalHusbandry.loadFromXMLFile, AnimalHusbandry_inj_loadFromXMLFile)

            AnimalHusbandry.readStream = Utils.appendedFunction(AnimalHusbandry.readStream, AnimalHusbandry_inj_readStream)
            AnimalHusbandry.writeStream = Utils.appendedFunction(AnimalHusbandry.writeStream, AnimalHusbandry_inj_writeStream)
        end
    end
end

local function FSBaseMission_inj_delete(mission)
    if manager ~= nil then
        manager:finalDelete()
        manager = nil
    end

    if loadError ~= nil then
        removeModEventListener(loadError)
        loadError = nil
    end

    getfenv(0)["g_animalPenExtensionManager"] = nil
end

local function FSBaseMission_inj_draw(mission)
    if manager ~= nil and manager.universalPlacement ~= nil then
        manager.universalPlacement:draw()
    end
end

local function FSCareerMissionInfo_inj_saveToXMLFile(missionInfo)
    if manager ~= nil and missionInfo.isValid then
        manager:saveToXMLFile(missionInfo.savegameDirectory .. "/animalPenExtension.xml")
    end
end

local function Server_inj_sendObjects(server, connection, x, y, z, viewDistanceCoeff)
    if manager ~= nil then
        manager:syncSettings(connection)
    end
end

local function initLoadError(name)
    loadError = {
        name = name,
        modName = modName,
        startUpdateTime = 2100,
        versionString = versionString
    }

    loadError.update = function(self, dt)
        if self.startUpdateTime > 0 then
            self.startUpdateTime = self.startUpdateTime - dt
        else
            local title = string.format("Animal Pen Extension - Version %s", self.versionString)
            local text = string.format(g_i18n:getText("animalPenExtension_loadError", self.modName), self.modName, self.name)

            if g_dedicatedServerInfo == nil then
                if not g_gui:getIsGuiVisible() then
                    g_gui:showYesNoDialog({
                        title = title,
                        text = text,
                        dialogType = DialogElement.TYPE_LOADING,
                        callback = self.openModHubLink,
                        target = nil,
                        yesText = g_i18n:getText("button_ok"),
                        noText = g_i18n:getText("button_modHubDownload")
                    })
                end
            else
                print("\n" .. text .. "\n    - https://farming-simulator.com/mods.php?lang=en&country=be&title=fs2019&filter=org&org_id=129652&page=0" .. "\n")
                self.openModHubLink(true)
            end
        end
    end

    loadError.openModHubLink = function(ignore)
        if ignore == false then
            local language = g_languageShort
            local link = "mods.php?lang=en&country=be&title=fs2019&filter=org&org_id=129652&page=0"

            if language == "de" or language == "fr" then
                link = "mods.php?lang=" .. language .. "&country=be&title=fs2019&filter=org&org_id=129652&page=0"
            end

            openWebFile(link, "")
        end

        removeModEventListener(loadError)
        loadError = nil
    end

    addModEventListener(loadError)
end

local function validate(name)
    local mod = g_modManager:getModByName(name)

    versionString = tostring(mod.version) or versionString

    if mod.modName == "FS19_AnimalPenExtension" or
        mod.modName == "FS19_AnimalPenExtension_update" then

        return mod.author:len() == 3, mod.author
    end

    return false, mod.author
end

local function initAnimalPenExtension()
    if g_animalPenExtensionManager ~= nil then
        g_animalPenExtensionManager:logPrint(3, "Mod has already been loaded by '%s'! Please remove duplicate mod '%s'.", g_animalPenExtensionManager.customEnvironment, modName)
        return
    end

    local canLoad, author = validate(modName)

    if canLoad then
        local xmlFilename = modDirectory .. "xml/BaseBuildings.xml"

        if fileExists(xmlFilename) then
            local isServer = g_server ~= nil
            local isClient = g_client ~= nil

            source(modDirectory .. "scripts/AnimalPenExtensionManager.lua")
            manager = AnimalPenExtensionManager:new(isServer, isClient, buildId, versionString, modName, modDirectory, xmlFilename)

            if manager ~= nil then
                getfenv(0)["g_animalPenExtensionManager"] = manager

                source(modDirectory .. "scripts/AnimalPenExtension.lua")

                source(modDirectory .. "scripts/misc/AnimalPenExtensionConsoleCommands.lua")
                source(modDirectory .. "scripts/misc/AnimalPenExtensionUniversalPlacement.lua")

                source(modDirectory .. "scripts/events/AnimalPenExtensionFillEvent.lua")
                source(modDirectory .. "scripts/events/AnimalPenExtensionDelayEvent.lua")
                source(modDirectory .. "scripts/events/AnimalPenExtensionJoinGameEvent.lua")
                source(modDirectory .. "scripts/events/AnimalPenExtensionSellMilkEvent.lua")
                source(modDirectory .. "scripts/events/AnimalPenExtensionBuildHourEvent.lua")
                source(modDirectory .. "scripts/events/AnimalPenExtensionUniversalPartsEvent.lua")
                source(modDirectory .. "scripts/events/AnimalPenExtensionMilkSalesSettingsEvent.lua")

                if g_gui ~= nil then
                    if g_gui.guis.MilkSaleDialog == nil then
                        source(modDirectory .. "scripts/gui/MilkSaleDialog.lua")

                        local milkSaleDialog = MilkSaleDialog:new(nil, manager.texts)
                        g_gui:loadGui(modDirectory .. "scripts/gui/MilkSaleDialog.xml", "MilkSaleDialog", milkSaleDialog)
                    end
                end

                manager.animalPenExtension = AnimalPenExtension
                manager.consoleCommands = AnimalPenExtensionConsoleCommands:new(isServer, isClient, buildId, versionString, modName, modDirectory, manager)
                manager.universalPlacement = AnimalPenExtensionUniversalPlacement:new(isServer, isClient, modName, modDirectory)

                FSBaseMission.loadMapFinished = Utils.prependedFunction(FSBaseMission.loadMapFinished, FSBaseMission_inj_loadMapFinished)
                FSBaseMission.delete = Utils.appendedFunction(FSBaseMission.delete, FSBaseMission_inj_delete)
                FSBaseMission.draw = Utils.appendedFunction(FSBaseMission.draw, FSBaseMission_inj_draw)

                FSCareerMissionInfo.saveToXMLFile = Utils.appendedFunction(FSCareerMissionInfo.saveToXMLFile, FSCareerMissionInfo_inj_saveToXMLFile)
                Server.sendObjects = Utils.prependedFunction(Server.sendObjects, Server_inj_sendObjects)
            end
        end
    else
        initLoadError(author)
    end
end

initAnimalPenExtension()
