precision mediump float;

uniform sampler2D texture;
uniform float alpha;
uniform vec2 texAtlasSize;
uniform vec2 gridSize;
uniform float deadly;
uniform float floating;

varying vec2 pass_TexCoords;

const float clampBorder = 0.05;

float itermod(in float x, in float y);
vec2 getInGridPos();
vec2 getTexCoordsInGridSquare();
vec2 getTexCoordsInAtlas(in vec2 texCoords, in float atlasIndex);

void main() {

    vec2 gridPos = getInGridPos();
    float index = 0.0;

    bool top = gridPos.y == 0.0;
    bool bottom = gridPos.y == gridSize.y - 1.0;
    bool left = gridPos.x == 0.0;
    bool right = gridPos.x == gridSize.x - 1.0;

    if(top){
        if(left)
            index = 5.0 + itermod(gridSize.x, 2.0) + itermod(gridSize.y, 2.0);
        else if(right)
            index = 21.0 + itermod(gridSize.x, 2.0) + itermod(gridSize.y, 2.0);
        else
            index = itermod(gridPos.x, 3.0);
        if(deadly == 1.0)
            index += 8.0;
    } else if(bottom){
        if(left)
            index = 37.0 + itermod(gridSize.x, 2.0) + itermod(gridSize.y, 2.0);
        else if(right)
            index = 53.0 + itermod(gridSize.x, 2.0) + itermod(gridSize.y, 2.0);
        else
            index = 16.0 + itermod(gridPos.x, 3.0);
        if(floating == 1.0)
            index += 8.0;
    } else if(left){
        index = 32.0 + itermod(gridPos.y, 3.0);
    } else if(gridPos.x == gridSize.x - 1.0){
        index = 40.0 + itermod(gridPos.y, 3.0);
    } else{
        index = 48.0 + itermod(gridPos.x, 2.0) + itermod(gridPos.y, 2.0);
    }

    vec2 texCoordsInGridSquare = getTexCoordsInGridSquare();
    texCoordsInGridSquare = clamp(texCoordsInGridSquare, clampBorder, 1.0 - clampBorder);
    vec2 texCoordsInAtlas = getTexCoordsInAtlas(texCoordsInGridSquare, index);
    gl_FragColor = texture2D(texture, texCoordsInAtlas);
    gl_FragColor.a = min(gl_FragColor.a, alpha);
    gl_FragColor.rgb = gl_FragColor.rgb / gl_FragColor.a;

}

float itermod(in float x, in float y){

    while(x - y >= 0.0){
        x -= y;
    }
    return x;

}

vec2 getInGridPos(){

    float gridX = floor(pass_TexCoords.x * gridSize.x);
    float gridY = floor(pass_TexCoords.y * gridSize.y);
    if(pass_TexCoords.y == 1.0)
        gridY -= 1.0;
    if(pass_TexCoords.x == 1.0)
        gridX -= 1.0;
    return vec2(gridX, gridY);

}

vec2 getTexCoordsInGridSquare(){

    float x = mod(pass_TexCoords.x, 1.0 / gridSize.x) * gridSize.x;
    float y = mod(pass_TexCoords.y, 1.0 / gridSize.y) * gridSize.y;
    if(pass_TexCoords.x == 1.0)
        x = 1.0;
    if(pass_TexCoords.y == 1.0)
        y = 1.0;
    return vec2(x, y);

}

vec2 getTexCoordsInAtlas(in vec2 texCoords, in float atlasIndex){

     vec2 texAtlasCoords = vec2(0.0, 0.0);
     texAtlasCoords.x = mod(texCoords.x, 1.0) / texAtlasSize.x;
     texAtlasCoords.x += mod(atlasIndex, texAtlasSize.x) / texAtlasSize.x;
     texAtlasCoords.y = mod(texCoords.y, 1.0) / texAtlasSize.y;
     texAtlasCoords.y += floor(atlasIndex / texAtlasSize.y) / texAtlasSize.y;
     return texAtlasCoords;

}