--[[
Interface: 1.6.0.0 b9173

Copyright (C) GtX (Andy), 2019

Author: GtX | Andy
Date: 12.09.2019
Version: 1.0.0.0

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

History:
V 1.0.0.0 @ 12.09.2019 - Release Version
V 1.1.0.0 @ 05.01.2020 - Remove functions no longer needed.

Important:
Free for use in other mods - no permission needed.
No changes are to be made to this script without permission from GtX | Andy

Frei verwendbar - keine erlaubnis nötig
An diesem Skript dürfen ohne Genehmigung von GtX | Andy keine Änderungen vorgenommen werden
]]


SiloDisplayManager = {}
local SiloDisplayManager_mt = Class(SiloDisplayManager)

local manager
local modName = g_currentModName
local modDirectory = g_currentModDirectory

function SiloDisplayManager:init()
    local canLoadPlaceable = true
    local path = modDirectory .. "scripts/events/SiloDisplayEvent.lua"

    if fileExists(path) then
        source(path)
    else
        canLoadPlaceable = false
        print(string.format("  Error: [SiloDisplayManager] - [%s]  Required event file '%s' could not be found!", modName, path))
    end

    if g_gui ~= nil and g_gui.guis.SiloDisplayGui == nil then
        path = modDirectory .. "scripts/gui/SiloDisplayGui.lua"

        if fileExists(path) then
            source(path)
        else
            canLoadPlaceable = false
            print(string.format("  Error: [SiloDisplayManager] - [%s]  Required file '%s' could not be found!", modName, path))
        end

        if canLoadPlaceable then
            path = modDirectory .. "scripts/gui/SiloDisplayGui.xml"

            if fileExists(path) then
                local siloDisplayGui = SiloDisplayGui:new(nil)
                g_gui:loadGui(path, "SiloDisplayGui", siloDisplayGui)
            else
                canLoadPlaceable = false
                print(string.format("  Error: [SiloDisplayManager] - [%s]  Required file '%s' could not be found!", modName, path))
            end
        end
    end

    if canLoadPlaceable then
        path = modDirectory .. "scripts/SiloDisplay.lua"

        if fileExists(path) then
            g_placeableTypeManager:addPlaceableType("siloDisplayPlaceable", "SiloDisplay", path)

            -- Using 'AddMaterialHolderTypes.lua' to show how icons for custom types can be added to maps / mods.
            -- g_materialManager:addMaterialType("SILO_DISPLAY_ICON")

            manager = SiloDisplayManager:new(g_server ~= nil, g_client ~= nil, g_dedicatedServerInfo ~= nil, modName)
            if manager ~= nil then
                getfenv(0)["g_siloDisplays"] = manager

                Mission00.onStartMission = Utils.appendedFunction(Mission00.onStartMission, onStartMission)
                FSBaseMission.delete = Utils.appendedFunction(FSBaseMission.delete, deleteFinal)
            end
        else
            print(string.format("  Error: [SiloDisplayManager] - [%s]  Required file '%s' could not be found!", modName, path))
        end
    else
        print(string.format("  Info: [SiloDisplayManager] - placeableType '%s.siloDisplayPlaceable' failed to load! Supporting files are missing.", modName))
    end
end

function SiloDisplayManager:new(isServer, isClient, isDedi, customEnvironment)
    if g_siloDisplays ~= nil then
        return
    end

    local self = {}
    setmetatable(self, SiloDisplayManager_mt)

    self.isServer = isServer
    self.isClient = isClient
    self.isDedi = isDedi

    self.customEnvironment = customEnvironment

    self.displays = {}
    self.numDisplays = 0

    return self
end

function SiloDisplayManager:addDisplay(display, hasText)
    if self.displays[display] == nil then
        self.displays[display] = display
        self.numDisplays = self.numDisplays + 1
    end
end

function SiloDisplayManager:removeDisplay(display)
    if self.displays[display] ~= nil then
        self.displays[display] = nil
        self.numDisplays = math.max(self.numDisplays - 1, 0)
    end
end

function onStartMission(mission)
    if g_siloDisplays ~= nil then
        Storage.setFillLevel = Utils.appendedFunction(Storage.setFillLevel, setFillLevel)
        Storage.addLoadingStation = Utils.appendedFunction(Storage.addLoadingStation, addLoadingStation)
        StorageSystem.removeStorage = Utils.overwrittenFunction(StorageSystem.removeStorage, removeStorage)
    end
end

function deleteFinal(mission)
    if g_siloDisplays ~= nil then
        removeModEventListener(g_siloDisplays)

        getfenv(0)["g_siloDisplays"] = nil
        manager = nil
    end
end

function setFillLevel(storage, fillLevel, fillType)
    if storage.siloDisplays ~= nil then
        for siloDisplay, _ in pairs (storage.siloDisplays) do
            siloDisplay:updateSlot(fillType, fillLevel, storage)
        end
    end
end

function addLoadingStation(storage, loadingStation)
    if g_siloDisplays ~= nil and g_siloDisplays.numDisplays > 0 then
        for siloDisplay, _ in pairs (g_siloDisplays.displays) do
            if not siloDisplay:hasStorage(storage) and siloDisplay:getIsStationInRange(loadingStation, true) then
                siloDisplay:onStorageAdded(storage, true)
            end
        end
    end
end

function removeStorage(storageSystem, superFunc, storage)
    if superFunc(storageSystem, storage) then
        if storage.siloDisplays ~= nil then
            for siloDisplay, _ in pairs (storage.siloDisplays) do
                if siloDisplay:hasStorage(storage) then
                    siloDisplay:onStorageRemoved(storage, true)
                end
            end

        end

        return true
    end

    return false
end

SiloDisplayManager:init()
