<!--

/*
** Copyright (c) 2012 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/

-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../resources/js-test-pre.js"></script>
<script src="../resources/webgl-test.js"></script>
<script src="../resources/webgl-test-utils.js"></script>
<script>
"use strict";
var wtu = WebGLTestUtils;
var gl = null;
var textureLoc = null;
var successfullyParsed = false;
var video;

initTestingHarnessWaitUntilDone();

function init()
{
    description('Verify npot video');

    var canvas = document.getElementById("example");
    gl = wtu.create3DContext(canvas);
    var program = wtu.setupTexturedQuad(gl);

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

    textureLoc = gl.getUniformLocation(program, "tex");

    video = document.getElementById("vid");
    wtu.startPlayingAndWaitForVideo(video, runTest);
}

// These two declarations need to be global for "shouldBe" to see them
var buf = null;
var idx = 0;
var pixel = [0, 0, 0];
var correctColor = null;
var texture;

function runOneIteration(videoElement, useTexSubImage2D, flipY, topColor, bottomColor, badMinFilter, badClamp, genMips)
{
    debug('Testing ' + (useTexSubImage2D ? 'texSubImage2D' : 'texImage2D') +
          ' with flipY=' + flipY);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    // Disable any writes to the alpha channel
    gl.colorMask(1, 1, 1, 0);
    if (!texture) {
        texture = gl.createTexture();
    }
    // Bind the texture to texture unit 0
    gl.bindTexture(gl.TEXTURE_2D, texture);
    // Set up pixel store parameters
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
    // Upload the videoElement into the texture
    debug("size: " + videoElement.videoWidth + "x" + videoElement.videoHeight);
    if (useTexSubImage2D) {
        // Initialize the texture to black first
        debug("use texSubImage2D");
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,
                      videoElement.videoWidth, videoElement.videoHeight, 0,
                      gl.RGBA, gl.UNSIGNED_BYTE, null);
        gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, videoElement);
    } else {
        debug("use texImage2D");
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, videoElement);
    }

    // Set up texture parameters
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    if (badMinFilter) {
        debug("bad min filter");
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
    } else {
        debug("good min filter");
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    }
    if (badClamp) {
        debug("bad clamp");
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
    } else {
        debug("good clamp");
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    }
    if (genMips) {
        debug("generate mips");
        gl.generateMipmap(gl.TEXTURE_2D);
        glErrorShouldBe(gl, gl.INVALID_OPERATION, "should be INVALID_OPERATION");
    }

    gl.bindTexture(gl.TEXTURE_2D, null);
    gl.bindTexture(gl.TEXTURE_2D, texture);

//    var c = document.createElement("canvas");
//    c.width = 16;
//    c.height = 16;
//    c.style.border = "1px solid black";
//    var ctx = c.getContext("2d");
//    ctx.drawImage(videoElement, 0, 0, 16, 16);
//    document.body.appendChild(c);

    // Point the uniform sampler to texture unit 0
    gl.uniform1i(textureLoc, 0);
    // Draw the triangles
    wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
    // Check a few pixels near the top and bottom and make sure they have
    // the right color.
    var tolerance = 5;
    debug("Checking lower left corner");
    wtu.checkCanvasRect(gl, 4, 4, 2, 2, bottomColor,
                        "shouldBe " + bottomColor, tolerance);
    debug("Checking upper left corner");
    wtu.checkCanvasRect(gl, 4, gl.canvas.height - 8, 2, 2, topColor,
                        "shouldBe " + topColor, tolerance);
    debug("");
}

function runTest(videoElement)
{
    var red = [255, 0, 0];
    var green = [0, 255, 0];
    var black = [0, 0, 0];
    runOneIteration(videoElement, false, true, black, black, true, true, true);
    runOneIteration(videoElement, false, true, black, black, true, false, false);
    runOneIteration(videoElement, false, true, black, black, false, true, false);
    runOneIteration(videoElement, false, true, black, black, true, true, false);
    runOneIteration(videoElement, false, true, green, red, false, false, false);
    runOneIteration(videoElement, false, false, red, green, false, false, false);
    runOneIteration(videoElement, true, true, green, red, false, false, false);
    runOneIteration(videoElement, true, false, red, green, false, false, false);

    glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
    finishTest();
}
</script>
</head>
<body onload="init()">
<canvas id="example" width="64" height="48"></canvas>
<div id="description"></div>
<div id="console"></div>
<video id="vid" style="display:none;">
  <source src="../resources/npot-video.mp4"  type='video/mp4; codecs="avc1.42E01E"' />
  <source src="../resources/npot-video.webmvp8.webm" type='video/webm; codecs="vp8"' />
  <source src="../resources/npot-video.theora.ogv"  type='video/ogg; codecs="theora"' />
</video>
</body>
</html>
