
Ambience 					= Ambience or {}
Ambience.ActiveSounds 		= Ambience.ActiveSounds or {}
Ambience.Running 			= false
Ambience.AmbientData 		= {}
Ambience.StreetData 		= {}
Ambience.StreetLexika 		= {}
Ambience.ScreenVehicleData	= {}
Ambience.SoundData			= {
	["*"] = {
		"rustsurvival/ambient/a_interior_generic_loop.wav"
	}
}
Ambience.Music = {
	Wanted = {
		"music/hl2_song3.mp3",
		"music/hl2_song4.mp3",
		"music/hl2_song6.mp3",
		"music/hl2_song29.mp3",
		"music/hl2_song16.mp3",
		"music/hl1_song10.mp3",
		"music/hl2_song20_submix0.mp3",
	},
	Normal = {
		"music/hl2_song31.mp3",
		"music/hl1_song11.mp3",
		"music/hl2_song14.mp3",
		"music/hl2_song12_long.mp3",
		"music/hl1_song25_remix3.mp3",
		"music/hl2_song31.mp3",
		"music/hl1_song17.mp3",
		"music/hl2_song8.mp3",
	},
	Weird = {
		"music/hl2_song13.mp3",
		"music/hl2_song17.mp3",
		"music/hl2_song30.mp3",
		"music/hl1_song15.mp3",
		"music/hl2_song32.mp3",
		"music/hl2_song33.mp3",
		"music/hl2_song19.mp3",
	},
}
Ambience.ActiveMusicTheme = 0
Ambience.Fresh = true
Ambience.CurrentRegion 		= ""
Ambience.CurrentZone		= ""

Ambience.RenderedStreetID 	= -1
Ambience.DownloadCount = 0

Ambience.CurrentStreetID = 0
Ambience.ClosestNodeData = nil
Ambience.ClosestNode = Vector(0,0,0)
Ambience.ClosestNodeDistance = 600000

Ambience.GraphData			 = {}
Ambience.ScapeData			 = {}
Ambience.WorldZ = 0

AMBIENCE_PACKET_AMBIENT		= 0
AMBIENCE_PACKET_STREET 		= 1
AMBIENCE_PACKET_LEXIKA 		= 2
AMBIENCE_PACKET_SVDATA 		= 3
AMBIENCE_PACKET_SCAPE 		= 4
AMBIENCE_PACKET_GRAPH 		= 5

if SERVER then AddCSLuaFile() end
if CLIENT then
	local PANEL = {}
	function PANEL:Init()
		
		self:SetSize( 24, 24 )
		self:NoClipping( true )
		
		self.imgPanel = vgui.Create( "DImage", self );
		self.imgPanel:SetImage( "icon16/script.png" );
		self.imgPanel:SetSize( 16, 16 )
		self.imgPanel:SetPos( 4, 4 )
		
		self.imgPanel:SetAlpha( 30 )
		
		self.BoxW = 0
		self.BoxH = 0
		
	end
	function PANEL:SetUp( name )

		local ext = string.GetExtensionFromFilename( name );
		
		if ( ext == "data" ) then 
			self.imgPanel:SetImage( "icon16/script.png" );
		/*elseif ( ext == "vtf" ) then 
			self.imgPanel:SetImage( "icon16/palette" );
		elseif ( ext == "mdl" ) then 
			self.imgPanel:SetImage( "icon16/brick_add" );
		elseif ( ext == "wav" ) then 
			self.imgPanel:SetImage( "icon16/sound" );*/
		end
		
		self.imgPanel:AlphaTo( 255, 0.2, 0 )

	end
	function PANEL:Update( f, status, name, size )

		self.status = status
		self.f = f;
		self.size = size
		
		if ( self.name != name ) then
			
			self:SetUp( name )
			self.name = name
			
		end

	end
	function PANEL:Think()

		if ( self.Bouncing ) then
		
			local ft = FrameTime() * 20
			
			self.yvel = self.yvel + 2.0 * ft
			self.xvel = math.Approach( self.xvel, 0.0, ft * 0.01 )
			
			self.xpos = self.xpos + self.xvel * ft * 3
			self.ypos = self.ypos + self.yvel * ft * 3
			
			if ( self.ypos > (ScrH() - 24) ) then
			
				self.ypos = (ScrH() - 24)
				self.yvel = self.yvel * -0.6
				self.xvel = self.xvel * 0.8
			
			end
			
			self:SetPos( self.xpos, self.ypos )
		
		end

	end
	function PANEL:Paint()

		local r = 255 - 255 * self.f
		local g = 255
		local b = 255 - 255 * self.f
		local a = self.imgPanel:GetAlpha()
		
		if ( self.f == 1.0 && !self.Bouncing ) then
		
			r = 255
			g = 55 + math.Rand( 0, 200 )
			b = 5
		
		end
		
		if ( self.DownloadFailed ) then
			r = 255
			g = 50
			b = 50
		end
		
		draw.RoundedBox( 4, 0, 0, self:GetWide(), self:GetTall(), Color( 20, 20, 20, a * 0.4 ) )
		draw.RoundedBox( 4, 1, 1, self:GetWide()-2, self:GetTall()-2, Color( r, g, b, a * 0.7 ) )

		// If the file is bigger than 3MB, give us some info.
		if ( self.f < 1.0 && self.size > (1024 * 1024 * 3) ) then
			self:DrawSizeBox( a )
		end

	end
	function PANEL:DrawSizeBox( a )

		local x = (self.BoxW - self:GetWide()) * -0.5
		local txt = math.Round( self.f * 100, 2 ) .."% of ".. string.NiceSize( self.size )

		self.BoxW, self.BoxH = draw.WordBox( 4, x, self.BoxH * -1.1, txt, "DefaultSmall", Color( 50, 55, 60, a * 0.8 ), Color( 255, 255, 255, a ) )

	end
	function PANEL:Bounce()

		local x, y = self:LocalToScreen( 0, 0 )
		self:SetParent( GetHUDPanel() )
		self:SetPos( x, y )
		
		self.Bouncing = true
		
		self.xvel = math.random( -12, 12 )
		self.yvel = math.random( -20, -10 )
		
		self.xpos = x
		self.ypos = y
		
		self.imgPanel:AlphaTo( 0, 1, 1 )

	end
	function PANEL:Failed()
		self.DownloadFailed = true;
	end
	vgui.Register( "GM12_DContentDownload", PANEL, "DPanel" )
	local PANEL = {}
	function PANEL:Init()
		
		self:SetSize( 256, 100 )
		self:SetPos( 0, ScrH() + 10 )
		self:SetZPos( 100 )
		
	end
	function PANEL:Think()

		self:SetParent(GetHUDPanel())
		
		if ( self.LastActivity && (SysTime() - self.LastActivity) > 2 ) then
		
			self:MoveTo( self.x, ScrH() + 5, 0.5, 0.5 )
			self.LastActivity = nil;
			self.MaxFileCount = 0
			
		end
		
		for k, v in pairs( Downloads ) do
		
			local x = (self:GetWide() * 0.5) + math.sin( SysTime() + k*-0.43  ) * self:GetWide() * 0.45
			local y = (20) + math.cos( SysTime() + k*-0.43  ) * 20 * 0.5
			v:SetPos( x-13, y )
			v:SetZPos( y )
			
			v.accel = accel;
		
		end

	end
	function PANEL:OnActivity( dlt )

		if ( self.LastActivity == nil ) then
			self:MoveTo( self.x, ScrH() - self:GetTall() + 20, 0.1 )
		end

		self.LastActivity = SysTime()

	end
	function PANEL:PerformLayout()

		self:CenterHorizontal()

	end
	function PANEL:Add( p )

		local x, y = self:GetPos()
		local ypos = math.random( 20, 25 )

	end
	vgui.Register( "GM12_DContentMain", PANEL, "Panel" )
	if(Main) then Main:Remove() end
	Downloads = {}
	local Main = nil

	function UpdatePackageDownloadStatus( id, name, f, status, size )

		if ( !Main ) then
			Main = vgui.Create("GM12_DContentMain")
		end

		local dl = Downloads[ id ]
		
		if ( dl == nil ) then
		
			dl = vgui.Create( "GM12_DContentDownload", Main )
			dl.Velocity = Vector( 0, 0, 0 );
			dl:SetAlpha(255)
			Downloads[ id ] 	= dl
			Main:Add( dl )
			
		end
		
		dl:Update( f, status, name, size );
		
		if ( status == "success" ) then
			
			dl:Bounce()
			Downloads[ id ] = nil
			surface.PlaySound( "hl1/fvox/fuzz.wav" ) 
			
			timer.Simple( 2, function() 
									dl:Remove() 
							end )
		end
		
		if ( status == "failed" ) then
			
			dl:Failed()
			Downloads[ id ] = nil
			surface.PlaySound( "hl1/fvox/buzz.wav" ) 
			
			timer.Simple( 2, function() 
									dl:Remove() 
							end )
		end
		
		Main:OnActivity( Downloads )

	end
	/*
	Ende Toybox Download Boxen
	*/

	Ambience.CEnabled = CreateClientConVar( "soundmaster_enabled","1",true,false,"Should the Soundmaster be on?")
	cvars.AddChangeCallback("soundmaster_enabled",function(cvar,old,new)
		if old == "0" and new == "1" then
			Ambience.Fresh = true
		end
		if old == "1" and new == "0" then
			Ambience.Stop()
		end
	end)

	Ambience.CDebugEnabled = CreateClientConVar( "soundmaster_debug_enabled","0",true,false,"Debug Only for Developer Job")
	Ambience.splodesprite = Material("sprites/light_glow04")
	Ambience.DebugTexture = Material("dev/dev_materialmodify")
	function Ambience.ClosestLineIntersection(a,b,p)
		local AP = p - a
		local AB = b - a
		
		local magnitudeAB = AB:LengthSqr()
		local ABAPproduct = AP:Dot(AB)
		local distance = ABAPproduct / magnitudeAB
		if distance < 0 then
			return a, (distance*AB):LengthSqr()
		elseif distance > 1 then
			return b, (distance*AB):LengthSqr()
		else
			return a + AB * distance , (distance*AB):LengthSqr()
		end
		return Vector(0,0,0),23456789
	end
	function Ambience.IsInRegion(regionRect)
		local lp = LocalPlayer():EyePos()
		local rs = regionRect.Start
		local re = regionRect.End
		if 	lp.x >= re.x and lp.x <= rs.x and
			lp.y >= re.y and lp.y <= rs.y and
			lp.z >= rs.z and lp.z <= re.z
		then 
			return true
		end
		return false
	end
	function Ambience.GetMusic()
		if(Ambience.ActiveMusicTheme == 0) then return Ambience.Music.Normal[math.random(0,#Ambience.Music.Normal-1)] end
		if(Ambience.ActiveMusicTheme == 1) then return Ambience.Music.Weird[math.random(0,#Ambience.Music.Weird-1)] end
		if(Ambience.ActiveMusicTheme == 2) then return Ambience.Music.Wanted[math.random(0,#Ambience.Music.Wanted-1)] end
	end
	function Ambience.Think()
		if Ambience.Fresh == true then
			Ambience.Fresh = false
			if Ambience.CEnabled:GetBool() == true then
				local delayedStart = false
				/*if Ambience.ActiveMusic then
					Ambience.ActiveMusic:ChangeVolume(0,2)
					timer.Simple(2,function() 
					Ambience.ActiveMusic:Stop() 
					Ambience.ActiveMusic = nil
				end) end*/
				if Ambience.ActiveSounds and table.Count(Ambience.ActiveSounds) > 0 then
					Ambience.Stop()
					delayedStart = true
				end
				local function timedStart()
					if LocalPlayer() and IsValid(LocalPlayer()) then Ambience.Init() end
					hook.Add("Initalize","Ambience.Init",Ambience.Init)
					net.Receive("MapData.Request",function(len)
						Ambience.Init()
					end)
				end
				if delayedStart then timer.Simple(2.3,timedStart) else timedStart() end
			end
		end
		if Ambience.Running == false then return end
		
		Ambience.ClosestNodeDistance = 600000
		if Ambience.AmbientData then
			local MapData = Ambience.AmbientData
			Ambience.ScapeDatas = nil
			Ambience.CurrentRegion	= ""
			Ambience.CurrentZone	= -1
			for _,regionName in pairs(MapData) do
				for __,regionRect in pairs(regionName) do
					local xc = (255 / table.Count(regionName)) * __
					local c = Color(255*xc,255 - (255*xc),0,20)
					if Ambience.IsInRegion(regionRect) then
						Ambience.CurrentRegion	= _
						Ambience.CurrentZone	= __
					end
				end
			end
			if Ambience.AmbientData[Ambience.CurrentRegion] and Ambience.AmbientData[Ambience.CurrentRegion][Ambience.CurrentZone] then
				Ambience.ScapeDatas = Ambience.AmbientData[Ambience.CurrentRegion][Ambience.CurrentZone].Scape
			end
			for scapeName,snd in pairs(Ambience.ActiveSounds) do
				if not Ambience.CheckConditions(scapeName) or not Ambience.ScapeDatas or not Ambience.ScapeDatas[scapeName] then
					Ambience.FadeOut(scapeName)
				end
			end
			if Ambience.ScapeDatas then
				for _,scapeName in pairs(Ambience.ScapeDatas) do
					if Ambience.CheckConditions(scapeName) then
						Ambience.FadeIn(scapeName)
					end
				end
			end
			--Ambience.SetStatus("Region="..Ambience.CurrentRegion,1)
			--Ambience.SetStatus("Zone="..Ambience.CurrentZone,3)
		end
		if Ambience.StreetData and LocalPlayer():InVehicle() then
			local lpPos = LocalPlayer():GetPos()
			local traceRes = util.TraceLine({
				start = lpPos,
				endpos = lpPos - Vector(0,0,2000),
				mask = MASK_SOLID_BRUSHONLY,
				filter = LocalPlayer()
			})
			Ambience.WorldZ = traceRes.Hit and traceRes.HitPos.z or Ambience.WorldZ
			local StreetData = Ambience.StreetData
			local StreetLexika = Ambience.StreetLexika
			local lpp = Vector(lpPos.x,lpPos.y,0)
			for _,node in pairs(StreetData) do
				local z = LocalPlayer():GetPos().z
				local intersects, distance = Ambience.ClosestLineIntersection(node.Start,node.End,lpp)
				if Vector(node.Start.x,node.Start.y,0):Distance(lpp) > 512 and Vector(node.End.x,node.End.y,0):Distance(lpp) > 512 and intersects:Distance(lpp) > 512 then continue end
				local la1 = node.Start:Distance(lpp) < node.End:Distance(lpp) and node.Start or node.End
				local la2 = node.Start:Distance(lpp) > node.End:Distance(lpp) and node.Start or node.End
				la1 = LerpVector(0.5,la1,la2)
				
				local intersects, distance = Ambience.ClosestLineIntersection(la1,la2,lpp)
				local distA = Ambience.ClosestNode:Distance(intersects)
				local distB = intersects:Distance(lpp)
				--MsgN(_ .. "=DistA="..math.Round(distA).." DistB="..math.Round(distB))
				if Ambience.ClosestNode and distA > distB and Ambience.CurrentStreetID != node.StreetID then
					--MsgN(distA.." < ".. distB .. " changing to ".. (Ambience.StreetLexika[node.StreetID] or ""))
					Ambience.ClosestNodeData = node
					Ambience.ClosestNode = intersects
					Ambience.ClosestNodeDistance = distance
					Ambience.CurrentStreetID = node.StreetID
				end
			end
			if Ambience.ClosestNodeData then
				--PrintTable(Ambience.ClosestNodeData.ConnectedWith or {})
			end
		end
		if Ambience.ActiveSounds then
			local u = 0
			for i,k in pairs(Ambience.ActiveSounds) do
				if k.fade then
					u=u+1
					if k.targetFade > 0 then
						if not k.Sound then
							--MsgN("Creating "..i)
							Ambience.CreateSound(i,k)
							if Ambience.ActiveSounds[i] == nil then
								continue 
							end
						end
						if k.Sound and k.Sound:IsPlaying() == false then 
							k.Sound:ChangeVolume(0,0)
							k.Sound:Play()
							--MsgN("Playing "..i)
						end
					else 
						if k.Sound and k.Sound:IsPlaying() == true then 
							k.Sound:Stop()
							k.Sound = nil
							--MsgN("Destroying "..i)
						end
					end
					--Ambience.SetStatus("Vol["..math.Round(k.targetFade,2).."] =  "..i,u)
					if k.Sound then
						k.Sound:ChangeVolume(k.targetFade*(k.volume or 1)*(LocalPlayer():InVehicle() and 0.5 or 1),0)
					end
					Ambience.ActiveSounds[i].targetFade = Lerp(0.002*FrameTime(),Ambience.ActiveSounds[i].fade,Ambience.ActiveSounds[i].targetFade)
				end
			end
		end
		/*if not Ambience.ActiveMusic then
			local pth = Ambience.GetMusic()
			MsgN("playing Music "..pth)
			Ambience.ActiveMusic = CreateSound(game.GetWorld(),pth)
			Ambience.ActiveMusic:SetSoundLevel(0)
			Ambience.ActiveMusic:ChangeVolume(0,0)
			Ambience.ActiveMusic:Play()
			Ambience.ActiveMusic:ChangeVolume(0.2,5)
		end
		if Ambience.ActiveMusic and Ambience.ActiveMusic:IsPlaying() == false then
			Ambience.ActiveMusic = nil
		end*/
	end
	function Ambience.DebugDeep(status,scape)
		Ambience.ActiveSounds[scape].debug = status
	end
	function Ambience.CheckConditions(scapeName)
		if not Ambience.ActiveSounds[scapeName] then MsgN(scapeName.." doesnt exists, reutrning false") return false end
		if Ambience.ActiveSounds[scapeName].cond == true then return true end
		local weather = SW.GetCurrentWeather() and (SW.GetCurrentWeather().ID or "none") or "none"
		local catastrophicWeather = (weather == "rain" or weather == "storm" or weather == "blizzard")
		local rainyWeather = (weather == "rain" or weather == "storm")
		for i,k in pairs(Ambience.ActiveSounds[scapeName].cond) do
			if k == "SW.Day" and (SW.Time > 20.5 or SW.Time < 4) then Ambience.DebugDeep('SW.Day',scapeName) return false end
			if k == "SW.Night" and (SW.Time < 20 and SW.Time > 4.5) then Ambience.DebugDeep('SW.Night',scapeName) return false end
			if k == "SW.DryWeather" and catastrophicWeather then Ambience.DebugDeep('SW.DryWeather',scapeName) return false end
			if k == "SW.InVehicle" and not LocalPlayer():InVehicle() then Ambience.DebugDeep('SW.InVehicle',scapeName) return false end
			if k == "!SW.InVehicle" and LocalPlayer():InVehicle() then Ambience.DebugDeep('!SW.InVehicle',scapeName) return false end
			if k == "SW.RainWeather" and not rainyWeather then Ambience.DebugDeep('SW.RainWeather',scapeName) return false end
			if k == "SW.WindWeather" and not catastrophicWeather then Ambience.DebugDeep('SW.WindWeather',scapeName) return false end
		end
		Ambience.DebugDeep("True",scapeName) 
		return true
	end
	function Ambience.Node(_,node,ps)
		if not LocalPlayer():InVehicle() then return end
		local lpPos = LocalPlayer():GetVehicle():GetPos()
		local rotPl = LocalPlayer():GetVehicle():GetAngles().yaw
		local rr = 90+45
		local rot = Angle(0,EyeAngles().yaw-90,90)
		local pos = Vector(ps.x,ps.y,Ambience.WorldZ)
		rot:SnapTo("y",30)
		--if Ambience.RenderedStreetID[node.StreetID] then return false end
		--Ambience.RenderedStreetID[node.StreetID] = true
		local cc = Vector(ps.x,ps.y,0):Distance(Vector(lpPos.x,lpPos.y,0)) <= (512+256)
		--cam.Start3D2D(pos,rot,1)
		--	draw.SimpleText(Ambience.StreetLexika[node.StreetID].."[".._.."]","DermaLarge",0,-60,MF4Config.MainColor,0,1)
		--cam.End3D2D()
	end
	function Ambience.DrawGPSInt(w,h)
		surface.SetDrawColor(80,80,80)
		surface.DrawRect(0,0,w,h)
		surface.SetDrawColor(255,0,0)
		surface.DrawLine(0,20,50,80)
		if Ambience.StreetData then
			local txt = Ambience.StreetLexika[Ambience.CurrentStreetID] or "-"
			surface.SetFont("matf4_job")
			local tw,th = surface.GetTextSize(txt)
			draw.SimpleText(txt,"matf4_job",w/2,h-th*2,color_white,1,1)
		end
	end
	Ambience.GPSRenderTarget = nil
	Ambience.GPSRenderTargetMat = nil
	function Ambience.DrawGPS(w,h)
		Ambience.GPSRenderTarget = GetRenderTarget("gps",w,h,false)
		local Scrw,Scrh = ScrW(),ScrH()
		
		render.PushRenderTarget(Ambience.GPSRenderTarget)
		cam.Start2D()
		--render.OverrideAlphaWriteEnable(true, true)
		Ambience.DrawGPSInt(w,h)
		cam.End2D()
		render.PopRenderTarget()
		
		if not Ambience.GPSRenderTargetMat then
			Ambience.GPSRenderTargetMat = CreateMaterial("gpsrt","UnlitGeneric",{
				["$basetexture"] = Ambience.GPSRenderTarget
			})
		end

		if Ambience.GPSRenderTargetMat then
			surface.SetDrawColor(255,255,255)
			surface.SetMaterial(Ambience.GPSRenderTargetMat)
			surface.DrawTexturedRect(0,0,w,h)
		else
			surface.SetDrawColor(255,0,0)
			surface.DrawRect(0,0,w,h)
		end
	end
	function Ambience.Debug(hud)
		if Ambience.Running == false then return end
		if LocalPlayer() and LocalPlayer():InVehicle() and Ambience.ScreenVehicleData and Ambience.ScreenVehicleData[LocalPlayer():GetVehicle():GetModel()] then
			local veh = LocalPlayer():GetVehicle()
			local data = Ambience.ScreenVehicleData[veh:GetModel()]
			--MsgN(veh:WorldToLocal(LocalPlayer():GetEyeTrace().HitPos))
			--MsgN(veh:WorldToLocalAngles((LocalPlayer():EyePos() - LocalPlayer():GetEyeTrace().HitPos):Angle()))
			cam.Start3D2D(veh:LocalToWorld(data.lp),veh:LocalToWorldAngles(data.la),0.025)
				Ambience.DrawGPS(data.w,data.h)
			cam.End3D2D()
			--MsgN(LocalPlayer():GetVehicle():GetModel())
		end
		if Ambience.StreetData and not hud and LocalPlayer():InVehicle() then
			--render.SetColorMaterial()
			local StreetData = Ambience.StreetData
			local StreetLexika = Ambience.StreetLexika
			local lpPos = LocalPlayer():GetPos()
			local z = LocalPlayer():GetPos().z
			local rotPl = LocalPlayer():GetAngles().yaw
			Ambience.RenderedStreetID = {}
			for _,node in pairs(StreetData) do
				if Vector(node.Start.x,node.Start.y,drawZS):Distance(LocalPlayer():GetPos()) > 4000 and Vector(node.End.x,node.End.y,drawZS):Distance(LocalPlayer():GetPos()) > 4000 then continue end
				if Vector(node.Start.x,node.Start.y,0):Distance(Vector(lpPos.x,lpPos.y,0)) <= 4000 then
					Ambience.Node(_,node,Ambience.ClosestLineIntersection(node.Start,node.End,Vector(lpPos.x,lpPos.y,0)))
					--render.DrawLine(Vector(node.Start.x,node.Start.y,Ambience.WorldZ),Vector(node.End.x,node.End.y,Ambience.WorldZ),Ambience.CurrentStreetID == node.StreetID and Color(200,0,0) or Color(0,255,255),false)
				end
			end
		end
		if (LocalPlayer():Team() == TEAM_DEV or GetHostName() == "Garry's Mod") and Ambience.CDebugEnabled:GetInt() > 0 then // or LocalPlayer():SteamID() == "STEAM_0:1:46594887" then
			if table.Count(Ambience.ActiveSounds) > 0 then
				surface.SetFont("TargetID")
				local _ignore,fontH = surface.GetTextSize("0")
				local extraLines = 1 + (Ambience.ScapeDatas and (1 + table.Count(Ambience.ScapeDatas)) or 0)
				local w,h,y = 420,fontH*table.Count(Ambience.ActiveSounds) + fontH*extraLines,0
				local x = ScrW()-w
				surface.SetDrawColor(80,80,80,120)
				surface.DrawRect(x,y,w,h)
				surface.SetDrawColor(255,255,255,255)
				local function txt(x,y,str)
					surface.SetTextPos(x,y*fontH)
					surface.DrawText(type(str) == "string" and str or tostring(str))
				end
				local yy = 1
				surface.SetTextColor(255,255,255,255)
				txt(x+0,0,"Name:")
				txt(x+190,0,"F|T:")
				txt(x+220,0,"Cond:")
				txt(x+270,0,"DCond:")
				for scapeName,scapeData in pairs(Ambience.ActiveSounds) do
					if scapeData.Sound then surface.SetTextColor(0,255,0,255) else surface.SetTextColor(255,0,0,255) end
					txt(x,yy,scapeName)
					txt(x + 190,yy,scapeData.fade or 0)
					surface.SetTextColor(91,113,255,255)
					txt(x + 205,yy,scapeData.targetFade or 0)
					local condRes = Ambience.CheckConditions(scapeName)
					if condRes then surface.SetTextColor(0,255,0,255) else surface.SetTextColor(255,0,0,255) end
					txt(x + 220,yy,condRes and "True" or "False")
					if scapeData.debug then
						surface.SetTextColor(91,113,255,255)
						txt(x + 270,yy,tostring(scapeData.debug))
					end
					yy = yy + 1
				end
				txt(x+0,yy,"Current Scapes: ")
				yy = yy + 1
				if Ambience.ScapeDatas then
					for _,NME in pairs(Ambience.ScapeDatas) do
						txt(x+0,yy,NME)
						yy = yy + 1
					end
				end
			end
			if Ambience.AmbientData and 3 > 2 then
				if not hud then
					render.SetColorMaterial()
					render.OverrideDepthEnable(true,true)
					render.CullMode(MATERIAL_CULLMODE_CW)
					render.SetColorMaterial()
					render.SetLightingMode(2)
					render.SetBlend(1)
				end
				local MapData = Ambience.AmbientData
				for _,regionName in pairs(MapData) do
					for __,regionRect in pairs(regionName) do
						if not hud and  Ambience.CDebugEnabled:GetInt() == 2 then
							local xc = (255 / table.Count(regionName)) * __
							local c = Color(255*xc,255 - (255*xc),0,255)
							if not Ambience.IsInRegion(regionRect) then
								Ambience.CurrentRegion	= _
								Ambience.CurrentZone	= __
								render.DrawBox(regionRect.Start,Angle(0,0,0),Vector(0,0,0),Vector(regionRect.End.x - regionRect.Start.x,regionRect.End.y - regionRect.Start.y,regionRect.End.z - regionRect.Start.z),c)
								render.CullMode(MATERIAL_CULLMODE_CW)
								render.DrawBox(regionRect.Start,Angle(0,0,0),Vector(0,0,0),Vector(regionRect.End.x - regionRect.Start.x,regionRect.End.y - regionRect.Start.y,regionRect.End.z - regionRect.Start.z),c)
							
								render.DrawLine(regionRect.Start,Vector(regionRect.Start.x,regionRect.Start.y,regionRect.End.z),Color(255,255,0))
								render.DrawLine(regionRect.End,Vector(regionRect.End.x,regionRect.End.y,regionRect.Start.z),Color(0,255,255))
							end
						end
						if hud and Ambience.IsInRegion(regionRect) then
							draw.SimpleText("REGION=".._.."/"..__,"DermaLarge",ScrW()/2,ScrH()/2 + 80,color_white,1,1)
							break
						end
					end
				end
				if not hud then
					render.CullMode(MATERIAL_CULLMODE_CCW)
					render.OverrideDepthEnable(false,false)
					render.SetLightingMode(0)
					render.SetBlend(1)
				end
			end
		end
	end
	function Ambience.SetStatusLoading(txt)
		MsgN("[Clean Ambience]"..txt)
		notification.AddProgress("Ambience.SetStatusLoading","[Clean Ambience]"..txt)
	end
	function Ambience.SetStatus(txt,u)
		--MsgN("[Ambient]"..txt)
		notification.AddProgress("Ambience.SetStatusLoading"..tostring(u or ""),"[Clean Ambience]"..txt)
		--GAMEMODE:AddNotify(txt,NOTIFY_GENERIC,5)
	end
	function Ambience.Stop()
		Ambience.DownloadCount = 0
		Ambience.Running = false
		Ambience.SetStatus("Gestoppt")
		for i,k in pairs(Ambience.ActiveSounds) do
			if IsValid(k.Sound) then k.Sound:Stop() end
		end
		//if IsValid(Ambience.ActiveMusic) then Ambience.ActiveMusic:Stop() end
		timer.Simple(10,function()
			if not Ambience.Running then 
				notification.Kill("Ambience.SetStatusLoading")
			end
		end)
	end
	function Ambience.Init()
		Ambience.DownloadCount = 0
		for i=0,10 do notification.Kill("Ambience.SetStatusLoading"..tostring(i)) end
		if Ambience.LastInit and Ambience.LastInit + 1 >= CurTime() then return end
		Ambience.LastInit 			= CurTime()
		Ambience.GraphData	 		= {}
		Ambience.AmbientData 		= {}
		Ambience.StreetData 		= {}
		Ambience.StreetLexika 		= {}
		net.Receive("MapData.MapPacketHeader",function(len)
			Ambience.DownloadCount = net.ReadInt(32)
			for i=1,Ambience.DownloadCount do
				UpdatePackageDownloadStatus(i,"", 0,"",1)
			end
		end)
		net.Receive("MapData.MapPacket",function(len)
			local packetsRemain = net.ReadInt(32)
			UpdatePackageDownloadStatus(packetsRemain,"", 1,"success",1)
			Ambience.SetStatusLoading("Lade Daten ["..packetsRemain.." verbleibend]")
			local packetType = net.ReadInt(32)
			local packetData = net.ReadTable()
			if packetType == AMBIENCE_PACKET_AMBIENT then table.Merge(Ambience.AmbientData,packetData) end
			if packetType == AMBIENCE_PACKET_STREET then table.Merge(Ambience.StreetData,packetData) end
			if packetType == AMBIENCE_PACKET_LEXIKA then table.Merge(Ambience.StreetLexika,packetData) end
			if packetType == AMBIENCE_PACKET_SVDATA then table.Merge(Ambience.ScreenVehicleData,packetData) end
			if packetType == AMBIENCE_PACKET_SCAPE then table.Merge(Ambience.ScapeData,packetData) end
			if packetType == AMBIENCE_PACKET_GRAPH then table.Merge(Ambience.GraphData,packetData) end
			if packetsRemain == 0 then
				Ambience.SetStatus("Starte Client")
				notification.Kill("Ambience.SetStatusLoading")
				timer.Simple(1,function()
					Ambience.Start()
					notification.AddLegacy("[Clean Ambience]".."Aktiv",NOTIFY_HINT,2)
				end)
			end
		end)
		net.Start("MapData.Request")
		net.SendToServer()
		Ambience.SetStatus("Initialisiere")
	end
	function Ambience.GetSoundIndex(index)
		return index
	end
	function Ambience.FadeIn(id)
		Ambience.ActiveSounds[Ambience.GetSoundIndex(id)].fade = 1
	end
	function Ambience.FadeOut(id)
		Ambience.ActiveSounds[Ambience.GetSoundIndex(id)].fade = 0
	end
	function Ambience.CreateSound(index,data)
		local snd = CreateSound(game.GetWorld(),type(data.path) == "string" and data.path or table.Random(data.path))
		MsgN("Spawning Sound "..index)
		snd:SetSoundLevel(0)
		snd:ChangeVolume(0,0)
		Ambience.ActiveSounds[Ambience.GetSoundIndex(index)] = {path=data.path,Sound=snd,fade=data.fade or 0,targetFade=data.targetFade or 0,volume=data.volume or 1,cond = data.cond or true}
	end
	function Ambience.Start()
		//Ambience.ActiveMusic = nil
		Ambience.Running = true
		RunConsoleCommand("play","garrysmod/save_load4.wav")
		notification.Kill("Ambience.SetStatusLoading")
		for i,k in pairs(Ambience.ScapeData) do
			Ambience.ActiveSounds[Ambience.GetSoundIndex(i)] = {path=k.path,Sound=nil,fade=0,targetFade=0,volume=k.volume or 1,cond = k.cond or true}
		end
	end
	hook.Add("Think","Ambience.Think",Ambience.Think)
	hook.Add("PostDrawOpaqueRenderables","Ambience.Debug",function() Ambience.Debug(false) end)
	hook.Add("HUDPaint","Ambience.Debug",function() Ambience.Debug(true) end)
	hook.Add("Initalize","Ambience.Debug",function() Ambience.Init() end)
end