#version 330
#pragma optionNV (unroll all)

in vec3 worldSpacePosition;
in vec3 color;
in vec3 normal;
//in vec3 tangent;

in vec3 uv;

layout(location = 0) out vec4 fragColor;
layout(location = 1) out vec4 fragData;

uniform float matSpecExponent;

const float PI = 3.14159265358979323846264;

const float P_DEPTH=2;
const int P_MAX_SAMPLES=30;
const int P_MIN_SAMPLES=5;

uniform float alpha;

const int MAX_LIGHTS = 20;
uniform int lightCount;
uniform int lightType[MAX_LIGHTS];
uniform vec3 lightPosition[MAX_LIGHTS];
uniform vec3 lightDirection[MAX_LIGHTS];
uniform vec3 lightIntensity[MAX_LIGHTS];
uniform float lightRange[MAX_LIGHTS];
uniform float lightAngle[MAX_LIGHTS];

uniform int textureCount;
uniform sampler2D texture0;
uniform sampler2D texture1;
uniform sampler2D texture2;
uniform sampler2D texture3;
uniform sampler2D texture4;
uniform sampler2D texture5;
uniform sampler2D texture6;
uniform sampler2D texture7;

uniform int fogEnabled;
uniform vec3 fogColor;
uniform float fogRange;
uniform float fogDensity;

uniform vec3 cameraWorldPos;

uniform mat4 transformationMatrix;
uniform mat4 viewMatrix;

uniform mat4 iMvp;
uniform mat4 lastMvp;

float cosTheta;

vec3 up = vec3(0,1,0);

vec3 lightingResult = vec3(0,0,0);

int i;
float lightDist=0;
vec3 lightVec;

void main() {
	vec4 modelspacepos = iMvp*gl_FragCoord;
	//modelspacepos /= modelspacepos.w;
	vec4 lastScreenSpacePos = lastMvp*modelspacepos;
	//lastScreenSpacePos.xyz /= lastScreenSpacePos.w;

	vec3 blurVector = lastScreenSpacePos.xyz - gl_FragCoord.xyz;
	
	fragData = vec4(blurVector.xy, gl_FragCoord.z, 1);

	for (i=0;i<lightCount;i++) {
		if (lightType[i]==3) {
			lightVec = worldSpacePosition-lightPosition[i];
			lightDist = length(lightVec);
			
			if (lightDist<lightRange[i]) {
				float angleDot = dot(normalize(lightDirection[i]),normalize(lightVec));
				float lightAngleCos = cos(lightAngle[i]*2*PI/360);
				if (angleDot>lightAngleCos) {
					lightingResult += lightIntensity[i] * max(1-lightDist / lightRange[i], 0);
				} else if (angleDot>lightAngleCos/1.02) {
					float fuzzFactor = 1-50*((lightAngleCos/angleDot)-1);
					lightingResult += lightIntensity[i] * max(1-lightDist / lightRange[i], 0) * fuzzFactor*fuzzFactor;//*fuzzFactor*fuzzFactor;
				}
			}
		} else if (lightType[i]==2) {
			lightVec = lightPosition[i]-worldSpacePosition;
			lightDist = length(lightVec);
			lightingResult += lightIntensity[i] * max(1-lightDist/ lightRange[i], 0);
		} else if (lightType[i]==0) {
			lightingResult += lightIntensity[i];
		} else if (lightType[i]==1) {
			cosTheta = dot(normalize(normal), -normalize(lightDirection[i]));
			
			cosTheta = (cosTheta>0 ? cosTheta : 0);
			cosTheta = (cosTheta<1 ? cosTheta : 1);
			
			lightingResult += lightIntensity[i] * cosTheta;
		}
	}


	if (textureCount==1) {
		fragColor = vec4(texture(texture0, uv.xy).xyz * lightingResult, texture(texture0, uv.xy).a*alpha);
	} else if (textureCount==0) {
		fragColor = vec4(lightingResult,alpha);// * color;
	}

	if (fogEnabled==1) {
		float dist = length(worldSpacePosition-cameraWorldPos);
		dist = 1 - dist/fogRange;
		dist = min(max(dist,0),1);

		float expterm = exp(dist * fogDensity);
		float ratio = 1.0f/(expterm*expterm);

		fragColor = vec4(fragColor.xyz*(1-ratio)+(ratio)*fogColor, fragColor.a);
		
	}
}