<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>

<script>
description("Tests XMLHttpRequest 'arraybuffer' loading with the .responseType and .response attributes.");

var xhr = 0;
var lastState = 0;

function stateChange() {
    // Protect against race-condition where .onreadystatechange sometimes will be called multiple times for the same state.
    if (xhr.readyState == lastState)
        return;
    lastState = xhr.readyState;
    
    if (xhr.readyState == XMLHttpRequest.DONE) {
        // Check that .response exists when .readyState is DONE
        if (xhr.response)
            testPassed("'arraybuffer' .response exists when .readyState is " + xhr.readyState + ".");
        else
            testFailed("'arraybuffer' .response should exist when .readyState is " + xhr.readyState + ".");
    } else {
        // Otherwise, for 'arraybuffer' the .response should not yet exist.
        if (!xhr.response)
            testPassed("'arraybuffer' .response does not exist when .readyState is " + xhr.readyState + ".");
        else
            testFailed("'arraybuffer' .response should not exist when .readyState is " + xhr.readyState + ".");
    }
}

function logBytesAtOffset(buffer8, offset) {
    var s = "bytes at offset " + offset + " : ";
    for (var i = 0; i < 8; ++i)
        s += buffer8[i + offset].toString(16) + ' ';
    
    debug(s);
}

function load() {
    testPassed('DONE LOADING');
    testPassed('received response object : ' + xhr.response + ".");

    // Make sure exception is thrown if responseType is set too late in the loading process.
    try {
        xhr.responseType = "text";
    } catch(e) {
        testPassed("exception correctly thrown when xhr.responseType is set to valid value too late in the loading process : " + e + ".");
    }

    var buffer = xhr.response;

    // Interpret the ArrayBuffer as Uint8Array.
    var buffer8 = new Uint8Array(buffer);
    buffer8.set(buffer);

    var totalLength = buffer8.length;
    debug('response length : ' + totalLength + ".");
    
    // Log the bytes at the start, in the middle, and near the end:
    logBytesAtOffset(buffer8, 0);
    logBytesAtOffset(buffer8, 0x5720A);
    logBytesAtOffset(buffer8, 0xA39D6);
    
    // Calculate checksum.
    var sum = 0;
    for (var i = 0; i < totalLength; ++i) {
        sum += buffer8[i];
    }
    
    debug('checksum : ' + sum);

    // Check that xhr.responseText throws an exception:
    try {
        var x = xhr.responseText;
    } catch(e) {
        testPassed("exception correctly thrown when xhr.responseText is accessed but responseType is 'arraybuffer' : " + e + ".");
    }

    // Check that xhr.responseXML throws an exception:
    try {
        var x = xhr.responseXML;
    } catch(e) {
        testPassed("exception correctly thrown when xhr.responseXML is accessed but responseType is 'arraybuffer' : " + e + ".");
    }
    
    // Test .response garbage collection.
    xhr.response.foo = "bar";
    gc();
    shouldBe("xhr.response.foo", "'bar'");    

    xhr = null;
    finishJSTest();
}

function runTest() {
    if (window.testRunner) {
        testRunner.dumpAsText();
        testRunner.waitUntilDone();
    }

    xhr = new XMLHttpRequest();
    xhr.onreadystatechange = stateChange;
    xhr.onload = load;
    xhr.open("GET", "../../http/tests/resources/balls-of-the-orient.aif", true);
        
    try {
        if ("responseType" in xhr)
            testPassed("responseType property exists.");

        if ("response" in xhr)
            testPassed("response property exists.");
            
        if (xhr.responseType == "")
            testPassed("xhr.responseType is initially set to default value of empty string.");

        // Make sure we can set responseType to valid values before send() is called.
        try {
            xhr.responseType = "";
            if (xhr.responseType == "")
                testPassed("xhr.responseType has been correctly set to ''.");

            xhr.responseType = "text";
            if (xhr.responseType == "text")
                testPassed("xhr.responseType has been correctly set to 'text'.");

            xhr.responseType = "document";
            if (xhr.responseType == "document")
                testPassed("xhr.responseType has been correctly set to 'document'.");

            xhr.responseType = "arraybuffer";
            if (xhr.responseType == "arraybuffer")
                testPassed("xhr.responseType has been correctly set to 'arraybuffer'.");
        } catch(e) {
            testFailed("unable to set xhr.responseType to a valid value " + e + ".");
        }
    } catch(e) {
        testFailed("Caught exception " + e + ".");
    }

    xhr.send(null);
    window.jsTestIsAsync = true;
}

runTest();

</script>

<script src="../../resources/js-test-post.js"></script>
</body>
</html>
