// __multiversion__
// This signals the loading code to prepend either #version 100 or #version 300 es as apropriate.

#include "vertexVersionCentroidUV.h"

#include "uniformWorldConstants.h"
#include "uniformEntityConstants.h"
#include "uniformPerFrameConstants.h"
#include "ESBEutil.h"
#ifdef USE_SKINNING
#include "uniformAnimationConstants.h"
#endif

attribute mediump vec4 POSITION;
attribute vec2 TEXCOORD_0;
attribute vec4 NORMAL;
#if defined(USE_SKINNING)
#ifdef MCPE_PLATFORM_NX
attribute uint BONEID_0;
#else
attribute float BONEID_0;
#endif
#endif

#ifdef COLOR_BASED
	attribute vec4 COLOR;
    varying vec4 vertColor;
#endif

varying vec4 light;
varying vec4 fogColor;

#ifdef USE_OVERLAY
    // When drawing horses on specific android devices, overlay color ends up being garbage data.
    // Changing overlay color to high precision appears to fix the issue on devices tested
	varying highp vec4 overlayColor;
#endif

#ifdef TINTED_ALPHA_TEST
	varying float alphaTestMultiplier;
#endif

#ifdef GLINT
	varying vec2 layer1UV;
	varying vec2 layer2UV;
    varying vec4 tileLightColor;
	varying vec4 glintColor;
#endif

const float AMBIENT = 0.45;

const float XFAC = -0.1;
const float ZFAC = 0.1;

float lightIntensity() {
#ifdef FANCY
#ifdef USE_SKINNING
#if defined(LARGE_VERTEX_SHADER_UNIFORMS)
    vec3 N = normalize( BONES[int(BONEID_0)] * NORMAL ).xyz;
#else
    vec3 N = normalize( BONE * NORMAL ).xyz;
#endif
#else
    vec3 N = normalize( WORLD * NORMAL ).xyz;
#endif

    N.y *= TILE_LIGHT_COLOR.w; //TILE_LIGHT_COLOR.w contains the direction of the light

    //take care of double sided polygons on materials without culling
#ifdef FLIP_BACKFACES
#ifdef USE_SKINNING
#if defined(LARGE_VERTEX_SHADER_UNIFORMS)
    vec3 viewDir = normalize((BONES[int(BONEID_0)] * POSITION).xyz);
#else
	vec3 viewDir = normalize((BONE * POSITION).xyz);
#endif
#else
    vec3 viewDir = normalize((WORLD * POSITION).xyz);
#endif
    if( dot(N, viewDir) > 0.0 )
        N *= -1.0;
#endif
	float yLight = (1.0+N.y) * 0.5;
	float def = yLight * (1.0-AMBIENT) + N.x*N.x * XFAC + N.z*N.z * ZFAC + AMBIENT;
	#ifdef ESBE_FLAT_SHADING
		float dusk = smoothstep(0.6,0.8,TILE_LIGHT_COLOR.b);
		N.x = abs(N.x*mix(1.5,0.6,dusk));
		N.yz = N.yz*0.6+0.3;
		N.yz *= mix(vec2(0.5,0.0),vec2(1.0),dusk);
		float esbe = max(0.2,max(N.x,max(N.y,N.z)));

		return mix(def,esbe,smoothstep(0.5,0.75,TILE_LIGHT_COLOR.b));
	#else
		return def;
	#endif
#else
    return 1.0;
#endif
}

#ifdef GLINT
vec2 calculateLayerUV(float offset, float rotation) {
	vec2 uv = TEXCOORD_0;
	uv -= 0.5;
	float rsin = sin(rotation);
	float rcos = cos(rotation);
	uv = mat2(rcos, -rsin, rsin, rcos) * uv;
	uv.x += offset;
	uv += 0.5;

	return uv * GLINT_UV_SCALE;
}
#endif

void main()
{
#ifdef USE_SKINNING
#if defined(LARGE_VERTEX_SHADER_UNIFORMS)
    POS4 pos = WORLDVIEWPROJ * BONES[int(BONEID_0)] * POSITION;
#else
    POS4 pos = WORLDVIEWPROJ * BONE * POSITION;
#endif
#else
    POS4 pos = WORLDVIEWPROJ * POSITION;
#endif
    gl_Position = pos;

    float L = lightIntensity();

#ifdef USE_OVERLAY
	L += OVERLAY_COLOR.a * 0.35;
#endif

#ifdef TINTED_ALPHA_TEST
    alphaTestMultiplier = OVERLAY_COLOR.a;
#endif

    light = vec4(vec3(L) * TILE_LIGHT_COLOR.xyz, 1.0);

#ifdef COLOR_BASED
	vertColor = COLOR;
#endif

#ifdef USE_OVERLAY
	overlayColor = OVERLAY_COLOR;
#endif

#ifndef NO_TEXTURE
    uv = TEXCOORD_0;
#endif

#ifdef USE_UV_ANIM
	uv.xy = UV_ANIM.xy + (uv.xy * UV_ANIM.zw);
#endif

#ifdef GLINT
	glintColor = GLINT_COLOR;
	layer1UV = calculateLayerUV(UV_OFFSET.x, UV_ROTATION.x);
	layer2UV = calculateLayerUV(UV_OFFSET.y, UV_ROTATION.y);
    tileLightColor = TILE_LIGHT_COLOR;
#endif

	//fog
    fogColor.rgb = FOG_COLOR.rgb;
	fogColor.a = clamp(((pos.z / RENDER_DISTANCE) - FOG_CONTROL.x) / (FOG_CONTROL.y - FOG_CONTROL.x), 0.0, 1.0);
}
