local TABAS_TFCSystem = {}

local TABAS_Utils = require("TABAS_Utils")
local TFC_Utils = require("TABAS_TFCSystem_Utils")

function TABAS_TFCSystem.register(tfc_Base)
    local facing = tfc_Base.facing
    local amount = tfc_Base:getAmount()
    local temperature = tfc_Base:getWaterData("temperature")
    local lastUpdate = tfc_Base:getLastUpdate()
    local args = {
        x = tfc_Base.x,
        y = tfc_Base.y,
        z = tfc_Base.z,
        f = facing,
        amount = amount,
        lastUpdate = lastUpdate,
        temperature = temperature,
    }
    sendClientCommand(getSpecificPlayer(0), 'tfcCommands', 'Register', args)
    TFC_Utils.noise("Registered", TFC_Utils.formatCoords(tfc_Base.x, tfc_Base.y, tfc_Base.z))
end

function TABAS_TFCSystem.isRegistered(x, y, z)
    local id = TFC_Utils.getIdByCoords(x, y, z)
    local gData = GetTFCSystemData()
    for k, _ in pairs(gData.Registered) do
        if k == id then return true end
    end
    return false
end

function TABAS_TFCSystem.unregister(x, y, z)
    if not TABAS_TFCSystem.isRegistered(x, y, z) then return end
    local args = {
        x = x,
        y = y,
        z = z,
    }
    sendClientCommand(getSpecificPlayer(0), 'tfcCommands', 'Unregister', args)
    TFC_Utils.noise("Unregistered", TFC_Utils.formatCoords(x, y, z))
end

function TABAS_TFCSystem.Activate(x, y, z, facing, state, activate)
    local args = {
        x = x,
        y = y,
        z = z,
        f = facing,
        state = state,
        activate = activate
    }
    sendClientCommand(getSpecificPlayer(0), 'tfcCommands', 'Activated', args)
    TFC_Utils.noise("TFC Activate", state .. " = " .. tostring(activate))
end

function TABAS_TFCSystem.currentActivatedState(x, y, z)
    local gData = GetTFCSystemData()
    local id = TFC_Utils.getIdByCoords(x, y, z)
    if gData.Activated[id] then
        return gData.Activated[id].state
    end
    return ""
end

function TABAS_TFCSystem.isActivated(x, y, z)
    local gData = GetTFCSystemData()
    local id = TFC_Utils.getIdByCoords(x, y, z)
    if gData.Activated[id] then
        return gData.Activated[id].activate
    else
        return false
    end
end

function TABAS_TFCSystem.syncData(x, y, z, facing)
    local gData = GetTFCSystemData()
    local id = TFC_Utils.getIdByCoords(x, y, z)
    local data = gData.Registered[id]
    if not data then return end

    local square = getCell():getGridSquare(x, y, z)
    if not square then return end

    local tfcObject = TABAS_Utils.getTfcObjectOnSquare(square, facing)
    if tfcObject then
        local modData = tfcObject:getModData()
        modData.amount = data.amount
        modData.temperature = data.temperature
        modData.lastUpdate = data.lastUpdate
        TFC_Utils.noise("TFC Sync Data", tostring(id))
    end
end

function TABAS_TFCSystem.transmitData(x, y, z, dataKey, dataValue)
    local args = {
        x = x,
        y = y,
        z = z,
    }
    args[dataKey] = dataValue

    sendClientCommand(getSpecificPlayer(0), 'tfcCommands', 'dataUpdate', args)
    -- TFC_Utils.noise("TFC update", dataKey .. " => " .. data)
    -- gData.Registered[id][dataKey] = tfc_Base:getWaterData(dataKey)
    -- TFCSystemTransmit()
end

function TABAS_TFCSystem.registPendedRemove(x, y, z, facing)
    local gData = GetTFCSystemData()
    for k,v in pairs(gData.Registered) do
        if x == v.x and y == v.y and z == v.z then
            TABAS_TFCSystem.unregister(x, y, z)
        end
    end
    local args = {
        x = x,
        y = y,
        z = z,
        f = facing
    }
    sendClientCommand(getSpecificPlayer(0), 'tfcCommands', 'RegistPendedRemove', args)
end

function TABAS_TFCSystem.unregistPendedRemove(x, y, z)
    local args = {
        x = x,
        y = y,
        z = z,
    }
    sendClientCommand(getSpecificPlayer(0), 'tfcCommands', 'UnregistPendedRemove', args)
end

local function onLoadChunk(chunk)
    local gData = GetTFCSystemData()
    for k,v in pairs(gData.Registered) do
        if chunk:getGridSquare(v.x, v.y, v.z) then
            local tfc_Base = TABAS_Utils.getTfcBase(v.x, v.y, v.z, v.f)
            -- To sync data, simply call TFC_Base.
        end
    end
    for k,v in pairs(gData.PendedRemove) do
        if chunk:getGridSquare(v.x, v.y, v.z) then
            local tfc_Base = TABAS_Utils.getTfcBase(v.x, v.y, v.z, v.f)
            if tfc_Base then
                tfc_Base:remove()
            end
            TABAS_TFCSystem.unregistPendedRemove(v.x, v.y, v.z)
        end
    end
end
Events.LoadChunk.Add(onLoadChunk)

local function onWaterAmountChange(object, prevAmount)
    if not object or not TABAS_Utils.isTfcObject(object) then return end

    local tfc_Base = TABAS_Utils.getTfcBaseOnBathObject(object)
    if not tfc_Base then return end

    tfc_Base:updateTfc()
    -- TFC_Utils.noise("onWaterAmountChange", "Done!")
end
Events.OnWaterAmountChange.Add(onWaterAmountChange)

local function onObjectAboutToBeRemoved(_object)
    local tfc_Base = TABAS_Utils.getTfcBaseOnBathObject(_object)
    if not tfc_Base then return end
    if not tfc_Base:hasTfc() then return end
    tfc_Base:remove()
    TFC_Utils.noise("Object Removed", "Done!")
end
Events.OnObjectAboutToBeRemoved.Add(onObjectAboutToBeRemoved)



return TABAS_TFCSystem