/*
Copyright (c) 2019 The Khronos Group Inc.
Use of this source code is governed by an MIT-style license that can be
found in the LICENSE.txt file.
*/

function generateTest(internalFormat, pixelFormat, pixelType, prologue, resourcePath, defaultContextVersion) {
    var wtu = WebGLTestUtils;
    var tiu = TexImageUtils;
    var gl = null;
    var successfullyParsed = false;
    var realRedColor = [255, 0, 0];
    var realGreenColor = [0, 255, 0];
    var realBlueColor = [0, 0, 255];
    var realCyanColor = [0, 255, 255];
    var redColor = realRedColor;
    var greenColor = realGreenColor;
    var blueColor = realBlueColor;
    var cyanColor = realCyanColor;

    function init()
    {
        description('Verify texImage2D and texSubImage2D code paths taking a sub-rectangle of a canvas (' + internalFormat + '/' + pixelFormat + '/' + pixelType + ')');

        // Set the default context version while still allowing the webglVersion URL query string to override it.
        wtu.setDefault3DContextVersion(defaultContextVersion);

        // The sub-rectangle tests only apply to WebGL 2.0 for the
        // time being, though the tests for the WebGL 1.0
        // format/internal format/type combinations are generated into
        // conformance/textures/.
        if (wtu.getDefault3DContextVersion() < 2) {
            debug('Test only applies to WebGL 2.0');
            finishTest();
            return;
        }

        gl = wtu.create3DContext("example", { preserveDrawingBuffer: true });

        if (!prologue(gl)) {
            finishTest();
            return;
        }

        switch (gl[pixelFormat]) {
        case gl.RED:
        case gl.RED_INTEGER:
          greenColor = [0, 0, 0];
          blueColor = [0, 0, 0];
          cyanColor = [0, 0, 0];
          break;

        case gl.RG:
        case gl.RG_INTEGER:
          blueColor = [0, 0, 0];
          cyanColor = [0, 255, 0];
          break;

        case gl.LUMINANCE:
        case gl.LUMINANCE_ALPHA:
          redColor = [255, 255, 255];
          greenColor = [0, 0, 0];
          blueColor = [0, 0, 0];
          cyanColor = [0, 0, 0];
          break;

        case gl.ALPHA:
          redColor = [0, 0, 0];
          greenColor = [0, 0, 0];
          blueColor = [0, 0, 0];
          cyanColor = [0, 0, 0];
          break;

        default:
          break;
        }

        gl.clearColor(0,0,0,1);
        gl.clearDepth(1);
        gl.disable(gl.BLEND);

        var canvas2d = document.createElement('canvas');
        runTest(canvas2d, setupSourceCanvas2D, '2D-rendered canvas');

        var canvasWebGL = document.createElement('canvas');
        runTest(canvasWebGL, setupSourceCanvasWebGL, 'WebGL-rendered canvas');

        finishTest();
    }

    function fillStyle2D(ctx, color) {
        ctx.fillStyle = 'rgb(' + color[0] + ', ' + color[1] + ', ' + color[2] + ')';
    }

    function setupSourceCanvas2D(canvas) {
        var width = canvas.width;
        var height = canvas.height;
        var halfWidth = Math.floor(width / 2);
        var halfHeight = Math.floor(height / 2);

        var ctx = canvas.getContext('2d');
        // Always use the same pattern for this test: four quadrants:
        //   red    green
        //   blue   cyan
        // Handle odd-sized canvases
        fillStyle2D(ctx, realRedColor);
        ctx.fillRect(0, 0, halfWidth, halfHeight);
        fillStyle2D(ctx, realGreenColor);
        ctx.fillRect(halfWidth, 0, width - halfWidth, halfHeight);
        fillStyle2D(ctx, realBlueColor);
        ctx.fillRect(0, halfHeight, halfWidth, height - halfHeight);
        fillStyle2D(ctx, realCyanColor);
        ctx.fillRect(halfWidth, halfHeight, width - halfWidth, height - halfHeight);
    }

    function clearColorWebGL(ctx, color) {
        ctx.clearColor(color[0] / 255.0, color[1] / 255.0, color[2] / 255.0, 1.0);
        ctx.clear(ctx.COLOR_BUFFER_BIT);
    }

    function setupSourceCanvasWebGL(canvas) {
        var width = canvas.width;
        var height = canvas.height;
        var halfWidth = Math.floor(width / 2);
        var halfHeight = Math.floor(height / 2);

        var ctx = canvas.getContext('webgl');
        // Always use the same pattern for this test: four quadrants:
        //   red    green
        //   blue   cyan
        // Handle odd-sized canvases

        ctx.viewport(0, 0, width, height);
        ctx.enable(ctx.SCISSOR_TEST);
        // OpenGL origin is lower-left
        ctx.scissor(0, 0, halfWidth, halfHeight);
        clearColorWebGL(ctx, realBlueColor);
        ctx.scissor(halfWidth, 0, width - halfWidth, halfHeight);
        clearColorWebGL(ctx, realCyanColor);
        ctx.scissor(0, halfHeight, halfWidth, height - halfHeight);
        clearColorWebGL(ctx, realRedColor);
        ctx.scissor(halfWidth, halfHeight, width - halfWidth, height - halfHeight);
        clearColorWebGL(ctx, realGreenColor);
    }

    function runOneIteration(sourceDescription, useTexSubImage2D, flipY,
                             canvas, canvasSize, canvasSetupFunction,
                             sourceSubRectangle, expected,
                             bindingTarget, program)
    {
        sourceSubRectangleString = '';
        if (sourceSubRectangle) {
            sourceSubRectangleString = ', sourceSubRectangle=' + sourceSubRectangle;
        }
        debug('');
        debug('Testing ' + sourceDescription + ' with ' +
              (useTexSubImage2D ? 'texSubImage2D' : 'texImage2D') +
              ', flipY=' + flipY +
              ', bindingTarget=' + (bindingTarget == gl.TEXTURE_2D ? 'TEXTURE_2D' : 'TEXTURE_CUBE_MAP') +
              sourceSubRectangleString);

        var loc;
        if (bindingTarget == gl.TEXTURE_CUBE_MAP) {
            loc = gl.getUniformLocation(program, "face");
        }

        // Initialize the contents of the source canvas.
        var width = canvasSize[0];
        var height = canvasSize[1];
        var halfWidth = Math.floor(width / 2);
        var halfHeight = Math.floor(height / 2);
        canvas.width = width;
        canvas.height = height;
        canvasSetupFunction(canvas);

        // Upload the source canvas to the texture and draw it to a quad.
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
        // Enable writes to the RGBA channels
        gl.colorMask(1, 1, 1, 0);
        var texture = gl.createTexture();
        // Bind the texture to texture unit 0
        gl.bindTexture(bindingTarget, texture);
        // Set up texture parameters
        gl.texParameteri(bindingTarget, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
        gl.texParameteri(bindingTarget, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
        // Set up pixel store parameters
        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
        gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
        wtu.failIfGLError(gl, 'gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);');
        var targets = [gl.TEXTURE_2D];
        if (bindingTarget == gl.TEXTURE_CUBE_MAP) {
            targets = [gl.TEXTURE_CUBE_MAP_POSITIVE_X,
                       gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
                       gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
                       gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
                       gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
                       gl.TEXTURE_CUBE_MAP_NEGATIVE_Z];
        }
        // In this test, this is always specified. It's currently WebGL 2.0-specific.
        gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, sourceSubRectangle[0]);
        gl.pixelStorei(gl.UNPACK_SKIP_ROWS, sourceSubRectangle[1]);
        // Upload the image into the texture
        var uploadWidth = sourceSubRectangle[2];
        var uploadHeight = sourceSubRectangle[3];
        for (var tt = 0; tt < targets.length; ++tt) {
            if (useTexSubImage2D) {
                // Initialize the texture to black first
                gl.texImage2D(targets[tt], 0, gl[internalFormat],
                              uploadWidth, uploadHeight, 0,
                              gl[pixelFormat], gl[pixelType], null);
                gl.texSubImage2D(targets[tt], 0, 0, 0,
                                 uploadWidth, uploadHeight,
                                 gl[pixelFormat], gl[pixelType], canvas);
            } else {
                gl.texImage2D(targets[tt], 0, gl[internalFormat],
                              uploadWidth, uploadHeight, 0,
                              gl[pixelFormat], gl[pixelType], canvas);
            }
        }

        gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, 0);
        gl.pixelStorei(gl.UNPACK_SKIP_ROWS, 0);

        // The tests are constructed to upload a single solid color
        // out of the canvas.
        var outputCanvasWidth = gl.drawingBufferWidth;
        var outputCanvasHeight = gl.drawingBufferHeight;

        for (var tt = 0; tt < targets.length; ++tt) {
            if (bindingTarget == gl.TEXTURE_CUBE_MAP) {
                gl.uniform1i(loc, targets[tt]);
            }
            // Draw the triangles
            wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);

            var msg = 'should be ' + expected;
            wtu.checkCanvasRect(gl, 0, 0, outputCanvasWidth, outputCanvasHeight, expected, msg);
        }
    }

    function runTest(canvas, canvasSetupFunction, sourceDescription)
    {
        var program = tiu.setupTexturedQuad(gl, internalFormat);
        runTestOnBindingTarget(gl.TEXTURE_2D, program, canvas, canvasSetupFunction, sourceDescription);
        program = tiu.setupTexturedQuadWithCubeMap(gl, internalFormat);
        runTestOnBindingTarget(gl.TEXTURE_CUBE_MAP, program, canvas, canvasSetupFunction, sourceDescription);

        wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
    }

    function runTestOnBindingTarget(bindingTarget, program, canvas, canvasSetupFunction, sourceDescription) {
        var cases = [
            // Small canvas cases. Expected that these won't be
            // GPU-accelerated in most browsers' implementations.
            { expected: redColor,   flipY: false, size: [2, 2], subRect: [0, 0, 1, 1] },
            { expected: greenColor, flipY: false, size: [2, 2], subRect: [1, 0, 1, 1] },
            { expected: blueColor,  flipY: false, size: [2, 2], subRect: [0, 1, 1, 1] },
            { expected: cyanColor,  flipY: false, size: [2, 2], subRect: [1, 1, 1, 1] },
            { expected: redColor,   flipY: true,  size: [2, 2], subRect: [0, 1, 1, 1] },
            { expected: greenColor, flipY: true,  size: [2, 2], subRect: [1, 1, 1, 1] },
            { expected: blueColor,  flipY: true,  size: [2, 2], subRect: [0, 0, 1, 1] },
            { expected: cyanColor,  flipY: true,  size: [2, 2], subRect: [1, 0, 1, 1] },

            // Larger canvas cases. Expected that these will be
            // GPU-accelerated in most browsers' implementations.
            // Changes will be gladly accepted to trigger more
            // browsers' heuristics to accelerate these canvases.
            { expected: redColor,   flipY: false, size: [384, 384], subRect: [  0,   0, 192, 192] },
            { expected: greenColor, flipY: false, size: [384, 384], subRect: [192,   0, 192, 192] },
            { expected: blueColor,  flipY: false, size: [384, 384], subRect: [  0, 192, 192, 192] },
            { expected: cyanColor,  flipY: false, size: [384, 384], subRect: [192, 192, 192, 192] },
            { expected: blueColor,  flipY: true,  size: [384, 384], subRect: [  0,   0, 192, 192] },
            { expected: cyanColor,  flipY: true,  size: [384, 384], subRect: [192,   0, 192, 192] },
            { expected: redColor,   flipY: true,  size: [384, 384], subRect: [  0, 192, 192, 192] },
            { expected: greenColor, flipY: true,  size: [384, 384], subRect: [192, 192, 192, 192] },

        ];

        for (var i in cases) {
            runOneIteration(sourceDescription, false, cases[i].flipY,
                            canvas, cases[i].size, canvasSetupFunction,
                            cases[i].subRect,
                            cases[i].expected, bindingTarget, program);
            runOneIteration(sourceDescription, true, cases[i].flipY,
                            canvas, cases[i].size, canvasSetupFunction,
                            cases[i].subRect,
                            cases[i].expected, bindingTarget, program);
        }
    }

    return init;
}
