<!--

/*
** 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>
        <style>
            canvas {
                width:50px;
                height:50px;
            }
            .square {
                display:inline-block;
                width:50px;
                height:50px;
                background-color:red;
            }
        </style>
        <script>
            "use strict";
            var wtu = WebGLTestUtils;
            function checkResult(ctx1, ctx2, preserve) {
                var imgData1 = ctx1.getImageData(0,0,1,1);
                var imgData2 = ctx2.getImageData(0,0,1,1);
                var correct1 = [255,0,0,255];
                var correct2 = preserve ? [255,0,0,255] : [0,0,0,255];
                var ok1 = true;
                var ok2 = true;
                for (var p = 0; p < 4; ++p) {
                    if (imgData1.data[p] != correct1[p])
                        ok1 = false;
                    if (imgData2.data[p] != correct2[p])
                        ok2 = false;
                }
                if (ok1 && ok2)
                    testPassed('Rendered ok with preserveDrawingBuffer ' + preserve +'.');
                else
                    testFailed('Did not render ok with preserveDrawingBuffer ' + preserve + '.');
                if (preserve) {
                    finishTest()
                } else {
                    runTest(true);
                }
            }

            function runTest(preserve) {
                var c1 = document.getElementById('c' + (preserve * 3 + 1));
                var c2 = document.getElementById('c' + (preserve * 3 + 2));
                var c3 = document.getElementById('c' + (preserve * 3 + 3));
                var ctx1 = c1.getContext('2d');
                var ctx2 = c2.getContext('2d');
                var gl = wtu.create3DContext(c3, { alpha:false, preserveDrawingBuffer:preserve });
                gl.clearColor(1, 0, 0, 1);
                gl.clear(gl.COLOR_BUFFER_BIT);
                ctx1.drawImage(c3, 0, 0);
                wtu.waitForComposite(gl, function() {
                    ctx2.drawImage(c3, 0, 0);
                    checkResult(ctx1, ctx2, preserve);
                });

            }
        </script>
    </head>
    <body>
        <div>
            <canvas id='c1'></canvas>
            <canvas id='c2'></canvas>
            <canvas id='c3'></canvas>
            <span>should look as right pattern</span>
            <div class='square'></div>
            <div class='square' style='background-color:black'></div>
            <div class='square'></div>
        </div>
        <div>
            <canvas id='c4'></canvas>
            <canvas id='c5'></canvas>
            <canvas id='c6'></canvas>
            <span>should look as right pattern</span>
            <div class='square'></div>
            <div class='square'></div>
            <div class='square'></div>
        </div>
        <div id="description"></div>
        <div id="console"></div>
        <script>
            "use strict";
            description('Verify that preserveDrawingBuffer attribute is honored.');
            runTest(false);
            var successfullyParsed = true;
            shouldBeTrue("successfullyParsed");
        </script>
    </body>
</html>
