package com.stencyl.graphics.shaders;

class BlurShader extends BasicShader
{
	public function new(radius:Float = 2.0, dirX:Float = 1.0, dirY:Float = 1.0)
	{
		super();
		
		var script = "
			#ifdef GL_ES
				precision mediump float;
			#endif
			
			//in attributes from our vertex shader
			varying vec2 vTexCoord;
			
			//declare uniforms
			uniform sampler2D uImage0;
			uniform vec2 uResolution;
			
			uniform float radius;
			uniform float dirx;
			uniform float diry;
			
			void main()
			{
				//this will be our RGBA sum
				vec4 sum = vec4(0.0);
			
				//our original texcoord for this fragment
				vec2 tc = vTexCoord;
			
				//the amount to blur, i.e. how far off center to sample from
				//1.0 -> blur by one pixel
				//2.0 -> blur by two pixels, etc.
				float blur = radius / uResolution.x;
			
				//the direction of our blur
				//(1.0, 0.0) -> x-axis blur
				//(0.0, 1.0) -> y-axis blur
				float hstep = dirx;
				float vstep = diry;
			
				//apply blurring, using a 9-tap filter with predefined gaussian weights
			
				sum += texture2D(uImage0, vec2(tc.x - 4.0*blur*hstep, tc.y - 4.0*blur*vstep)) * 0.0162162162;
				sum += texture2D(uImage0, vec2(tc.x - 3.0*blur*hstep, tc.y - 3.0*blur*vstep)) * 0.0540540541;
				sum += texture2D(uImage0, vec2(tc.x - 2.0*blur*hstep, tc.y - 2.0*blur*vstep)) * 0.1216216216;
				sum += texture2D(uImage0, vec2(tc.x - 1.0*blur*hstep, tc.y - 1.0*blur*vstep)) * 0.1945945946;
			
				sum += texture2D(uImage0, vec2(tc.x, tc.y)) * 0.2270270270;
			
				sum += texture2D(uImage0, vec2(tc.x + 1.0*blur*hstep, tc.y + 1.0*blur*vstep)) * 0.1945945946;
				sum += texture2D(uImage0, vec2(tc.x + 2.0*blur*hstep, tc.y + 2.0*blur*vstep)) * 0.1216216216;
				sum += texture2D(uImage0, vec2(tc.x + 3.0*blur*hstep, tc.y + 3.0*blur*vstep)) * 0.0540540541;
				sum += texture2D(uImage0, vec2(tc.x + 4.0*blur*hstep, tc.y + 4.0*blur*vstep)) * 0.0162162162;
			
				//discard alpha for our simple demo, multiply by vertex color and return
				gl_FragColor = vec4(sum.rgb, 1.0);
			}
		";
	
		model = new PostProcess(this, script, true);
		
		setRadius(radius);
		setDirectionX(dirX);
		setDirectionY(dirY);
	}
	
	public function setRadius(amount:Float)
	{
		setProperty("radius", amount);
	}
	
	public function setDirectionX(amount:Float)
	{
		setProperty("dirx", amount);
	}
	
	public function setDirectionY(amount:Float)
	{
		setProperty("diry", amount);
	}
}