#line 1

// #define OVERLAY

// #define SAMPLE_TYPE_UNSIGNED_INT
// #define SAMPLE_TYPE_INT

#if defined(SAMPLE_TYPE_UNSIGNED_INT)

#define samplerType usampler2D
#define sampleType uvec4

#elif defined(SAMPLE_TYPE_INT)

#define samplerType isampler2D
#define sampleType ivec4

#else

#define samplerType sampler2D
#define sampleType vec4

#endif


uniform samplerType textureMap;
uniform vec4 u_min;
uniform vec4 u_max;
uniform vec4 u_defaultColor;
uniform uvec4 u_channelSwizzle;
uniform bvec4 u_channelSelect;
uniform bool u_convertTosRGB;
uniform float u_scale;
uniform float u_gridScale;

in vec2 texcoords;
in vec2 texelCoords;

out vec4 results[1];

void main()
{
    sampleType sample = texture(textureMap, texcoords);
    vec4 ldr_sample = vec4(sample - u_min) / max(vec4(u_max - u_min), vec4(0.00000001));
    ldr_sample = clamp(ldr_sample, vec4(0,0,0,0), vec4(1,1,1,1));

    vec4 ldr_sample2;
    
    // swizzle channels
    ldr_sample2.r = ldr_sample[u_channelSwizzle.r];
    ldr_sample2.g = ldr_sample[u_channelSwizzle.g];
    ldr_sample2.b = ldr_sample[u_channelSwizzle.b];
    ldr_sample2.a = ldr_sample[u_channelSwizzle.a];
    
    // disable channels
    ldr_sample2 = mix(u_defaultColor, ldr_sample2, u_channelSelect);
    
    vec2 texelFraction = fract(texelCoords);
    float iScale = 1.0 / u_scale;
    
    if (u_scale >= u_gridScale)
    {
        // Anti-aliased grid
        vec2 lineHalfWidth= vec2(iScale * 0.25);
        vec2 smoothingWidth= vec2(iScale * 0.75);
        const vec2 h= vec2(0.5);
        vec2 lineAlpha= smoothstep (lineHalfWidth, lineHalfWidth + smoothingWidth, abs (fract (texelCoords + h) - h));
        
        // Use luminance as grid color
        float luminance = dot (vec3(0.2126, 0.7152, 0.0722), ldr_sample2.rgb);
        luminance = clamp(luminance, 0.25, 0.75);
        vec4 lineColor= vec4(luminance, luminance, luminance, 1.0);

        ldr_sample2 = mix (lineColor, ldr_sample2, min(lineAlpha.x, lineAlpha.y));
    }
    
    results[0] = ldr_sample2;

    /*
     * From: http://www.khronos.org/registry/gles/extensions/EXT/EXT_sRGB.txt
     *
     * From linear to sRGB
     *      {  0.0,                          cl        <= 0
     *      {  12.92 * cl,                   0         <  cl < 0.0031308
     * cs = {  1.055 * cl^0.41666 - 0.055,   0.0031308 <= cl < 1
     *      {  1.0,                                       cl >= 1
     *
     * Assume cs is the sRGB component in the range [0,1].
     */
    if (u_convertTosRGB)
    {
        float components[3];
        components[0] = results[0].r;
        components[1] = results[0].g;
        components[2] = results[0].b;
        const float darkScale = 12.92;
        const float darkThreshold = 0.0031308;
        const float lightScale = 1.055;
        const float lightExponent = 0.4166;
        const float lightShift = 0.055;
        for(int i = 0; i < 3; ++i)
        {
           if(components[i] < 0.0)
               components[i] = 0.0;
           else if(components[i] < darkThreshold)
               components[i] *= darkScale;
           else if(components[i] < 1.0)
               components[i] = lightScale * pow(components[i], lightExponent) - lightShift;
           else
               components[i] = 1.0;
        }
        results[0].rgb = vec3(components[0], components[1], components[2]);
    }
}
