zmlab = zmlab or {}
zmlab.f = zmlab.f or {}
//zmlab.f.CreateNetEffect(id,data)

// Here we define diffrent effect groups which later make it pretty optimized to create Sound/Particle effects over the network
// The key will be used as the NetworkString
zmlab.NetEffectGroups = {
	["zmlab_crate_close"] = {
		_type = "entity",
		_server = true,
		action = function(ent)

			if CLIENT then
				zmlab.f.ClientAnim(ent, "close", 1)
			else
				zmlab.f.ServerAnim(ent, "close", 1)
			end
		end,
	},
	["zmlab_combiner_load_liquid"] = {
		_type = "entity",
		action = function(ent)
			zmlab.f.ParticleEffectAttach("zmlab_methylamin_fill", PATTACH_POINT_FOLLOW, ent, 1)
			ent:EmitSound("Methylamin_filling")
		end,
	},
	["zmlab_combiner_load_alum"] = {
		_type = "entity",
		action = function(ent)
			zmlab.f.ParticleEffectAttach("zmlab_aluminium_fill01", PATTACH_POINT_FOLLOW, ent, 1)
			ent:EmitSound("Aluminium_filling")
		end,
	},
	["zmlab_breakice"] = {
		action = function(pos)
			sound.Play(zmlab.GlobalSounds["zmlab_breakice"][math.random(#zmlab.GlobalSounds["zmlab_breakice"])], pos, 60, math.random(70,90), 0.5)
			zmlab.f.ParticleEffect("zmlab_meth_breaking", pos, Angle(0,0,0), Entity(1))
		end,
	},
	["zmlab_sell_small"] = {
		action = function(pos)
			zmlab.f.ParticleEffect("zmlab_sell_effect_small", pos, Angle(0,0,0), Entity(1))
		end,
	},
	["zmlab_sell_big"] = {
		action = function(pos)
			zmlab.f.ParticleEffect("zmlab_sell_effect_big", pos, Angle(0,0,0), Entity(1))
		end,
	},
	["zmlab_crate_fill"] = {
		_type = "entity",
		action = function(ent)

			zmlab.f.ParticleEffectAttach("zmlab_meth_filling", PATTACH_POINT_FOLLOW, ent, 1)
			ent:EmitSound("progress_fillingcrate")
		end,
	},
	["zmlab_crate_collect"] = {
		_type = "entity",
		action = function(ent)

			ent:EmitSound("progress_fillingcrate")
		end,
	},
	["zmlab_tray_convert"] = {
		_type = "entity",
		action = function(ent)

			ent:EmitSound("ConvertingSludge")
		end,
	},

	["zmlab_combiner_clean"] = {
		action = function(pos)
			sound.Play(zmlab.GlobalSounds["zmlab_clean"][math.random(#zmlab.GlobalSounds["zmlab_clean"])], pos, 60, math.random(90,95), 1)
			zmlab.f.ParticleEffect("zmlab_cleaning", pos, Angle(0,0,0), Entity(1))
		end,
	},

	["zmlab_aluminium_drops"] = {
		action = function(pos)
			zmlab.f.ParticleEffect("zmlab_aluminium_drops", pos, Angle(0,0,0), Entity(1))
		end,
	},
}

if SERVER then


	// Creates a network string for all the effect groups
	for k, v in pairs(zmlab.NetEffectGroups) do
		util.AddNetworkString("zmlab_fx_" .. k)
	end

	// Sends a Net Effect Msg to all clients
	function zmlab.f.CreateNetEffect(id,data)

		// Data can be a entity or position

		local EffectGroup = zmlab.NetEffectGroups[id]

		// Some events should be called on server to
		if EffectGroup._server then
			EffectGroup.action(data)
		end

		net.Start("zmlab_fx_" .. id)
		if EffectGroup._type == "entity" then
			net.WriteEntity(data)
		else
			net.WriteVector(data)
		end
		net.Broadcast()
	end

	// Animation
	function zmlab.f.ServerAnim(prop, anim, speed)
		local sequence = prop:LookupSequence(anim)
		if !sequence then return end
		prop:SetCycle(0)
		prop:ResetSequence(sequence)
		prop:SetPlaybackRate(speed)
		prop:SetCycle(0)
	end

	function zmlab.f.GenericEffect(effect,vPoint)
		local effectdata = EffectData()
		effectdata:SetStart(vPoint)
		effectdata:SetOrigin(vPoint)
		effectdata:SetScale(1)
		util.Effect(effect, effectdata)
	end
end

if CLIENT then

	// Animation
	function zmlab.f.ClientAnim(prop, anim, speed)
		local sequence = prop:LookupSequence(anim)
		if !sequence then return end
		prop:SetCycle(0)
		prop:ResetSequence(sequence)
		prop:SetPlaybackRate(speed)
		prop:SetCycle(0)
	end

	local particleEffects = GetConVar("zmlab_cl_vfx_particleeffects")
	function zmlab.f.ParticleEffect(effect, pos, ang, ent)
		if particleEffects:GetBool() then
			ParticleEffect(effect, pos, ang, ent)
		end
	end

	function zmlab.f.ParticleEffectAttach(effect, enum, ent, attachid)
		if particleEffects:GetBool() then
			ParticleEffectAttach(effect, enum, ent, attachid)
		end
	end

	for k, v in pairs(zmlab.NetEffectGroups) do
		net.Receive("zmlab_fx_" .. k, function(len)
			zmlab.f.Debug("zmlab_fx_" .. k .. " Len: " .. len)

			if v._type == "entity" then
				local ent = net.ReadEntity()

				if IsValid(ent) then

					zmlab.NetEffectGroups[k].action(ent)
				end
			else
				local pos = net.ReadVector()
				if pos then
					zmlab.NetEffectGroups[k].action(pos)
				end
			end
		end)
	end
end