PunctureJackEvent = {}
local PunctureJackEvent_mt = Class(PunctureJackEvent, Event)
InitEventClass(PunctureJackEvent, "MudSystemPhysics.PunctureJackEvent")

function PunctureJackEvent.emptyNew()
    return Event.new(PunctureJackEvent_mt)
end

function PunctureJackEvent.new(vehicle, wheelIndex, placed, x, y, z, rotY, extension)
    local self = PunctureJackEvent.emptyNew()
    self.vehicle = vehicle
    self.wheelIndex = wheelIndex or 0
    self.placed = placed == true
    self.x = x or 0
    self.y = y or 0
    self.z = z or 0
    self.rotY = rotY or 0
    self.extension = extension or 0
    return self
end

function PunctureJackEvent:readStream(streamId, connection)
    self.vehicle = NetworkUtil.readNodeObject(streamId)
    self.wheelIndex = streamReadUInt8(streamId)
    self.placed = streamReadBool(streamId)
    self.x = streamReadFloat32(streamId)
    self.y = streamReadFloat32(streamId)
    self.z = streamReadFloat32(streamId)
    self.rotY = streamReadFloat32(streamId)
    self.extension = streamReadFloat32(streamId)
    self:run(connection)
end

function PunctureJackEvent:writeStream(streamId, connection)
    NetworkUtil.writeNodeObject(streamId, self.vehicle)
    streamWriteUInt8(streamId, self.wheelIndex or 0)
    streamWriteBool(streamId, self.placed == 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)
    streamWriteFloat32(streamId, self.extension or 0)
end

function PunctureJackEvent: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:handleClientJackRequest(
            connection, self.vehicle, self.wheelIndex, self.placed,
            self.x, self.y, self.z, self.rotY, self.extension
        ) then
            PunctureSystem:sendJackStateToConnection(connection, self.vehicle, self.wheelIndex)
        end
        return
    end

    PunctureSystem:applyJackNetworkState(
        self.vehicle, self.wheelIndex, self.placed,
        self.x, self.y, self.z, self.rotY, self.extension
    )
end

function PunctureJackEvent.send(vehicle, wheelIndex, placed, x, y, z, rotY, extension)
    if PunctureSystem == nil or vehicle == nil then return end

    PunctureSystem:applyJackNetworkState(
        vehicle, wheelIndex, placed, x, y, z, rotY, extension
    )

    local event = PunctureJackEvent.new(
        vehicle, wheelIndex, placed, x, y, z, rotY, extension
    )
    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
