<!--

/*
** 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-utils.js"></script>
        <style>
            .pattern {
                white-space: nowrap;
                display: inline-block;
            }
            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(function() {
                    ctx2.drawImage(c3, 0, 0);
                    checkResult(ctx1, ctx2, preserve);
                });

            }
        </script>
    </head>
    <body>
        <div class="pattern">
            <canvas id='c1'></canvas>
            <canvas id='c2'></canvas>
            <canvas id='c3'></canvas>
        </div>
        <span>should look like</span>
        <div class="pattern">
            <div class='square'></div>
            <div class='square' style='background-color:black'></div>
            <div class='square'></div>
        </div>
        <hr />
        <div class="pattern">
            <canvas id='c4'></canvas>
            <canvas id='c5'></canvas>
            <canvas id='c6'></canvas>
        </div>
        <span>should look like</span>
        <div class="pattern">
            <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>
