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

//Settings//
#include "/lib/settings.glsl"

//Varyings//
varying float mat;

varying vec2 texCoord,lmCoord;

varying vec4 color;
varying vec4 position;


#ifdef SHADOW_BACKFACE_CULLING
varying vec3 normal;
#endif

//Fragment Shader///////////////////////////////////////////////////////////////////////////////////
#ifdef FSH

//Uniforms//
uniform int isEyeInWater;
uniform int blockEntityId;

uniform vec3 fogColor;
uniform vec3 cameraPosition;

uniform sampler2D tex;
uniform sampler2D noisetex;
uniform float shadowFade;
uniform float rainStrength;
uniform float rainStrengthS;
uniform float frameTimeCounter;
uniform int worldTime;
//Common Variables//

//Includes//
#include "/lib/color/waterColor.glsl"
#include "/lib/util/dither.glsl"

#ifdef WATER_CAUSTICS
#ifdef OVERWORLD
#include "/lib/lighting/caustics.glsl"
#endif
#endif

//Common Functions//
void doWaterShadowCaustics(inout vec4 albedo, float dither){
	#if defined(OVERWORLD)&&defined WATER_CAUSTICS
	vec3 worldPos=position.xyz+cameraPosition.xyz;
	worldPos*=0.5;
	float noise=0.0;
	float mult=0.5;
	
	vec2 wind=vec2(frameTimeCounter)*0.3;
	float verticalOffset=worldPos.y*0.2;
	
	if(mult>0.01){
		float numberRays=UNDERWATER_LIGHTSHAFT_SIZE;
		float lacunarity=1.0/numberRays, persistance=1.0, weight=0.0;
		
		mult*=(lmCoord.y*0.9+0.1);
		
		for(int i=0;i<8;i++){
			float windSign=mod(i,2)*2.0-1.0;
			vec2 noiseCoord=worldPos.xz+wind*windSign-verticalOffset;
			if(i<7)noise+=texture2D(noisetex,noiseCoord*lacunarity).r*persistance;
			else{
				noise+=texture2D(noisetex,noiseCoord*lacunarity*0.150).r*persistance*10.0;
				noise=-noise;
				float noisePlus=1.0+0.125 * -noise;
				noisePlus*=noisePlus;
				noisePlus*=noisePlus;
				noise*=noisePlus;
			}
			
			if(i==0)noise = -noise;
			
			weight+=persistance;
			lacunarity*=1.50;
			persistance*=0.60;
		}
		noise*=mult/weight;
	}
	#ifdef SHADOW_COLOR
		float discardFactor=0.025;
		if(noise>discardFactor || noise < -discardFactor)discard;
	#else
		float noiseFactor=1.1+noise;
		noiseFactor=pow(noiseFactor,10.0);
	if (noiseFactor > 1.0 - dither * 0.5) discard;
	#endif
	#else
	discard;
	#endif
}

//Program//
void main(){
	#if MC_VERSION>=11300
	if(blockEntityId==10250)discard;
	#endif

	vec4 albedo = texture2D(tex, texCoord.xy);

	albedo.rgb*=color.rgb;
	
	float dither = Bayer64(gl_FragCoord.xy);

	float premult = float(mat > 0.95 && mat < 1.05);
	float water   = float(mat > 1.95 && mat < 2.05);
	float ice     = float(mat > 2.95 && mat < 3.05);
	
	#ifdef SHADOW_COLOR
		if (water > 0.5) {
			if (isEyeInWater < 0.5) { 
				albedo = vec4(0.0, 0.0, 0.0, 1.0);
			} else {
				albedo.rgb *= 0.1;
				doWaterShadowCaustics(albedo, dither);
			}
		} else {
			albedo.rgb = mix(vec3(1.0), albedo.rgb, pow(albedo.a, (1.0 - albedo.a) * 0.5) * 1.05);
			albedo.rgb *= 1.0 - pow(albedo.a, 64.0);
		}
		if (ice > 0.5) {
			if (isEyeInWater < 0.5) {
				albedo.rgb *= albedo.rgb * albedo.rgb;
			} else {
				discard;
			}
		}
	#else
		if (water > 0.5) {
			if (isEyeInWater < 0.5) { 
				
			} else {
				doWaterShadowCaustics(albedo, dither);
			}
		}

		if (premult > 0.5) {
			if (albedo.a < 0.01) discard;
		}
	#endif
	
	gl_FragData[0]=clamp(albedo,vec4(0.0),vec4(1.0));

}

#endif

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

//Uniforms//
uniform int worldTime;

uniform float frameTimeCounter;

uniform vec3 cameraPosition;

uniform mat4 gbufferModelView,gbufferModelViewInverse;
uniform mat4 shadowProjection,shadowProjectionInverse;
uniform mat4 shadowModelView,shadowModelViewInverse;

//Attributes//
attribute vec4 mc_Entity;
attribute vec4 mc_midTexCoord;

//Includes//
#include "/lib/vertex/waving.glsl"

#ifdef WORLD_CURVATURE
#include "/lib/vertex/worldCurvature.glsl"
#endif

//Program//
void main(){
	texCoord=gl_MultiTexCoord0.xy;
	color=gl_Color;
	
	lmCoord=(gl_TextureMatrix[1]*gl_MultiTexCoord1).xy;
	lmCoord=clamp((lmCoord-0.03125)*1.06667,0.0,1.0);
	
	position=shadowModelViewInverse*shadowProjectionInverse*ftransform();
	
	mat=0;
	if(mc_Entity.x==10100||mc_Entity.x==10105||mc_Entity.x==10102||mc_Entity.x==10103||mc_Entity.x==10104 || mc_Entity.x==10302 || mc_Entity.x==10303 )
	mat=1;
	if(mc_Entity.x==10249||mc_Entity.x==10252||mc_Entity.x==10300||mc_Entity.x==10223)
	mat=2;
	

	float istopv=gl_MultiTexCoord0.t<mc_midTexCoord.t?1.0:0.0;
	float skylight=(gl_TextureMatrix[1]*gl_MultiTexCoord1).y;
	skylight=clamp((skylight-0.03125)*1.06667,0.0,1.0);
	position.xyz=WavingBlocks(position.xyz,istopv,skylight);
	
	#ifdef WORLD_CURVATURE
	position.y-=WorldCurvature(position.xz);
	#endif
	
	#ifdef MOUVEMENT_CAM
	position+=vec4(0.03*sin(frameTimeCounter*3.*SPEED_MOOVE),0.015*cos(frameTimeCounter*4.*SPEED_MOOVE),0.0,0.0)*gbufferModelView;
	#endif
	
	gl_Position=shadowProjection*shadowModelView*position;
	
	#ifdef SHADOW_BACKFACE_CULLING
	normal=gl_NormalMatrix*gl_Normal;
	if(normal.z<0.0){
		gl_Position=vec4(-1.0);
		return;
	}
	#endif
	
	float dist=sqrt(gl_Position.x*gl_Position.x+gl_Position.y*gl_Position.y);
	float distortFactor=dist*shadowMapBias+(1.0-shadowMapBias);
	
	gl_Position.xy*=1.0/distortFactor;
	gl_Position.z=gl_Position.z*0.2;
}

#endif