--[[
	
	██╗  ██╗██████╗ ██╗   ██╗██████╗ ████████╗ ██████╗     ███████╗██╗  ██╗██████╗ ██╗   ██╗██████╗ ████████╗
	██║ ██╔╝██╔══██╗╚██╗ ██╔╝██╔══██╗╚══██╔══╝██╔═══██╗    ██╔════╝██║ ██╔╝██╔══██╗╚██╗ ██╔╝██╔══██╗╚══██╔══╝
	█████╔╝ ██████╔╝ ╚████╔╝ ██████╔╝   ██║   ██║   ██║    ███████╗█████╔╝ ██████╔╝ ╚████╔╝ ██████╔╝   ██║   
	██╔═██╗ ██╔══██╗  ╚██╔╝  ██╔═══╝    ██║   ██║   ██║    ╚════██║██╔═██╗ ██╔══██╗  ╚██╔╝  ██╔═══╝    ██║   
	██║  ██╗██║  ██║   ██║   ██║        ██║   ╚██████╔╝    ███████║██║  ██╗██║  ██║   ██║   ██║        ██║   
	╚═╝  ╚═╝╚═╝  ╚═╝   ╚═╝   ╚═╝        ╚═╝    ╚═════╝     ╚══════╝╚═╝  ╚═╝╚═╝  ╚═╝   ╚═╝   ╚═╝        ╚═╝   
	
	Source: https://forum.facepunch.com/f/gmoddev/oaxt/Blue-s-Masks-and-Shadows/
	
--]]

local RenderTarget = GetRenderTarget( "bshadows_original", ScrW(), ScrH() )
local RenderTarget2 = GetRenderTarget( "bshadows_shadow", ScrW(), ScrH() )

local ShadowMaterial = CreateMaterial( "bshadows", "UnlitGeneric", {
	
	[ "$translucent" ] = 1,
	[ "$vertexalpha" ] = 1,
	[ "alpha" ] = 1
	
} )

local ShadowMaterialGrayscale = CreateMaterial( "bshadows_grayscale", "UnlitGeneric",{
	
	[ "$translucent" ] = 1,
	[ "$vertexalpha" ] = 1,
	[ "$alpha" ] = 1,
	[ "$color" ] = "0 0 0",
	[ "$color2" ] = "0 0 0"
	
} )

function KS.BeginShadow()
	
	render.PushRenderTarget( RenderTarget )
	render.OverrideAlphaWriteEnable( true, true )
	render.Clear( 0, 0, 0, 0 )
	render.OverrideAlphaWriteEnable( false, false )
	
	cam.Start2D()
	
end

function KS.EndShadow( Intensity, Spread, Blur, Opacity, Direction, Distance, ShadowOnly )
	
	Opacity = Opacity or 255
	Direction = Direction or 0
	Distance = Distance or 0
	ShadowOnly = ShadowOnly or false
	
	render.CopyRenderTargetToTexture( RenderTarget2 )
	
	if Blur > 0 then
		
		render.OverrideAlphaWriteEnable( true, true )
		render.BlurRenderTarget( RenderTarget2, Spread, Spread, Blur )
		render.OverrideAlphaWriteEnable( false, false )
		
	end
	
	render.PopRenderTarget()
	
	ShadowMaterial:SetTexture( "$basetexture", RenderTarget )
	ShadowMaterialGrayscale:SetTexture( "$basetexture", RenderTarget2 )
	
	local xOffset = math.sin( math.rad( Direction ) ) * Distance
	local yOffset = math.cos( math.rad( Direction ) ) * Distance
	
	ShadowMaterialGrayscale:SetFloat( "$alpha", Opacity / 255 )
	
	render.SetMaterial( ShadowMaterialGrayscale )
	
	for i = 1 , math.ceil( Intensity ) do
		
		render.DrawScreenQuadEx( xOffset, yOffset, ScrW(), ScrH() )
		
	end
	
	if not ShadowOnly then
		
		ShadowMaterial:SetTexture( "$basetexture", RenderTarget )
		
		render.SetMaterial( ShadowMaterial )
		render.DrawScreenQuad()
		
	end
	
	cam.End2D()
	
end

function KS.DrawShadowTexture( Texture, Intensity, Spread, Blur, Opacity, Direction, Distance, ShadowOnly )
	
	Opacity = Opacity or 255
	Direction = Direction or 0
	Distance = Distance or 0
	ShadowOnly = ShadowOnly or false
	
	render.CopyTexture( Texture, RenderTarget2 )
	
	if Blur > 0 then
		
		render.PushRenderTarget( RenderTarget2 )
		render.OverrideAlphaWriteEnable( true, true )
		render.BlurRenderTarget( RenderTarget2, Spread, Spread, Blur )
		render.OverrideAlphaWriteEnable( false, false )
		render.PopRenderTarget()
		
	end
	
	ShadowMaterialGrayscale:SetTexture( "$basetexture", RenderTarget2 )
	
	local xOffset = math.sin( math.rad( Direction ) ) * Distance
	local yOffset = math.cos( math.rad( Direction ) ) * Distance
	
	ShadowMaterialGrayscale:SetFloat( "$alpha", Opacity / 255 )
	
	render.SetMaterial( ShadowMaterialGrayscale )
	
	for i = 1 , math.ceil( Intensity ) do
		
		render.DrawScreenQuadEx( xOffset, yOffset, ScrW(), ScrH() )
		
	end
	
	if not ShadowOnly then
		
		ShadowMaterial:SetTexture( "$basetexture", Texture )
		
		render.SetMaterial( ShadowMaterial )
		render.DrawScreenQuad()
		
	end
	
end