<!DOCTYPE html>
<html>
<head>
<meta charset="ks_c_5601-1989"> <!-- test breaks if the server overrides this -->
<title>ks_c_5601-1989 encoding (form)</title>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="euckr_index.js"></script>
<script src="euckr-encoder.js"></script>
<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
<link rel="help" href="https://encoding.spec.whatwg.org/#names-and-labels">
<meta name="assert" content="The browser produces the same encoding behavior for a document labeled 'ks_c_5601-1989' as for a document labeled 'euc-kr'.">
<style>
 iframe { display:none }
 form { display:none }
</style>
</head>
<body>
<div id="log"></div>
<script>
var tests = [];
var cplist = [];
var numTests = null;
var numFrames = 2;
var chunkSize = 500;
var numChunks = null;
var frames = null;
var frames = null;
var forms = null;
var seperator = ",";
var encodedSeperator = encodeURIComponent(",");
var currentChunkIndex = 0;

// set up a sparse array of all unicode codepoints listed in the index
// this will be used for lookup in getByteSequence
var indexcodepoints = []; // index is unicode cp, value is pointer
for (p = 0; p < euckr.length; p++) {
    if (euckr[p] != null && indexcodepoints[euckr[p]] == null) {
        indexcodepoints[euckr[p]] = p;
    }
}

setup(function() {
    // create a simple list of just those code points for which there is an encoding possible
    codepoints = [];
    for (var i = 0x80; i < 0xffff; i++) {
        result = euckrEncoder(String.fromCodePoint(i));
        if (result) {
            var item = {};
            codepoints.push(item);
            item.cp = i;
            item.expected = "%" + result.replace(/ /g, "%");
        }
    }

    // convert the information into a simple array of objects that can be easily traversed
    var currentChunk = [];
    var currentTests = [];
    cplist = [currentChunk];
    tests = [currentTests];
    for (i = 0; i < codepoints.length; i++) {
        if (currentChunk.length == chunkSize) {
            currentChunk = [];
            cplist.push(currentChunk);
            currentTests = [];
            tests.push(currentTests);
        }
        var item = {};
        currentChunk.push(item);
        item.cp = codepoints[i].cp;
        item.expected = codepoints[i].expected;
        currentTests.push(
            async_test(
                "U+" +
                    item.cp.toString(16).toUpperCase() +
                    " " +
                    String.fromCodePoint(item.cp) +
                    " " +
                    item.expected
            )
        );
    }

    numChunks = cplist.length;

    for (var i = 0; i < numFrames; i++) {
        var frame = document.createElement("iframe");
        frame.id = frame.name = "frame-" + i;
        document.body.appendChild(frame);
        var form = document.createElement("form");
        form.id = "form-" + i;
        form.method = "GET";
        form.action = "/common/blank.html";
        form.acceptCharset = "ks_c_5601-1989";
        form.target = frame.id;
        var input = document.createElement("input");
        input.id = input.name = "input-" + i;
        form.appendChild(input);
        document.body.appendChild(form);
    }

    addEventListener("load", function() {
        frames = Array.prototype.slice.call(
            document.getElementsByTagName("iframe")
        );
        forms = Array.prototype.slice.call(
            document.getElementsByTagName("form")
        );
        inputs = Array.prototype.slice.call(
            document.getElementsByTagName("input")
        );
        for (var i = 0; i < Math.min(numFrames, numChunks); i++) {
            runNext(i);
        }
    });
});

function runNext(id) {
    var i = currentChunkIndex;
    currentChunkIndex += 1;

    var iframe = frames[id];
    var form = forms[id];
    var input = inputs[id];

    input.value = cplist[i]
        .map(function(x) {
            return String.fromCodePoint(x.cp);
        })
        .join(seperator);
    form.submit();

    iframe.onload = function() {
        var url = iframe.contentWindow.location;
        var query = url.search;
        var result_string = query.substr(query.indexOf("=") + 1);
        var results = result_string.split(encodedSeperator);

        for (var j = 0; j < cplist[i].length; j++) {
            var t = tests[i][j];
            t.step(function() {
                assert_equals(
                    normalizeStr(results[j]),
                    normalizeStr(cplist[i][j].expected)
                );
            });
            t.done();
        }
        if (currentChunkIndex < numChunks) {
            runNext(id);
        }
    };
}
</script>
</body>
</html>
