<html>
<head>
    <style type="text/css">
    video { border: solid 1px black; }
    canvas { padding: 1px }
    .placeholder {
        display: inline-block;
        border: 1px dashed black;
        width: 300px;
        height: 150px;
    }
    </style>
</head>
<body>
<p>
<input type="button" onclick="drawOnce()" value="Draw once" />
<input type="button" onclick="clearOnce()" value="Clear once" />
<input type="button" onclick="toggleDrawing()" value="Toggle drawing"/>
</p>
<p>
    <ul>
        <li>Left: canvas</li>
        <li>Right: video</li>
        <li>Top rectangle small: opaque</li>
        <li>Bottom rectangle big: 50% translucent</li>
        <li>Background: transparent</li>
    </ul>
</p>
<script>

var ctx2Ds = [];

var gls = [];

function createTests()
{
    let glCases = [];
    for (let preserveDrawingBuffer of [true, false]) {
        for (let alpha of [true, false]) {
            for (let premultipliedAlpha of [true, false]) {
                glCases.push({
                    preserveDrawingBuffer: preserveDrawingBuffer,
                    alpha: alpha,
                    premultipliedAlpha: premultipliedAlpha,
                    antialias: false,
                    inDocument: true
                });
            }
        }
    }
    glCases.push({
        preserveDrawingBuffer: false,
        alpha: true,
        premultipliedAlpha: true,
        antialias: true,
        inDocument: true
    });
    glCases.push({
        preserveDrawingBuffer: false,
        alpha: true,
        premultipliedAlpha: true,
        antialias: false,
        inDocument: false
    });

    var ctx2DCases = [];
    for (let inDocument of [true, false]) {
        ctx2DCases.push({ inDocument: inDocument });
    }

    for (let c of glCases) {
        let d = document.createElement("div");
        document.body.appendChild(d);
        let h = document.createElement("h3");
        h.innerText = `WebGL case: ${JSON.stringify(c)}`;
        d.appendChild(h);
        let canvas = document.createElement("canvas");
        if (c.inDocument)
            d.appendChild(canvas);
        else {
            let p = document.createElement("div");
            p.className = "placeholder";
            d.appendChild(p);
        }
        let v = document.createElement("video");
        v.controls = true;
        v.autoplay = true;
        d.appendChild(v);

        let gl = canvas.getContext("webgl2", {
            preserveDrawingBuffer: c.preserveDrawingBuffer,
            alpha: c.alpha,
            premultipliedAlpha: c.premultipliedAlpha,
            antialias: c.antialias
        });
        v.srcObject = canvas.captureStream();
        gls.push(gl);
    }

    for (let c of ctx2DCases) {
        let d = document.createElement("div");
        document.body.appendChild(d);
        let h = document.createElement("h3");
        h.innerText = `Canvas case: ${JSON.stringify(c)}`;
        d.appendChild(h);
        let canvas = document.createElement("canvas");
        if (c.inDocument)
            d.appendChild(canvas);
        else {
            let p = document.createElement("div");
            p.className = "placeholder";
            d.appendChild(p);
        }
        let v = document.createElement("video");
        v.controls = true;
        v.autoplay = true;
        d.appendChild(v);
        let ctx2D = canvas.getContext("2d");
        v.srcObject = canvas.captureStream();
        ctx2Ds.push(ctx2D);
    }
}

function drawOnce()
{
    for (let c of gls) {
        c.enable(c.SCISSOR_TEST);
        if (c.getContextAttributes().premultipliedAlpha)
            c.clearColor(0., 0.5, 0., 0.5);
        else
            c.clearColor(0., 1., 0., 0.5);
        c.scissor(0, 0, 300, 50);
        c.clear(c.COLOR_BUFFER_BIT);

        c.scissor(125, 50, 50, 50);
        c.clearColor(0., 1., 0., 1.);
        c.clear(c.COLOR_BUFFER_BIT);
        c.scissor(0, 0, 300, 50);
        c.clear(c.COLOR_BUFFER_BIT);

    }
    for (let c of ctx2Ds) {
        c.fillStyle = "rgba(0, 128, 0, 0.5)";
        c.fillRect(0, 100, 300, 50);
        c.fillStyle = "rgba(0, 255, 0, 1.)";
        c.fillRect(125, 50, 50, 50);
    }
}

function clearOnce()
{
    console.log("clear");
    for (let c of gls) {
        c.clearColor(0., 0., 0., 0.);
        c.disable(c.SCISSOR_TEST);
        c.clear(c.COLOR_BUFFER_BIT);
    }
    for (let c of ctx2Ds) {
        c.clearRect(0, 0, 300, 150);
    }
}

var isToggling = false;

function toggleDrawing()
{
    if (isToggling) {
        clearTimeout(isToggling);
        isToggling = false;
        return;
    }
    var hasDrawn = true;
    function f() {
        if (hasDrawn)
            clearOnce();
        else
            drawOnce();
        hasDrawn = !hasDrawn;
        isToggling = setTimeout(f, 1000);
    }
    f();
}

createTests();

if (window.testRunner) {
    window.testRunner.waitUntilDone();
    toggleDrawing();
}
</script>
</body>
</html>