if (not CLIENT) then return end
local lasttraceEnt = nil
local lastTrace = 0
local trace
local traceEnt
local lastCoveyorBelt
local zrmine_Halotable = {}
local zrmine_InserterEndPartTable = {}
local zrmine_HaloLookTable = {}
local zrmine_MineConnectedResourceTable = {}
local zrmine_MainModuleHalo = {}

hook.Add("PreDrawHalos", "zrmine_AddHalos", function()
	if (CurTime() > (lastTrace or 1)) then
		lastTrace = CurTime() + GetConVar("zrms_cl_highlight_refreshrate"):GetFloat()
		trace = LocalPlayer():GetEyeTrace()
		traceEnt = trace.Entity
	end

	if (LocalPlayer():GetPos():Distance(trace.HitPos) > 200) then
		-- Disables the Info if we are too far away
		if (IsValid(lastCoveyorBelt)) then
			lastCoveyorBelt.ShowInfo = false
			lastCoveyorBelt = nil
		end

		return
	end

	-- Disables the Info if we dont look at the same ent again
	if (IsValid(lastCoveyorBelt) and traceEnt ~= lastCoveyorBelt) then
		lastCoveyorBelt.ShowInfo = false
		lastCoveyorBelt = nil
	end

	-- If the Player is not the owner of the prop then stop
	if (not zrmine.f.IsOwner(LocalPlayer(), traceEnt)) then return end

	if (zrmine.config.SharedOwnership and zrmine.f.IsAdmin(LocalPlayer()) == false) then return end

	-- Enables Conveyorbelt Info
	if (IsValid(traceEnt) and (string.sub(traceEnt:GetClass(), 1, 17) == "zrms_conveyorbelt" or string.sub(traceEnt:GetClass(), 1, 13) == "zrms_inserter" or string.sub(traceEnt:GetClass(), 1, 13) == "zrms_splitter" or string.sub(traceEnt:GetClass(), 1, 11) == "zrms_sorter") and traceEnt:GetBuildMode() == false) then
		lastCoveyorBelt = traceEnt
		lastCoveyorBelt.ShowInfo = true
	end

	if GetConVar("zrms_cl_highlight"):GetInt() == 0 then return end
	if (not IsValid(traceEnt)) then return end

	if (traceEnt ~= lasttraceEnt) then
		table.Empty(zrmine_Halotable)
		table.Empty(zrmine_InserterEndPartTable)
		table.Empty(zrmine_HaloLookTable)
		table.Empty(zrmine_MineConnectedResourceTable)
		table.Empty(zrmine_MainModuleHalo)
		lasttraceEnt = traceEnt

		-- Adds Conveyorbelt MainModule Halo
		if (traceEnt:GetClass() == "zrms_conveyorbelt_n" and traceEnt:GetBuildMode() == true) then
			table.insert(zrmine_MainModuleHalo, traceEnt)
		end

		-- Adds Mine Connected Ore Look Halo
		if (string.sub(traceEnt:GetClass(), 1, 22) == "zrms_mineentrance_base" and traceEnt:GetCurrentState() == "CLOSED") then
			table.insert(zrmine_MineConnectedResourceTable, traceEnt)
		end

		-- Adds Conveyorbelt Look Halo
		if (string.sub(traceEnt:GetClass(), 1, 17) == "zrms_conveyorbelt" or string.sub(traceEnt:GetClass(), 1, 13) == "zrms_inserter" or string.sub(traceEnt:GetClass(), 1, 13) == "zrms_splitter" or string.sub(traceEnt:GetClass(), 1, 11) == "zrms_sorter" and traceEnt:GetBuildMode() == false) then
			table.insert(zrmine_HaloLookTable, traceEnt)
		end

		-- Adds Conveyorbelt Halo
		if (string.sub(traceEnt:GetClass(), 1, 17) == "zrms_conveyorbelt" and traceEnt:GetHasChild() == false and traceEnt:GetBuildMode() == false) then
			table.insert(zrmine_Halotable, traceEnt)
		end

		-- Adds Minecart Halo
		if (traceEnt:GetClass() == "zrms_minecart" and traceEnt:GetParent():GetCurrentState() == "WAITING_FOR_ORDER") then
			table.insert(zrmine_Halotable, traceEnt)
		end

		-- Adds Basket Halo
		if (traceEnt:GetClass() == "zrms_basket" and traceEnt:GetInUse() and traceEnt:GetParent():GetCurrentState() == "WAITING_FOR_ORDER") then
			table.insert(zrmine_Halotable, traceEnt)
		end

		-- Adds refiner Halo
		if (string.sub(traceEnt:GetClass(), 1, 12) == "zrms_refiner" and traceEnt:GetCurrentState() == "WAITING_FOR_ORDER" and traceEnt:GetHasChild() == false and traceEnt:GetBuildMode() == false) then
			table.insert(zrmine_Halotable, traceEnt)
		end

		-- Adds Crusher Halo
		if (string.sub(traceEnt:GetClass(), 1, 12) == "zrms_crusher" and traceEnt:GetCurrentState() == "WAITING_FOR_ORDER" and traceEnt:GetHasChild() == false and traceEnt:GetBuildMode() == false) then
			table.insert(zrmine_Halotable, traceEnt)
		end

		-- Adds Splitter Halo
		if (string.sub(traceEnt:GetClass(), 1, 11) == "zrms_sorter" and traceEnt:GetCurrentState() == "WAITING_FOR_ORDER" and not traceEnt:GetHasChild() and not traceEnt:GetBuildMode()) then
			table.insert(zrmine_Halotable, traceEnt)
		end

		-- Adds Splitter Halo
		if (string.sub(traceEnt:GetClass(), 1, 13) == "zrms_splitter" and traceEnt:GetCurrentState() == "WAITING_FOR_ORDER" and not traceEnt:GetHasChild() and not traceEnt:GetBuildMode()) then
			table.insert(zrmine_Halotable, traceEnt)
		end

		-- Adds Inserter Halo
		if (string.sub(traceEnt:GetClass(), 1, 13) == "zrms_inserter") then
			if (traceEnt:GetHasChild() == false and traceEnt:GetBuildMode() == false) then
				table.insert(zrmine_Halotable, traceEnt)
			end

			if (traceEnt:GetInserterEndPart() ~= -1) then
				for k, v in pairs(ents.GetAll()) do
					if (v:EntIndex() == traceEnt:GetInserterEndPart()) then
						table.insert(zrmine_InserterEndPartTable, v)
					end
				end
			end
		end
	end

	if (table.Count(zrmine_HaloLookTable) > 0) then
		halo.Add(zrmine_HaloLookTable, Color(255, 255, 255, 25), 1, 1, 1, true, true)
	end

	if (table.Count(zrmine_InserterEndPartTable) > 0) then
		halo.Add(zrmine_InserterEndPartTable, Color(72, 205, 229), 3, 3, 2, true, true)
	end

	if (table.Count(zrmine_Halotable) > 0) then
		halo.Add(zrmine_Halotable, Color(87, 229, 72), 3, 3, 2, true, true)
	end

	if (table.Count(zrmine_MineConnectedResourceTable) > 0) then
		halo.Add(zrmine_MineConnectedResourceTable, Color(87, 229, 72), 4, 4, 0, true, true)
	end

	if (table.Count(zrmine_MainModuleHalo) > 0) then
		halo.Add(zrmine_MainModuleHalo, Color(87, 72, 229), 3, 3, 2, true, true)
	end
end)
