/* Shader implementation of Scale2x is adapted from https://gist.github.com/singron/3161079 */
varying vec2 texCoord;
uniform sampler2D tex;
uniform vec2 texSize;

vec4 scale2x(vec4 pixels[5], vec2 p) {
    // texel arrangement
    // x 0 x
    // 1 2 3
    // x 4 x
    // p = the texCoord within a pixel [0...1]
    p = fract(p);
	if (p.x > .5) {
		if (p.y > .5) {
			// Top Right
			return pixels[0] == pixels[3] && pixels[0] != pixels[1] && pixels[3] != pixels[4] ? pixels[3] : pixels[2];
		} else {
			// Bottom Right
			return pixels[4] == pixels[3] && pixels[1] != pixels[4] && pixels[0] != pixels[3] ? pixels[3] : pixels[2];
		}
	} else {
		if (p.y > .5) {
			// Top Left
			return pixels[1] == pixels[0] && pixels[0] != pixels[3] && pixels[1] != pixels[4] ? pixels[1] : pixels[2];
		} else {
			// Bottom Left
			return pixels[1] == pixels[4] && pixels[1] != pixels[0] && pixels[4] != pixels[3] ? pixels[1] : pixels[2];
		}
	}
}

vec4 scaleNeighborhood(vec2 p, vec2 x, vec2 o) {
	vec4 neighborhood[5];
    neighborhood[0] = texture2D(tex, texCoord + x + vec2( 0.0,  o.y));
    neighborhood[1] = texture2D(tex, texCoord + x + vec2(-o.x,  0.0));
    neighborhood[2] = texture2D(tex, texCoord + x + vec2( 0.0,  0.0));
    neighborhood[3] = texture2D(tex, texCoord + x + vec2( o.x,  0.0));
    neighborhood[4] = texture2D(tex, texCoord + x + vec2( 0.0, -o.y));
	return scale2x(neighborhood, p + x * texSize);
}

void main() {
    // o = offset, the width of a pixel
    vec2 o = 1.0 / texSize;

    vec2 p = texCoord * texSize;
	vec4 pixels[5];
	pixels[0] = scaleNeighborhood(p, vec2(       0.0,  o.y / 2.0), o);
	pixels[1] = scaleNeighborhood(p, vec2(-o.x / 2.0,        0.0), o);
	pixels[2] = scaleNeighborhood(p, vec2(       0.0,        0.0), o);
	pixels[3] = scaleNeighborhood(p, vec2( o.x / 2.0,        0.0), o);
	pixels[4] = scaleNeighborhood(p, vec2(       0.0, -o.y / 2.0), o);
	gl_FragColor = scale2x(pixels, p * 2.0);
}