varying vec2 		texcoord;
varying vec2 		texcoord1;

uniform sampler2D 	bg,
					bmp,
					tex,
					depthBG;
uniform samplerCube	ambientCube;

varying vec4 		pos;
varying vec4		eyepos;
uniform vec2		density;
uniform vec3		refrColor;
uniform vec3		diffuseColor;
uniform vec3		ambientColor;
uniform float		transparency;

#ifdef DECAL
	uniform vec4		coordMod;
	uniform float		alphaLevel;
#endif

#ifdef BUMP2

	varying vec2 		texcoord2;
	uniform sampler2D 	bmp1;

#endif

#ifdef PSYSTEM

	varying float 	life;
	//varying vec4 	posDir;
	
#else

	// SHADOWMAP PARAMS
	uniform sampler2DShadow 	shadowmap;
	uniform sampler2DShadow 	shadowmap2;
	uniform sampler2DShadow 	shadowmap4;
	uniform sampler2DShadow 	shadowmap8;

	uniform float 		lightrange;
	uniform float 		lightrange2;
	uniform float 		lightrange4;
	uniform float 		lightrange8;
		
	uniform int 		split4;
	uniform int 		split8;

	uniform float		cOfs;

	uniform vec4		LTM0,
						LTM1,
						LTM2,
						LTM3;

	uniform vec4		LTM0b,
						LTM1b,
						LTM2b,
						LTM3b;

	uniform vec4		LTM0c,
						LTM1c,
						LTM2c,
						LTM3c;

	uniform vec4		LTM0d,
						LTM1d,
						LTM2d,
						LTM3d;
	//////////////////////////////////////////

	uniform vec3		lightDir;
	//uniform float		lightscale;
	uniform vec4		lightcolor;

	#ifdef CUBEREFL
		uniform samplerCube	reflCube;
		uniform float		reflScale;
		uniform float		reflPow;
		uniform vec4 		reflColorMul;
	#endif

/*	varying vec3		w0,
						w1,
						w2;*/
	varying mat3		TBN;
	varying vec3		viewDir;
	
	uniform vec2 		spec;
	uniform vec2		fresnel;
	varying vec4 		vpos;

#endif

///////// LIGHTS ////////////////////////
uniform float 		light0;
uniform vec3 		lightpos0;
uniform vec3 		lightdir0;
uniform float 		lightCos0;
uniform vec3 		lightColor0;
uniform float 		lightRange0;
uniform float 		lightfallof0;

uniform float 		light1;
uniform vec3 		lightpos1;
uniform vec3 		lightdir1;
uniform float 		lightCos1;
uniform vec3 		lightColor1;
uniform float 		lightRange1;
uniform float 		lightfallof1;
///////////////////////////////////////////

//varying vec4		fog;
varying vec3 		Fex;
varying vec3 		Lin;
float				Pi=3.14159265359;

vec4 refl=vec4(0.0,0.0,0.0,0.0);
float reflInt=0.0;
vec3 litColor=vec3(0.0,0.0,0.0);
vec3 diffuse=vec3(0.0,0.0,0.0);
vec4 texColor;
float shadowOcc;
float lightDist;
	
vec4 normalColor;
	
vec3 ComputeSunLight(vec3 N, vec3 vdir, vec3 ldir)
{
	#ifdef PSYSTEM
		return vec3(0.0,0.0,0.0);
	#else
	
		//vec3 diffuse=vec3(0.0,0.0,0.0);

		// SHADOW MAP CODE
		vec4	XYproj;	
		shadowOcc=1.0;
		vec3 projcoords;
				
		if( -eyepos.z/lightrange <= 1.0 )
		{
			// COMPUTE LIGHT TEXTURE PROJECTION + ATTENUATION
			XYproj.x = dot(eyepos,LTM0);
			XYproj.y = dot(eyepos,LTM1);
			XYproj.z = dot(eyepos,LTM2);
			XYproj.w = dot(eyepos,LTM3);

			projcoords.xy=XYproj.xy;
			projcoords.z=XYproj.z-0.00005;
			///////////////////////////////////

			float dOfs = cOfs*0.5;
			shadowOcc=0.0;

			vec3 shadowcoords;
			shadowcoords.z=projcoords.z;

			shadowcoords.xy=projcoords.xy+vec2(-dOfs,dOfs);
			shadowOcc+=shadow2D(shadowmap,shadowcoords).r;

			shadowcoords.xy=projcoords.xy+vec2(dOfs,dOfs);
			shadowOcc+=shadow2D(shadowmap,shadowcoords).r;

			shadowcoords.xy=projcoords.xy+vec2(dOfs,-dOfs);
			shadowOcc+=shadow2D(shadowmap,shadowcoords).r;

			shadowcoords.xy=projcoords.xy+vec2(-dOfs,-dOfs);
			shadowOcc+=shadow2D(shadowmap,shadowcoords).r;
			
			shadowOcc *= 0.25;
		}
		else
		{	
			if( -eyepos.z/lightrange2 <= 1.0 )
			{
				// COMPUTE LIGHT TEXTURE PROJECTION + ATTENUATION
				XYproj.x = dot(eyepos,LTM0b);
				XYproj.y = dot(eyepos,LTM1b);
				XYproj.z = dot(eyepos,LTM2b);
				XYproj.w = dot(eyepos,LTM3b);

				projcoords.xy=XYproj.xy;
				projcoords.z=XYproj.z-0.0004;
				///////////////////////////////////

				float dOfs = cOfs*0.5;
				shadowOcc=0.0;

				vec3 shadowcoords;
				shadowcoords.z=projcoords.z;

				shadowcoords.xy=projcoords.xy+vec2(-dOfs,dOfs);
				shadowOcc+=shadow2D(shadowmap2,shadowcoords).r;

				shadowcoords.xy=projcoords.xy+vec2(dOfs,dOfs);
				shadowOcc+=shadow2D(shadowmap2,shadowcoords).r;

				shadowcoords.xy=projcoords.xy+vec2(dOfs,-dOfs);
				shadowOcc+=shadow2D(shadowmap2,shadowcoords).r;

				shadowcoords.xy=projcoords.xy+vec2(-dOfs,-dOfs);
				shadowOcc+=shadow2D(shadowmap2,shadowcoords).r;
				
				shadowOcc *= 0.25;
				
				/*float lrangeMin=lightrange2-200.0;
				shadowOcc=mix(shadowOcc,1.0,( clamp( (-eyepos.z-lrangeMin)/(lightrange2-lrangeMin),0.0,1.0) ));*/
			}
			else
			{
				if( -eyepos.z/lightrange4 <= 1.0 )
				{
					// COMPUTE LIGHT TEXTURE PROJECTION + ATTENUATION
					XYproj.x = dot(eyepos,LTM0c);
					XYproj.y = dot(eyepos,LTM1c);
					XYproj.z = dot(eyepos,LTM2c);
					XYproj.w = dot(eyepos,LTM3c);

					projcoords.xy=XYproj.xy;
					projcoords.z=XYproj.z-0.0006;
					///////////////////////////////////

					float dOfs = cOfs*0.5;
					shadowOcc=0.0;

					vec3 shadowcoords;
					shadowcoords.z=projcoords.z;

					shadowcoords.xy=projcoords.xy+vec2(-dOfs,dOfs);
					shadowOcc+=shadow2D(shadowmap4,shadowcoords).r;

					shadowcoords.xy=projcoords.xy+vec2(dOfs,dOfs);
					shadowOcc+=shadow2D(shadowmap4,shadowcoords).r;

					shadowcoords.xy=projcoords.xy+vec2(dOfs,-dOfs);
					shadowOcc+=shadow2D(shadowmap4,shadowcoords).r;

					shadowcoords.xy=projcoords.xy+vec2(-dOfs,-dOfs);
					shadowOcc+=shadow2D(shadowmap4,shadowcoords).r;
				
					shadowOcc *= 0.25;
					
					float lrangeMin=lightrange4-300.0;
					shadowOcc=mix(shadowOcc,1.0,( clamp( (-eyepos.z-lrangeMin)/(lightrange4-lrangeMin),0.0,1.0) ));
				}
				/*else
				{
					if( -eyepos.z/lightrange8 <= 1.0 )
					{
						if(split8==1)
						{
							// COMPUTE LIGHT TEXTURE PROJECTION + ATTENUATION
							XYproj.x = dot(eyepos,LTM0d);
							XYproj.y = dot(eyepos,LTM1d);
							XYproj.z = dot(eyepos,LTM2d);
							XYproj.w = dot(eyepos,LTM3d);

							projcoords.xy=XYproj.xy;
							projcoords.z=XYproj.z-0.002;
							///////////////////////////////////

							float dOfs = cOfs*0.5;
							shadowOcc=0.0;

							vec3 shadowcoords;
							shadowcoords.z=projcoords.z;

							shadowcoords.xy=projcoords.xy+vec2(-dOfs,dOfs);
							shadowOcc+=shadow2D(shadowmap8,shadowcoords).r;

							shadowcoords.xy=projcoords.xy+vec2(dOfs,dOfs);
							shadowOcc+=shadow2D(shadowmap8,shadowcoords).r;

							shadowcoords.xy=projcoords.xy+vec2(dOfs,-dOfs);
							shadowOcc+=shadow2D(shadowmap8,shadowcoords).r;

							shadowcoords.xy=projcoords.xy+vec2(-dOfs,-dOfs);
							shadowOcc+=shadow2D(shadowmap8,shadowcoords).r;
					
							shadowOcc *= 0.25;
								
							float lrangeMin=lightrange8-1000.0;
							shadowOcc=mix(shadowOcc,1.0,( clamp( (-pos.z-lrangeMin)/(lightrange8-lrangeMin),0.0,1.0) ));
						}
					}
				}*/
			}
		}
		////////////////////////////////////////
		
		float specular=0.0;
			
	/*	if( -eyepos.z < 4000.0 )	
		{
			if( -eyepos.z < 2000.0 )
			{*/
				if(shadowOcc>0.0)
				{
					/*vec3 halfv = normalize(ldir+vdir);
					specular = clamp(dot(halfv, N.xyz),0.0,1.0);
					specular = pow(specular,spec.x)*spec.y;*/
					float S=fresnel.y*normalColor.a;
					if(S>0.0)	// specular reflectance (fresnel)
					{
						vec3 H = normalize(ldir+vdir);
						float NdotH = (dot(H,N.xyz));
						float EdotH = dot(vdir,H);
						float NdotE = dot(N.xyz,vdir);
						float NdotL = dot(ldir,N.xyz);
						float F=0.1+0.9*pow((1.0-EdotH),5.0);
						specular=max((0.0397436*S+0.0856832)*(F*pow(NdotH,S)/max(NdotL,NdotE)),0.0);
					}					
				}
		//	}
			diffuse = diffuseColor*transparency*clamp(dot(N,ldir),0.0,1.0)/Pi*0.9;
	//	}
		
		return (diffuse+specular)*lightcolor.rgb*shadowOcc;
		
	#endif
}

vec3 ComputeLight(vec3 N, vec3 vdir, vec3 lpos, vec3 lcolor, float lrange, float light, vec3 lightdir, float lcos, float fallof)
{
	#ifdef PSYSTEM
		return vec3(0.0,0.0,0.0);
	#else
		
		if(light>1.0)
		{
			/*vec4	XYproj;	
			vec3 	projcoords;
			XYproj.x = dot(eyepos,LTM0);
			XYproj.y = dot(eyepos,LTM1);
			XYproj.z = dot(eyepos,LTM2);
			XYproj.w = dot(eyepos,LTM3);
			projcoords.xyz=XYproj.xyz/XYproj.w;
			float att=clamp(1.0 - XYproj.z/lrange,0.0,1.0)*step(0.0,XYproj.z);
			vec3 projcolor=texture2D(tex,projcoords.xy).xyz*att;*/

			float specular = 0.0;
			vec3 ldir=lpos-vpos.xyz;
			lightDist=length(ldir)/lrange;
			if(lightDist<=1.0)
			{
				ldir=normalize(ldir);
				float cos=dot(lightdir,ldir);
				float angAtt=clamp(1.0 - (1.0-cos)/(1.0-lcos),0.0,1.0);
				float linAtt=clamp(1.0 - lightDist,0.0,1.0);
				float att=min(1.0,linAtt*angAtt*fallof);

				/*if( -eyepos.z < 4000.0 )
				{
					diffuse = clamp(dot(N,ldir),0.0,1.0)*diffuseColor*transparency;
					vec3 halfv = normalize(ldir+vdir);
					specular = clamp(dot(halfv, N.xyz),0.0,1.0);
					specular = pow(specular,spec.x)*spec.y;
				}*/
				diffuse = clamp(dot(N,ldir),0.0,1.0)*diffuseColor*transparency;	
				diffuse/=Pi;
				diffuse*=0.9;
				
				float S=fresnel.y*normalColor.a;
				if(S>0.0)	// specular reflectance (fresnel)
				{
					vec3 H = normalize(ldir+vdir);
					float NdotH = (dot(H,N.xyz));
					float EdotH = dot(vdir,H);
					float NdotE = dot(N.xyz,vdir);
					float NdotL = dot(ldir,N.xyz);
					float F=0.1+0.9*pow((1.0-EdotH),5.0);
					specular=max((0.0397436*S+0.0856832)*(F*pow(NdotH,S)/max(NdotL,NdotE)),0.0);
				}					
				return (diffuse+specular)*lcolor*att;
			}
		}
		else
		{
			float specular = 0.0;
			vec3 ldir=lpos-vpos.xyz;
			lightDist=length(ldir)/lrange;
			if(lightDist<=1.0)
			{
				ldir=normalize(ldir);
				float att= clamp((1.0 - lightDist)*fallof,0.0,1.0);
				/*if( -eyepos.z < 4000.0 )
				{
					diffuse = clamp(dot(N,ldir),0.0,1.0)*diffuseColor*transparency;
					vec3 halfv = normalize(ldir+vdir);
					specular = clamp(dot(halfv, N.xyz),0.0,1.0);
					specular = pow(specular,spec.x)*spec.y;
				}*/
				diffuse = clamp(dot(N,ldir),0.0,1.0)*diffuseColor*transparency;	
				diffuse/=Pi;
				diffuse*=0.9;
				
				float S=fresnel.y*normalColor.a;
				if(S>0.0)	// specular reflectance (fresnel)
				{
					vec3 H = normalize(ldir+vdir);
					float NdotH = (dot(H,N.xyz));
					float EdotH = dot(vdir,H);
					float NdotE = dot(N.xyz,vdir);
					float NdotL = dot(ldir,N.xyz);
					float F=0.1+0.9*pow((1.0-EdotH),5.0);
					specular=max((0.0397436*S+0.0856832)*(F*pow(NdotH,S)/max(NdotL,NdotE)),0.0);
				}					
				return (diffuse+specular)*lcolor*att;
			}
		}
		return vec3(0.0,0.0,0.0);
	#endif
}

void main()
{
	normalColor=texture2D(bmp,texcoord1.st);
	vec3 normal=normalize((normalColor.xyz*2.0)-1.0);
	vec3 background;
	vec3 ambient;
	texColor=texture2D(tex,texcoord.st);
	//vec3 specular;//=texColor.rgb*ambientColor;

#ifdef BUMP2

	vec4 normalColor1=texture2D(bmp1,texcoord2.st);
	vec3 normal1=(normalColor1.xyz*2.0)-1.0;
	vec3 normal2=normal;
	normal=(normal2+normal1)*0.5;
	normal=normalize(normal);

#endif

	vec2 UV=(pos.xy/pos.w)*0.5+0.5;
	float depth=texture2D(depthBG,UV).z;
	
	#ifdef PSYSTEM

		UV+=normal.xy*density.x;
		float alpha=( clamp( (life-0.2) * 5.0,0.0,1.0) );
		texColor.a*=alpha;
		UV=clamp(UV,0.0,1.0);
		ambient=texture2D(bg,UV*0.25).rgb;
		
	#else
			
		vec3 N;
		vec3 vdir;
			
		N=TBN*normal;
		N=normalize(N);
		float E=fresnel.y*0.00390625*normalColor.a;
		vdir=normalize(viewDir);	
		
		UV+=normal.xy*density.x;
		UV=clamp(UV,0.0,1.0);
		float dist=(clamp(abs(depth-eyepos.z)*density.y,0.0,1.0));
		background=mix(texture2D(bg,UV*0.25).rgb,refrColor,dist);
			
		//glossColor*=textureCubeLod(ambientCube,N.xyz,6.0).xyz;
		vec3 reflection = reflect(vdir,N);
		vec4 specularAmb = textureCubeLod(ambientCube,reflection.xyz,(1.0-E)*7.0);
		
		vec4 diffuseAmb=textureCubeLod(ambientCube,N.xyz,6.0);	
		ambient=ambientColor.rgb*mix(texColor.rgb*diffuseColor.rgb*diffuseAmb.rgb, specularAmb.rgb/*reflColorMul.rgb*/, E);
			
	//	#ifdef CUBEREFL
		//	vec3 reflection = reflect(vdir,N);
			
		//		reflInt=clamp(pow(1.0-abs(dot(N,vdir)),fresnel.x),0.0,1.0)*reflPow;
		//		refl=textureCubeLod(ambientCube,reflection.xyz)*reflScale*reflColorMul;
	//	#endif
		
		vec3 lit=ComputeSunLight(N, vdir, lightDir);
		litColor += lit;
		
		#ifdef DECAL
		#else
		//	glossColor += diffuse*lit;
				
			if(light0>0.0)
			{
				lit=ComputeLight(N, vdir, lightpos0, lightColor0, lightRange0, light0, lightdir0, lightCos0, lightfallof0);
				litColor += lit;
			//	glossColor += diffuse*lit;
				if(light1>0.0)
				{
					lit=ComputeLight(N, vdir, lightpos1, lightColor1, lightRange1, light1, lightdir1, lightCos1, lightfallof1);
					litColor += lit;
			//		glossColor += diffuse*lit;
				}
			}
		#endif
		
	#endif	
		
	#ifdef PSYSTEM
		gl_FragColor.rgb=max(ambient,0.0);
	#else
	
		vec3 finalColor= litColor.rgb+ambient.rgb;
		finalColor=mix(background,finalColor,texColor.a);
		//finalColor=Fex*finalColor + Lin;
		
//		vec3 finalColor=/*mix(*/litColor.xyz + ambient.xyz/*,refl.xyz,reflInt)*/;
		#ifdef DECAL
		#else
//			finalColor=mix(finalColor,glossColor,texColor.a);
		#endif
			finalColor=finalColor*Fex+Lin;
			gl_FragColor.rgb=max(finalColor,0.0);
	#endif
	
	#ifdef DECAL
		gl_FragColor.a=max(texColor.a*coordMod.x*alphaLevel,0.0);
	#else
		gl_FragColor.a=1.0;//texColor.a;
	#endif
}
