<html>
<head>
<title>WebGL Canvas probablySupportsContext Tests</title>
<script src="../../../resources/js-test.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script>
var type2d = "2d";
var type3dlegacy = "webkit-3d";
var type3dprovisional = "experimental-webgl";
var type3dmoz = "moz-webgl";

function print_basic_results(supports, context, args_str)
{
    if (context && !supports)
        testFailed(type_of_context + " context exists yet canvas.probablySupportsContext(" + args_str + ") returns false");
    else
        testPassed("probablySupportsContext(" + args_str + ") is consistent with getContext(" + args_str + ")");

    if (supports)
        testPassed("probablySupportsContext(" + args_str + ") returns true");
    else
        testFailed("probablySupportsContext(" + args_str + ") returns false");

    if (context) {
        testPassed("getContext(" + args_str + ") returns true (context exists)");
        return true;
    } else {
        testFailed("getContext(" + args_str + ") returns false (context does not exist)");
        return false;
    }
}

function other_type_of_context(type_of_context)
{
    if (type_of_context == type2d)
        return type3dlegacy;
    else if ((type_of_context == type3dlegacy) || (type_of_context == type3dprovisional))
        return type2d;
    else
        return "";
}

function test_post_creation(canvas, type_of_context)
{
    debug("Testing getContext and probablySupportsContext('" + type_of_context + "') after a context is created");

    if (canvas.probablySupportsContext(type_of_context))
        testPassed("probablySupportsContext('" + type_of_context + "') returns true");
    else
        testFailed("probablySupportsContext('" + type_of_context + "') returns false");

    var other_type = other_type_of_context(type_of_context);
    
    if (!other_type) {
        testFailed(type_of_context + ' not currently supported');
        return;
    }

    if (!canvas.probablySupportsContext(other_type))
        testPassed("probablySupportsContext('" + other_type + "') returns false");
    else
        testFailed("probablySupportsContext('" + other_type + "') returns true");

    if (!canvas.getContext(other_type))
        testPassed(other_type + " context does not exist");
    else
        testFailed(other_type + " context exists");

}

function check_context(type_of_context)
{
    debug("");
    debug("Canvas.probablySupportsContext('" + type_of_context + "')");
    debug("");

    var canvas = document.createElement("canvas");
    var supports = canvas.probablySupportsContext(type_of_context);
    var context = canvas.getContext(type_of_context);

    if(print_basic_results(supports, context, "'" + type_of_context + "'"))
        test_post_creation(canvas, type_of_context);
}

function malformed_attrs(attrs, attrs_str)
{
    type_of_context = type3dlegacy;

    debug("");
    debug("canvas.probablySupportsContext('" + type_of_context + "' ," + attrs_str + ")");
    debug("");

    var canvas = document.createElement("canvas");
    var supports;
    try {
        supports = canvas.probablySupportsContext(type_of_context, attrs);
    } catch (e) { } finally {
        if (typeof(supports) == typeof(undefined))
            testPassed("supports is undefined");
        else
            testFailed("supports is not undefined");
    }

    var context;
    try {
        context = canvas.getContext(type_of_context, attrs);
    } catch (e) { } finally {
        if (typeof(context) == typeof(undefined))
            testPassed("context is undefined");
        else
            testFailed("context is not undefined");

    }

    print_basic_results(supports, context, "'" + type_of_context + "' ," + attrs_str);
}

function run_tests()
{
    description("This test ensures WebGL implementations interact correctly with the canvas tag's probablySupportsContext function, that getContext and probablySupportsContext are implemented consistently with one another, and that malformed parameters to probablySupportsContext are handled correctly.");

    check_context(type2d);

    debug("");
    debug("WebGL disabled");
    window.testRunner.overridePreference("WebKitWebGLEnabled", "0");

    check_context(type3dlegacy);
    check_context(type3dprovisional);
    check_context(type3dmoz); // "moz-webgl" is not supported in WK2, but was used in create3DContext

    debug("");
    debug("WebGL enabled");
    window.testRunner.overridePreference("WebKitWebGLEnabled", "1");

    check_context(type3dlegacy);
    check_context(type3dprovisional);
    check_context(type3dmoz);

    debug("");
    debug("Testing malformed attributes that cause probablySupportsContext and getContext to be undefined");

    malformed_attrs({ get alpha() { throw 'Test alpha Error'; } }, 
        "{ get alpha() { throw 'Test alpha Error'; } }");
    malformed_attrs({ get depth() { throw 'Test depth Error'; } }, 
        "{ get depth() { throw 'Test depth Error'; } }");
    malformed_attrs({ get stencil() { throw 'Test stencil Error'; } }, 
        "{ get stencil() { throw 'Test stencil Error'; } }");
    malformed_attrs({ get antialias() { throw 'Test antialias Error'; } }, 
        "{ get antialias() { throw 'Test antialias Error'; } }");
    malformed_attrs({ get premultipliedAlpha() { throw 'premultipliedAlpha Error'; } }, 
        "{ get premultipliedAlpha() { throw 'Test premultipliedAlpha Error'; } }");
    malformed_attrs({ get preserveDrawingBuffer() { throw 'preserveDrawingBuffer Error'; } }, 
        "{ get preserveDrawingBUffer() { throw 'Test preserveDrawingBuffer Error'; } }");

    debug("");
    debug("Testing how probablySupportsContext handles no parameters");
    shouldBeFalse("document.createElement('canvas').probablySupportsContext()");

    debug("");
}

run_tests();
</script>
</body>
</html>