#include "/lib/util/reprojection.glsl"

#ifdef TAA_VERSION_1
	vec2 neighbourhoodOffsets[8] =  vec2[8](vec2(-1.0, -1.0),
											vec2( 0.0, -1.0),
											vec2( 1.0, -1.0),
											vec2(-1.0,  0.0),
											vec2( 1.0,  0.0),
											vec2(-1.0,  1.0),
											vec2( 0.0,  1.0),
											vec2( 1.0,  1.0)
											);
	const int numOffsets = 8;
#endif

#ifdef TAA_VERSION_2
	vec2 neighbourhoodOffsets[25] = vec2[25] (vec2(2.0, 2.0),
											  vec2(1.0, 2.0),
											  vec2(0.0, 2.0),
											  vec2(-1.0, 2.0),
											  vec2(-2.0, 2.0),
											  vec2(2.0, 1.0),
											  vec2(1.0, 1.0),
											  vec2(0.0, 1.0),
											  vec2(-1.0, 1.0),
											  vec2(-2.0, 1.0),
											  vec2(2.0, 0.0),
											  vec2(1.0, 0.0),
											  vec2(0.0, 0.0),
											  vec2(-1.0, 0.0),
											  vec2(-2.0, 0.0),
											  vec2(2.0, -1.0),
											  vec2(1.0, -1.0),
											  vec2(0.0, -1.0),
											  vec2(-1.0, -1.0),
											  vec2(-2.0, -1.0),
											  vec2(2.0, -2.0),
											  vec2(1.0, -2.0),
											  vec2(0.0, -2.0),
											  vec2(-1.0, -2.0),
											  vec2(-2.0, -2.0)
											  );
	const int numOffsets=25;
#endif

		void NeighbourhoodClamping(vec3 color, inout vec3 tempColor, vec2 view, float depth, inout float edge) {
			vec3 minclr = color, maxclr = color;

			for(int i = 0; i < numOffsets; i++) {
				vec2 offset = neighbourhoodOffsets[i] * view;
				float depthCheck = textureLod(depthtex1, texCoord + offset, 0.0).r;
				if (abs(GetLinearDepth(depthCheck) - GetLinearDepth(depth)) > 0.03) edge = 1.0;
				vec3 clr = textureLod(colortex1, texCoord + offset, 0.0).rgb;
				minclr = min(minclr, clr); maxclr = max(maxclr, clr);
			}

			tempColor = clamp(tempColor, minclr, maxclr);
		}

		void TAA(inout vec3 color, inout vec4 temp) {
			float depth = textureLod(depthtex1, texCoord, 0.0).r;
			float noTAA = textureLod(colortex7, texCoord, 0.0).r;
			if (depth < 0.56 || noTAA > 0.5) {
				return;
			}

			vec3 coord = vec3(texCoord, depth);
			vec2 prvCoord = Reprojection(coord);

			vec2 view = vec2(viewWidth, viewHeight);
			vec3 tempColor = textureLod(colortex2, prvCoord, 0.0).gba;
			if (tempColor == vec3(0.0)) {
				temp = vec4(temp.r, color);
				return;
			}

			float edge = 0.0;
			NeighbourhoodClamping(color, tempColor, 1.0 / view, depth, edge);

			vec2 velocity = (texCoord - prvCoord.xy) * view;

			float blendFactor = float(prvCoord.x > 0.0 && prvCoord.x < 1.0 &&
									prvCoord.y > 0.0 && prvCoord.y < 1.0);

		#ifdef TAA_VERSION_1
			float a = 0.5;
			float b = 0.4;
			float c = 0.2;
		#endif

		#ifdef TAA_VERSION_2
			float a = 0.3;
			float b = 0.6;
			float c = 0.6;
		#endif

		float lengthVelocity =clamp(1.0-sqrt(length(velocity))/1.999, 0.0, 1.0);
		blendFactor *= max(exp(-lengthVelocity) * a + b - lengthVelocity * edge * 20.0, c) ;
		color = mix(color, tempColor, blendFactor);
		temp = vec4(temp.r, color);
	}