<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script src="resources/shaderProgram-utilities-webgl.js"></script>
<script id="vertex-shader" type="x-shader/x-vertex">
    attribute vec3 position;
    void main(void) {
        gl_Position = vec4(position, 1.0);
    }
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
    precision mediump float;

    void main(void) {
        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
    }
</script>
<script>
function load() {
    createProgram("webgl");
    linkProgram("vertex-shader", "fragment-shader");
    context.useProgram(program);

    clearContext();

    runTest();
}

function clearContext() {
    context.clearColor(0.0, 0.0, 0.0, 1.0);
    context.clear(context.COLOR_BUFFER_BIT);
}

function drawArrays() {
    clearContext();

    let vertexes = [
        -0.5,  0.5,  0.0,
        -0.5, -0.5,  0.0,
         0.5, -0.5,  0.0, 
    ];
    let vertexBuffer = context.createBuffer();
    context.bindBuffer(context.ARRAY_BUFFER, vertexBuffer);
    context.bufferData(context.ARRAY_BUFFER, new Float32Array(vertexes), context.STATIC_DRAW);

    let position = context.getAttribLocation(program, "position");
    context.vertexAttribPointer(position, 3, context.FLOAT, false, 0, 0); 
    context.enableVertexAttribArray(position);

    context.drawArrays(context.TRIANGLES, 0, 3);
}

function drawElements() {
    clearContext();

    let vertexes = [
         0.5,  0.5,  0.0,
        -0.5, -0.5,  0.0,
         0.5, -0.5,  0.0, 
    ];
    let vertexBuffer = context.createBuffer();
    context.bindBuffer(context.ARRAY_BUFFER, vertexBuffer);
    context.bufferData(context.ARRAY_BUFFER, new Float32Array(vertexes), context.STATIC_DRAW);

    let indexes = [0, 1, 2];
    let indexBuffer = context.createBuffer();
    context.bindBuffer(context.ELEMENT_ARRAY_BUFFER, indexBuffer);
    context.bufferData(context.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexes), context.STATIC_DRAW);

    let position = context.getAttribLocation(program, "position");
    context.vertexAttribPointer(position, 3, context.FLOAT, false, 0, 0); 
    context.enableVertexAttribArray(position);

    context.drawElements(context.TRIANGLES, indexes.length, context.UNSIGNED_SHORT, 0);
}

function test() {
    let suite = InspectorTest.createAsyncSuite("Canvas.setShaderProgramDisabled");

    let shaderProgram = WI.canvasManager.shaderPrograms[0];
    let originalContent = null;

    function validTest({name, disabled, evaluateString}) {
        suite.addTestCase({
            name,
            test(resolve, reject) {
                CanvasAgent.setShaderProgramDisabled(shaderProgram.identifier, disabled, (error) => {
                    if (error) {
                        reject(error);
                        return;
                    }

                    InspectorTest.evaluateInPage(evaluateString, (error) => {
                        if (error) {
                            reject(error);
                            return;
                        }

                        CanvasAgent.requestContent(shaderProgram.canvas.identifier)
                        .then(({content}) => {
                            if (disabled)
                                InspectorTest.expectEqual(content, originalContent, "Disabling a shader program should prevent it from drawing.");
                            else
                                InspectorTest.expectNotEqual(content, originalContent, "Re-enabling a shader program should allow it to draw.");
                        })
                        .then(resolve, reject);
                    });
                });
            }
        });
    }

    validTest({
        name: "Canvas.setShaderProgramDisabled.disabledDrawArrays",
        disabled: true,
        evaluateString: `drawArrays()`,
    });

    validTest({
        name: "Canvas.setShaderProgramDisabled.disabledDrawElements",
        disabled: true,
        evaluateString: `drawElements()`,
    });

    validTest({
        name: "Canvas.setShaderProgramDisabled.reenabledDrawArrays",
        disabled: false,
        evaluateString: `drawArrays()`,
    });

    validTest({
        name: "Canvas.setShaderProgramDisabled.reenabledDrawElements",
        disabled: false,
        evaluateString: `drawElements()`,
    });

    suite.addTestCase({
        name: "Canvas.setShaderProgramDisabled.invalidProgramId",
        description: "Invalid program identifiers should cause an error.",
        test(resolve, reject) {
            const programId = "INVALID_PROGRAM_ID";
            const disabled = false;
            CanvasAgent.setShaderProgramDisabled(programId, disabled, (error) => {
                InspectorTest.expectThat(error, "Should produce an error.");
                InspectorTest.log("Error: " + error);
                resolve();
            });
        }
    });

    CanvasAgent.requestContent(shaderProgram.canvas.identifier, (error, content) => {
        originalContent = content;

        suite.runTestCasesAndFinish();
    });
}
</script>
</head>
<body onload="load()">
    <p>Test disabling and re-enabling of shader programs.</p>
</body>
</html>
