



function cancelClientObjectBreak (loss)
	cancelEvent()
end

--[[
	The following code is a buffer used to send over damage of the turrets over to serverside.
		Buffer: There is a 300 ms timer to reduce data incase of damage done at a high rate. Like shooting with a minigun, this would kill the network of some players.
]]

local objectLossToSync = {}

local function syncObjectDamage ()
	for turretElement, loss in pairs(objectLossToSync) do
		if isElement(turretElement) then
			triggerServerEvent("onTurretDamage", turretElement, loss, localPlayer)
		end
	end
	 objectLossToSync = {}
end

function cancelClientObjectDamage (loss, attacker)
	if getElementData(source, "sams", false) and attacker and (attacker == localPlayer or (getElementType(attacker) == "vehicle" and attacker == getPedOccupiedVehicle(localPlayer))) then

		local turretElement = getElementParent(source)
		if getElementType(turretElement) == "turret" then
			if loss == 30 then -- It seems like 30 loss is caused by an explosion. Not sure why it is so low...
				loss = 1000
			end
			if not next(objectLossToSync) then
				setTimer(syncObjectDamage, 300, 1)
			end
			objectLossToSync[turretElement] = (objectLossToSync[turretElement] or 0) + loss
		end
	end
	cancelEvent()
end

function turretInitialization ()
	local turretParentElement = getElementByID("turretParentElement")
	respawnObject ( turretParentElement ) -- respawn the turrets if they were destroyed before the events from below are attached:
	addEventHandler("onClientObjectBreak", turretParentElement, cancelClientObjectBreak)
	addEventHandler("onClientObjectDamage", turretParentElement, cancelClientObjectDamage)
end

local processLineOfSignChecking
processLineOfSignChecking = {
	turretCheck = dataManagerConstructor:new(),
	status = false,
	timer = nil,
	func = function ()
		local turretCheck = processLineOfSignChecking.turretCheck
		if turretCheck:getNext() then
			local hasChangedStatus = {}
			local playerX, playerY, playerZ = getElementPosition(localPlayer)
			
			
			local turretCheckList = turretCheck:getAllData() -- The collection is a copy
			for i=1, #turretCheckList do
				
				local turret_ID = turretCheckList[i].key
				local turretCheckData = turretCheckList[i].value
				
				--

				local turretElement = turretCheckData.turretElement
				if isElement(turretElement) then
					
					local posX, posY, posZ = getElementPosition(turretElement)
					local currentStatus = isLineOfSightClear (
						posX, posY, posZ + 4, 
						playerX, playerY, playerZ, 
						true, -- checkBuildings
						false, -- checkVehicles
						false, -- checkPlayers
						true, -- checkObjects
						false, -- checkDummies
						true, -- seeThroughStuff 
						false -- ignoreSomeObjectsForCamera
						)  
					if turretCheckData.status ~= currentStatus then
						
						hasChangedStatus[#hasChangedStatus + 1] = {
							turret_ID = turret_ID,
							status = currentStatus
						}
						turretCheckData.status = currentStatus
					end
				else
					turretCheck:removeData(turret_ID)
				end
			end

			if hasChangedStatus[1] then
				triggerServerEvent("onPlayerInTurretInlineOfSight", resourceRoot, hasChangedStatus)
			end
		end
		if not turretCheck:getNext() and processLineOfSignChecking.status then
			if isTimer(processLineOfSignChecking.timer) then
				killTimer(processLineOfSignChecking.timer)
			end
			processLineOfSignChecking.timer = nil
			processLineOfSignChecking.status = false
		end
	end
}

addEvent("turretInlineOfSightChecking", true)
addEventHandler("turretInlineOfSightChecking", localPlayer, function (turret_ID, turretElement, checkStatus)
	
	local turretCheck = processLineOfSignChecking.turretCheck
	if turret_ID then 
		local turretCheckData = turretCheck:getData(turret_ID)
		if checkStatus then
			if not turretCheckData then
				turretCheck:setData(turret_ID, {
					status = false,
					turretElement = turretElement
				})
			else
				turretCheckData.status = false
			end
		elseif turretCheckData then
			turretCheck:removeData(turret_ID)
		end
		if turretCheck:getNext() and not processLineOfSignChecking.status then
			processLineOfSignChecking.func()
			processLineOfSignChecking.timer = setTimer(processLineOfSignChecking.func, 1500, 0)
			processLineOfSignChecking.status = true
		end
	else
		turretCheck:clear()
	end
end)

