<!DOCTYPE html>
<title>Test to make sure a "source" moved after the media element begins processing is handled correctly.</title>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="media-file.js"></script>
<script>
for(var i = 0; i < 7; i++) {
    async_test(function(t) {
        var testInfo = [
            { func : moveToEnd, errorCount : 0, moved : null, elementToMove: function(video, current) {
                // Moving previous "source" element to end of list, it should be processed again.
                return video.removeChild(current.previousSibling);
            } },
            { func : moveToEnd, errorCount : 0, moved : null, elementToMove: function(video, current) {
                // Moving current "source" element, it should be processed again.
                return video.removeChild(current);
            } },
            { func : moveToEnd, errorCount : 0, moved : null, elementToMove: function(video, current) {
                // Moving next "source" element, it should be processed again.
                return video.removeChild(current.nextSibling);
            } },
            { func : moveEarlier, errorCount : 0, moved : null, elementToMove: function(video, current) {
                // Moving current "source" element to beginning of list, it should not be processed again.
                return video.removeChild(current);
            } },
            { func : moveEarlier, errorCount : 0, moved : null, elementToMove: function(video, current) {
                // Moving next "source" element to beginning of list, it should never processed.
                return video.removeChild(current.nextSibling);
            } },
            { func : moveEarlier, errorCount : 0, moved : null, elementToMove: function(video, current) {
                // span inserted after current "source" element before it is removed, processing should proceed normally.
                var span = document.createElement("span")
                span.appendChild(document.createTextNode("Your browser doesn't support HTML5 video!"));
                video.insertBefore(span, current.nextSibling);
                return video.removeChild(current);
            } },
            { func : moveEarlier, errorCount : 0, moved : null, elementToMove: function(video, current) {
                // span inserted after next "source" element before it is removed, processing should proceed normally.
                var span = document.createElement("span")
                span.appendChild(document.createTextNode("Your browser doesn't support HTML5 video!"));
                video.insertBefore(span, current.nextSibling.nextSibling);
                return video.removeChild(current.nextSibling);
            } }
        ];

        var test = testInfo[i];
        var video = document.createElement("video");

        // Add a bunch of source elements with bogus urls because we want to rearrange
        // elements after the media engine begins processing sources, and we can't predict
        // the delay between when the media element fires an "error" event and our handler
        // is called, but we need to guarantee that there are <source> elements that
        // haven't been processed when we run the test.
        for (var index = 1; index <= 10; index++)
            addSource(index);

        function addSource(index) {
            var source = document.createElement("source");
            source.src = index + "-" + Date.now() + ".ogv";
            source.type = mimeTypeForExtension(source.src.split(".").pop());
            video.appendChild(source);

            source.onerror = t.step_func(function(event) {
                test.func(event);
            });
        }

        function findCurrentSourceElement() {
            var sources = video.childNodes;
            var currentSrc = video.currentSrc;
            var index;
            for (index = 0; index < sources.length; ++index) {
                if (sources[index].src == currentSrc)
                    break;
            }

            assert_less_than(index, sources.length, currentSrc + " not found in <source> list");
            return sources[index];
        }

        function moveEarlier(event) {
            switch (++test.errorCount) {
            case 1:
                // Do nothing on the first error event
                break;

            case 2:
                var current = findCurrentSourceElement();
                test.moved = test.elementToMove(video, current);
                assert_not_equals(test.moved, null);
                video.insertBefore(test.moved, video.firstChild);
                break;

            default:
                // We should never get an error for the element we moved.
                assert_not_equals(event.target, test.moved);
                if (event.target.nextSibling == null)
                    t.done();
                break;
            }
        }

        function moveToEnd(event) {
            switch (++test.errorCount) {
            case 1:
                // Do nothing on the first error event
                break;

            case 2:
                var current = findCurrentSourceElement();
                test.moved = test.elementToMove(video, current);
                assert_not_equals(test.moved, null);
                video.appendChild(test.moved);
                break;

            default:
                assert_true(event.target == test.moved || event.target.nextSibling != null);
                if (event.target == test.moved)
                    t.done();
                break;
            }
        }
    });
}
</script>