ParkItUnderARoofSettingsEvent = ParkItUnderARoofSettingsEvent or {}
local ParkItUnderARoofSettingsEvent_mt = Class(ParkItUnderARoofSettingsEvent, Event)

InitEventClass(ParkItUnderARoofSettingsEvent, "ParkItUnderARoofSettingsEvent")

function ParkItUnderARoofSettingsEvent.emptyNew()
    return Event.new(ParkItUnderARoofSettingsEvent_mt)
end

function ParkItUnderARoofSettingsEvent.new(isRequest, snapshot)
    local self = ParkItUnderARoofSettingsEvent.emptyNew()
    self.isRequest = isRequest == true
    self.snapshot = snapshot
    return self
end

local function getSettings()
    return rawget(_G, "ParkItUnderARoofSettings")
end

function ParkItUnderARoofSettingsEvent:writeStream(streamId, connection)
    streamWriteBool(streamId, self.isRequest)

    if not self.isRequest then
        local snapshot = self.snapshot or {}
        streamWriteUInt8(streamId, tonumber(snapshot.damageSpeed) or 2)
        streamWriteUInt8(streamId, tonumber(snapshot.dirtSpeed) or 2)
        streamWriteBool(streamId, snapshot.autoRepair == true)
        streamWriteUInt8(streamId, math.clamp(math.floor((tonumber(snapshot.autoRepairCostRatio) or 1.25) * 4 + 0.5), 2, 8))
        streamWriteBool(streamId, snapshot.autoWash == true)
        streamWriteBool(streamId, snapshot.showRoofStatus == true)
        streamWriteBool(streamId, snapshot.outdoorDamage ~= false)
        streamWriteBool(streamId, snapshot.outdoorDirt ~= false)
        streamWriteUInt8(streamId, math.clamp(math.floor((tonumber(snapshot.outdoorDamageMax) or 0.4) * 10 + 0.5), 1, 10))
    end
end

function ParkItUnderARoofSettingsEvent:readStream(streamId, connection)
    self.isRequest = streamReadBool(streamId)

    if self.isRequest then
        local settings = getSettings()
        if g_server ~= nil and settings ~= nil and settings.collectSnapshot ~= nil and connection ~= nil and connection.sendEvent ~= nil then
            connection:sendEvent(ParkItUnderARoofSettingsEvent.new(false, settings:collectSnapshot()))
        end
        return
    end

    self.snapshot = {
        damageSpeed = streamReadUInt8(streamId),
        dirtSpeed = streamReadUInt8(streamId),
        autoRepair = streamReadBool(streamId),
        autoRepairCostRatio = streamReadUInt8(streamId) / 4,
        autoWash = streamReadBool(streamId),
        showRoofStatus = streamReadBool(streamId),
        outdoorDamage = streamReadBool(streamId),
        outdoorDirt = streamReadBool(streamId),
        outdoorDamageMax = streamReadUInt8(streamId) / 10
    }

    self:run(connection)
end

function ParkItUnderARoofSettingsEvent:run(connection)
    if self.hasRun == true then
        return
    end
    self.hasRun = true

    local settings = getSettings()
    if settings == nil or self.snapshot == nil then
        return
    end

    if g_server ~= nil then
        if AAIntegration ~= nil
            and AAIntegration.isAuthorizedSettingsConnection ~= nil
            and not AAIntegration.isAuthorizedSettingsConnection(connection) then
            connection:sendEvent(ParkItUnderARoofSettingsEvent.new(false, settings:collectSnapshot()))
            return
        end
        settings:applySnapshot(self.snapshot, true)
        g_server:broadcastEvent(ParkItUnderARoofSettingsEvent.new(false, settings:collectSnapshot()), false)
    else
        settings:applySnapshot(self.snapshot, false)
    end
end

function ParkItUnderARoofSettingsEvent.sendRequest()
    if g_client ~= nil and g_client.getServerConnection ~= nil and g_client:getServerConnection() ~= nil then
        g_client:getServerConnection():sendEvent(ParkItUnderARoofSettingsEvent.new(true))
    end
end

function ParkItUnderARoofSettingsEvent.sendSnapshot(snapshot)
    if snapshot == nil then
        return
    end

    if g_server ~= nil then
        g_server:broadcastEvent(ParkItUnderARoofSettingsEvent.new(false, snapshot), false)
    elseif g_client ~= nil and g_client.getServerConnection ~= nil and g_client:getServerConnection() ~= nil then
        local isAdmin = g_currentMission ~= nil and g_currentMission.isMasterUser == true
        if isAdmin then
            g_client:getServerConnection():sendEvent(ParkItUnderARoofSettingsEvent.new(false, snapshot))
        end
    end
end
