uniform sampler2D tex;
uniform sampler2D lightFromLeft;
uniform sampler2D lightFromTop;
uniform sampler2D lightFromRight;
uniform sampler2D lightFromBottom;
uniform sampler2D bump;
uniform float strength;
uniform vec2 lightSize;
uniform float screenHeight;

varying vec2 vflipped_concave;

varying vec4 vbevel; // top, bottom, left, right

varying vec3 vt; // tl, tm, tr
varying vec3 vm; // ml, mm, mr
varying vec3 vb; // bl, bm, br

varying vec4 vpaint;

void main(void) {
    vec4 bumpLookup = texture2D(bump, floor(gl_TexCoord[0].st) / 1024.0);
    float bly = bumpLookup.y;
    float blx = bumpLookup.x;
    
    float localY = mod(gl_TexCoord[0].st.y, 16.0);
    float localX = mod(gl_TexCoord[0].st.x, 16.0);
    
    if (
        ((localY <= 4.0) &&
            ((localX <= 4.0 && vt[0] < 0.1) ||
            (localX >= 12.0 && vt[2] < 0.1) ||
            (localX > 4.0 && localX < 12.0 && vt[1] < 0.1)))
        ||
        ((localY >= 12.0) &&
            ((localX <= 4.0 && vb[0] < 0.1) ||
            (localX >= 12.0 && vb[2] < 0.1) ||
            (localX > 4.0 && localX < 12.0 && vb[1] < 0.1)))
        ||
        ((localY > 4.0 && localY < 12.0) &&
            ((localX <= 4.0 && vm[0] < 0.1) ||
            (localX >= 12.0 && vm[2] < 0.1) ||
            (localX > 4.0 && localX < 12.0 && vm[1] < 0.1)))
    ) {
        gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
        return;
    }
    
    // Bevels up
    if (vflipped_concave.y > 0.5) {
        if (localY <= 2.0 && vbevel[0] > 0.9) {
            blx = (blx - 0.5) * 0.5 + 0.25;
        } else if (localY >= 14.0 && vbevel[1] > 0.9) {
            blx = (blx - 0.5) * 0.5 + 0.75;
        } else if (localX <= 2.0 && vbevel[2] > 0.9) {
            bly = (bly - 0.5) * 0.5 + 0.25;
        } else if (localX >= 14.0 && vbevel[3] > 0.9) {
            bly = (bly - 0.5) * 0.5 + 0.75;
        }
    } else {
        if (localY <= 2.0 && vbevel[0] > 0.9) {
            blx = (blx - 0.5) * 0.5 + 0.75;
        } else if (localY >= 14.0 && vbevel[1] > 0.9) {
            blx = (blx - 0.5) * 0.5 + 0.25;
        } else if (localX <= 2.0 && vbevel[2] > 0.9) {
            bly = (bly - 0.5) * 0.5 + 0.75;
        } else if (localX >= 14.0 && vbevel[3] > 0.9) {
            bly = (bly - 0.5) * 0.5 + 0.25;
        }
    }

    float leftM = max(bly - 0.3, 0.0) * 2.0 * bumpLookup.z * strength;
    float rightM = max(0.7 - bly, 0.0) * 2.0 * bumpLookup.z * strength;
    float topM = max(blx - 0.3, 0.0) * 2.0 * bumpLookup.z * strength;
    float bottomM = max(0.7 - blx, 0.0) * 2.0 * bumpLookup.z * strength;
	
	vec4 lightTop = texture2D(lightFromTop, vec2(gl_FragCoord.x, screenHeight - gl_FragCoord.y) / lightSize / 4.0);
	lightTop = vec4(lightTop.x * topM, lightTop.y * topM, lightTop.z * topM, 0);
	
	vec4 lightBottom = texture2D(lightFromBottom, vec2(gl_FragCoord.x, screenHeight - gl_FragCoord.y) / lightSize / 4.0);
	lightBottom = vec4(lightBottom.x * bottomM, lightBottom.y * bottomM, lightBottom.z * bottomM, 0);
	
    vec4 lightLeft = texture2D(lightFromLeft, vec2(gl_FragCoord.x, screenHeight - gl_FragCoord.y) / lightSize / 4.0);
	vec4 lightRight = texture2D(lightFromRight, vec2(gl_FragCoord.x, screenHeight - gl_FragCoord.y) / lightSize / 4.0);
	
	if (vflipped_concave.x > 0.9) {
	    lightLeft = vec4(lightLeft.x * rightM, lightLeft.y * rightM, lightLeft.z * rightM, 0);
	    lightRight = vec4(lightRight.x * leftM, lightRight.y * leftM, lightRight.z * leftM, 0);
	} else {
	    lightLeft = vec4(lightLeft.x * leftM, lightLeft.y * leftM, lightLeft.z * leftM, 0);
	    lightRight = vec4(lightRight.x * rightM, lightRight.y * rightM, lightRight.z * rightM, 0);
	}
	
	gl_FragColor = (texture2D(tex, floor(gl_TexCoord[0].st) / 1024.0) * vec4(1.0 - vpaint.w, 1.0 - vpaint.w, 1.0 - vpaint.w, 1.0) + vec4(vpaint.x, vpaint.y, vpaint.z, 0.0)) * gl_Color + lightLeft + lightRight + lightTop + lightBottom;
}
