/*//////////////////////////////////////////////////////////////////////////////
//    ##      #####   ######   ######     ##     ####     #######  ##  ##     //
//   ####    ##   ##  # ## #    ##  ##   ####     ##       ##   #  ##  ##     //
//  ##  ##   #          ##      ##  ##  ##  ##    ##       ## #     ####      //
//  ##  ##    #####     ##      #####   ##  ##    ##       ####      ##       //
//  ######        ##    ##      ## ##   ######    ##   #   ## #     ####      //
//  ##  ##   ##   ##    ##      ##  ##  ##  ##    ##  ##   ##   #  ##  ##     //
//  ##  ##    #####    ####    #### ##  ##  ##   #######  #######  ##  ##     //
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
//      #####   ##   ##    ##     #####    #######  ######    #####           //
//     ##   ##  ##   ##   ####     ## ##    ##   #   ##  ##  ##   ##          //
//     #        ##   ##  ##  ##    ##  ##   ## #     ##  ##  #                //
//      #####   #######  ##  ##    ##  ##   ####     #####    #####           //
//          ##  ##   ##  ######    ##  ##   ## #     ## ##        ##          //
//          ##  ##   ##  ######    ##  ##   ## #     ## ##        ##          //
//     ##   ##  ##   ##  ##  ##    ## ##    ##   #   ##  ##  ##   ##          //
//      #####   ##   ##  ##  ##   #####    #######  #### ##   #####           //
/////(BSL Shaders Edit)//////////////////////////////////////By LexBoosT//////*/

//Settings//

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

#include "/settings/globalSettings.glsl"

//Varyings//
varying vec2 texCoord;
varying vec3 sunVec, upVec;

//Fragment Shader///////////////////////////////////////////////////////////////////////////////////

#ifdef FSH

	//Uniforms//
	uniform sampler2D colortex0;
	uniform sampler2D colortex1;
	uniform sampler2D depthtex0;
	uniform sampler2D depthtex1;
	uniform sampler2D noisetex;

	uniform int frameCounter;
	uniform int isEyeInWater;

	uniform float nightVision;
	uniform float blindFactor;
	uniform float far, near;
	uniform float frameTimeCounter;
	uniform float rainStrengthS;
	uniform float screenBrightness;
	uniform float viewWidth, viewHeight, aspectRatio;

	uniform ivec2 eyeBrightnessSmooth;

	uniform vec3 cameraPosition;

	uniform mat4 gbufferProjection, gbufferProjectionInverse;
	uniform mat4 gbufferModelView, gbufferModelViewInverse;
	uniform mat4 shadowModelView;
	uniform mat4 shadowProjection;

	uniform vec3 fogColor;

	#if (defined OVERWORLD && defined LIGHT_SHAFT) || (defined END && defined LIGHT_SHAFT_END)
		uniform sampler2DShadow shadowtex0;
		uniform sampler2DShadow shadowtex1;
		uniform sampler2D shadowcolor0;
	#endif

	//Common Variables//
	float eBS = eyeBrightnessSmooth.y / 240.0;
	float sunVisibility  = clamp00125(dot( sunVec,upVec) + 0.0625) * 8.0;
	float moonVisibility = clamp00125(dot( -sunVec,upVec) + 0.0625) * 8.0;
	float screenBrightness2 = clamp01(screenBrightness);

	vec3 lightVec = sunVec * (1.0 - 2.0 * float(timeAngle > 0.5325 && timeAngle < 0.9675));

	//Common Functions//
	float GetLuminance(vec3 color){
		return dot(color,vec3(0.299, 0.587, 0.114));
	}

	float GetLinearDepth(float depth) {
		return (2.0 * near) / (far + near - depth * (far - near));
	}

	#if (defined OVERWORLD && defined LIGHT_SHAFT) || (defined END && defined LIGHT_SHAFT_END)
		float GetDepth(float depth) {
			return 2.0 * near * far / (far + near - (2.0 * depth - 1.0) * (far - near));
		}

		float GetDistX(float dist) {
			return (far * (dist - near)) / (dist * (far - near));
		}

	#endif

	//Includes//
	#if defined NETHER || defined END
	#include "/lib/color/lightColor.glsl"
	#endif

	#include "/lib/color/dimensionColor.glsl"
	#include "/lib/color/waterColor.glsl"
	#include "/lib/util/dither.glsl"
	#include "/lib/atmospherics/waterFog.glsl"
	#include "/lib/util/spaceConversion.glsl"

	#if (defined OVERWORLD && defined LIGHT_SHAFT) || (defined END && defined LIGHT_SHAFT_END)
	#include "/lib/atmospherics/volumetricLight.glsl"
	#endif

	#ifdef OUTLINE_ENABLED
	#include "/lib/color/skyColor.glsl"
	#include "/lib/color/blocklightColor.glsl"
	#include "/lib/outline/outlineOffset.glsl"
	#include "/lib/outline/outlineMask.glsl"
	#include "/lib/atmospherics/sky.glsl"
	#include "/lib/atmospherics/fog.glsl"
	#include "/lib/outline/blackOutline.glsl"
	#endif

	//Program//
	void main(){
		vec4  color      =texture2D(colortex0, texCoord);
		vec3  translucent=texture2D(colortex1,texCoord).rgb;
		vec3  worldPos   =vec3(0.0);
		float z0         =texture2D(depthtex0, texCoord).r;
		float z1         =texture2D(depthtex1, texCoord).r;

		bool water = false;

		if (translucent.b > 0.999 && z1 > z0) {
			water       = true;
			translucent = vec3(1.0);
		}

		vec4 viewPos = gbufferProjectionInverse * (vec4(texCoord, z0, 1.0) * 2.0 - 1.0);
		viewPos /= viewPos.w;

		#ifdef WATER_REFRACTION

			if (water){
				worldPos = ViewToWorld(viewPos.xyz);

				vec3 worldPosWF=worldPos.xyz + cameraPosition.xyz;
				vec2 PosRF     =worldPosWF.xz * 0.005 + worldPosWF.y * 0.0025 + 0.0045 * WATER_SPEED * frameTimeCounter;

				float hand    =1.0 - float(z0 < 0.56);
				float d0      =GetLinearDepth(z0);
				float fovScale=gbufferProjection[1][1] / 1.37;
				float ScaleWF =fovScale;

				float distScaleRF =max((far - near) * d0 + near, 14.0);
				      ScaleWF    *=2.0 / distScaleRF;

				vec2 NoiseRF =texture2D(noisetex, PosRF).rb;
					 NoiseRF.r -= 0.45;
					 NoiseRF.g -= 0.58;

				     NoiseRF*=vec2(0.07 * hand * ScaleWF);
				vec2 CoordRF =texCoord.xy + NoiseRF;

				float Wateraim=float(texture2D(colortex1, CoordRF).b > 0.999);
				float z0aim     =texture2D(depthtex0, CoordRF).r;
				float z1aim     =texture2D(depthtex1, CoordRF).r;

				float depthDif =GetLinearDepth(z1aim) - GetLinearDepth(z0aim);
				      NoiseRF *=clamp01(depthDif * 150.0);

				if (z0aim >= 0.56 && Wateraim > 0.95){

					CoordRF = texCoord.xy + NoiseRF;

					color.rgb = texture2D(colortex0, CoordRF).rgb;

				//Water Surface
					if (isEyeInWater == 1) {
						      translucent                         = texture2D(colortex1, CoordRF).rgb;
						   if (translucent.b < 0.999) translucent = vec3(1.0);
						      z0                                  = texture2D(depthtex0, CoordRF).r;
						      z1                                  = texture2D(depthtex1, CoordRF).r;
					}

				}
				/*
				Petit debug pour detecter l'eau avec la texture
				color.rgb = vec3(NoiseRF,0.0);
				*/
			}
		#endif

		#ifdef OUTLINE_ENABLED
			vec4  outerOutline=vec4(0.0), innerOutline=vec4(0.0);
			float outlineMask =GetOutlineMask();
			if (outlineMask > 0.5 || isEyeInWater > 0.5)
				Outline(color.rgb, true, outerOutline, innerOutline);

			#if PROMO_OUTLINE_EVERYWHERE > 0
				if(z1 > z0) color.rgb=mix(color.rgb, innerOutline.rgb, innerOutline.a);
			#endif
		#endif

		if (isEyeInWater == 1.0) {
			vec4 waterFog   =GetWaterFog(viewPos.xyz);
			     waterFog.a =mix(waterAlpha * 0.1, 1.0, waterFog.a);
			     color.rgb  =mix(sqrt(color.rgb), sqrt(waterFog.rgb), waterFog.a);
			     color.rgb *=color.rgb;
		}

		#ifdef LIGHT_SHAFT
			#ifdef OVERWORLD
				vec3  nViewPos = normalize(viewPos.xyz);
				float cosS     = dot(nViewPos, lightVec);
			#else
				float cosS = 0.0;
			#endif
		#endif

		#if (defined OVERWORLD && defined LIGHT_SHAFT) || (defined END && defined LIGHT_SHAFT_END)
			vec3  vlAlbedo                              = translucent;
			float dither                                =InterleavedGradientNoise();
			#if AA > 0
				dither=fract(64.0 * frameTimeCounter + dither);
			#endif
			if    (isEyeInWater == 0 && water) vlAlbedo = vec3(0.0);
			float depth0                                = GetDepth(z0);
			float depth1                                = GetDepth(z1);
			vec3 vl = getVolumetricRays(depth0, depth1, vlAlbedo, dither, cosS);
		#else
			vec3 vl = vec3(0.0);
		#endif

		#ifdef OUTLINE_ENABLED
			color.rgb = mix(color.rgb, outerOutline.rgb, outerOutline.a);
		#endif

		/*DRAWBUFFERS:01*/
		gl_FragData[0] = vec4(color);
		gl_FragData[1] = vec4(vl, 1.0);


	}

#endif

//Vertex Shader/////////////////////////////////////////////////////////////////////////////////////
#ifdef VSH

	//Uniforms//
	uniform mat4 gbufferModelView;

	//Common Variables//
	#ifdef OVERWORLD
		float timeAngleM = timeAngle;
	#else
		float timeAngleM = 0.25;
	#endif

	//Program//
	void main(){
		texCoord=gl_MultiTexCoord0.xy;

		gl_Position=ftransform();

		const vec2 sunRotationData=vec2(cos(sunPathRotation * 0.01745329251994), -sin(sunPathRotation * 0.01745329251994));
		float ang                 =fract(timeAngleM - 0.25);
		      ang                 =(ang+(cos(ang * 3.14159265358979) * -0.5 + 0.5 - ang) / 3.0) * 6.28318530717959;
		      sunVec              =normalize((gbufferModelView * vec4(vec3(-sin(ang), cos(ang) * sunRotationData) * 2000.0, 1.0)).xyz);
		      upVec				  =normalize(gbufferModelView[1].xyz);
	}

#endif
