PunctureStateEvent = {}
local PunctureStateEvent_mt = Class(PunctureStateEvent, Event)
InitEventClass(PunctureStateEvent, "MudSystemPhysics.PunctureStateEvent")

function PunctureStateEvent.emptyNew()
    return Event.new(PunctureStateEvent_mt)
end

function PunctureStateEvent.new(vehicle, wheelIndex, stage, repaired, x, y, z, rotY, aiEvent)
    local self = PunctureStateEvent.emptyNew()
    self.vehicle = vehicle
    self.wheelIndex = wheelIndex or 0
    self.stage = stage or 0
    self.repaired = repaired == true
    self.x = x or 0
    self.y = y or 0
    self.z = z or 0
    self.rotY = rotY or 0
    self.aiEvent = aiEvent == true
    return self
end

function PunctureStateEvent:readStream(streamId, connection)
    self.vehicle = NetworkUtil.readNodeObject(streamId)
    self.wheelIndex = streamReadUInt8(streamId)
    self.stage = streamReadUInt8(streamId)
    self.repaired = streamReadBool(streamId)
    self.x = streamReadFloat32(streamId)
    self.y = streamReadFloat32(streamId)
    self.z = streamReadFloat32(streamId)
    self.rotY = streamReadFloat32(streamId)
    self.aiEvent = streamReadBool(streamId)
    self:run(connection)
end

function PunctureStateEvent:writeStream(streamId, connection)
    NetworkUtil.writeNodeObject(streamId, self.vehicle)
    streamWriteUInt8(streamId, self.wheelIndex or 0)
    streamWriteUInt8(streamId, self.stage or 0)
    streamWriteBool(streamId, self.repaired == true)
    streamWriteFloat32(streamId, self.x or 0)
    streamWriteFloat32(streamId, self.y or 0)
    streamWriteFloat32(streamId, self.z or 0)
    streamWriteFloat32(streamId, self.rotY or 0)
    streamWriteBool(streamId, self.aiEvent == true)
end

function PunctureStateEvent:run(connection)
    if PunctureSystem == nil or self.vehicle == nil then return end

    if connection ~= nil and not connection:getIsServer() and g_server ~= nil then
        if not PunctureSystem:handleClientStateRequest(
            connection, self.vehicle, self.wheelIndex, self.stage,
            self.repaired, self.x, self.y, self.z, self.rotY
        ) then
            PunctureSystem:sendWheelStateToConnection(connection, self.vehicle, self.wheelIndex)
        end
        return
    end

    PunctureSystem:applyNetworkState(
        self.vehicle, self.wheelIndex, self.stage, self.repaired,
        self.x, self.y, self.z, self.rotY, false, self.aiEvent
    )
end

function PunctureStateEvent.send(vehicle, wheelIndex, stage, repaired, x, y, z, rotY, aiEvent)
    if PunctureSystem == nil or vehicle == nil then return end

    PunctureSystem:applyNetworkState(
        vehicle, wheelIndex, stage, repaired, x, y, z, rotY, true, aiEvent
    )

    local event = PunctureStateEvent.new(vehicle, wheelIndex, stage, repaired, x, y, z, rotY, aiEvent)
    if g_server ~= nil then
        g_server:broadcastEvent(event, nil, nil, vehicle)
    elseif g_client ~= nil and g_client:getServerConnection() ~= nil then
        g_client:getServerConnection():sendEvent(event)
    end
end
