<!DOCTYPE html>
<html>
    <head>
        <title>Selecting from a list of tracks</title>
        <script src="media-controls.js"></script>
        <script src="media-file.js"></script>
        <script src="video-test.js"></script>
        <script src="trackmenu-test.js"></script>
        <script>
            if (window.testRunner)
                testRunner.dumpAsText();

            function startTest()
            {
                consoleWrite("<br>*** Add another text track.");
                run('video.addTextTrack("captions", "Commentary", "ru")');
                showTrackMenu()
                window.setTimeout(turnCaptionsOn, 100);
                consoleWrite("");
            }

            function trackMenuList()
            {
                var trackListElement = getTrackListElement();
                if (!trackListElement)
                    return;
                // Track list should have a <ul> with <li> children (One of them is "Off").
                var trackList = trackListElement.querySelector("ul");
                if (!trackList) {
                    failTest("Could not find a child ul element in track list menu");
                    return;
                }
                var trackListItems = trackList.querySelectorAll("li");
                if (!trackListItems) {
                    failTest("Could not find child li elements in track list menu");
                    return;
                }

                return trackListItems;
            }

            function testMenu()
            {
                trackListItems = trackMenuList();
                var expectedItemCount = video.textTracks.length + 2;
                consoleWrite("There should be " + expectedItemCount + " items in the menu.");
                testExpected("trackListItems.length", expectedItemCount);
            }

            function selectCaptionMenuItem(index, nextStep)
            {
                // Click on the selected item
                var trackListItems = trackMenuList();
                var selectedTrackItem = trackListItems[index];
                var boundingRect = selectedTrackItem.getBoundingClientRect();
                var x = boundingRect.left + boundingRect.width / 2;
                var y = boundingRect.top + boundingRect.height / 2;
                eventSender.mouseMoveTo(x, y);
                eventSender.mouseDown();
                eventSender.mouseUp();
                window.setTimeout(function() { testMenu(); nextStep(); }, 100);
            }

            function turnCaptionsOn()
            {
                consoleWrite("*** Turning captions on");
                // Click on the third item, which is the second track (Off is the first item, Automatic is second)
                selectCaptionMenuItem(3, testCaptionsVisible);
            }

            function testCaptionsVisible()
            {
                testExpected("video.textTracks.length", 4);
                consoleWrite("Track 0 should be showing");
                testExpected("video.textTracks[0].mode", "showing");
                consoleWrite("Track 1 should be disabled");
                testExpected("video.textTracks[1].mode", "disabled");
                consoleWrite("Track 2 should be disabled");
                testExpected("video.textTracks[2].mode", "disabled");
                consoleWrite("Track 3 should be disabled");
                testExpected("video.textTracks[3].mode", "disabled");
                testExpected("textTrackDisplayElement(video, 'display').innerText", "Lorem");

                consoleWrite("<br>*** Remove a track.");
                run('video.removeChild(document.querySelectorAll("track")[0])');

                clickCCButton();
                window.setTimeout(turnCaptionsOff, 100);
            }

            function turnCaptionsOff()
            {
                consoleWrite("*** Turning captions off");
                selectCaptionMenuItem(0, testCaptionsDisabled);
            }

            function testCaptionsDisabled()
            {
                testExpected("video.textTracks.length", 3);
                consoleWrite("Track 0 should be disabled");
                testExpected("video.textTracks[0].mode", "disabled");
                consoleWrite("Track 1 should be disabled");
                testExpected("video.textTracks[1].mode", "disabled");
                consoleWrite("Track 2 should be disabled");
                testExpected("video.textTracks[2].mode", "disabled");
                testExpected("textTrackDisplayElement(video, 'display').innerText", "Lorem");
                endTest();
            }

            function start()
            {
                findMediaElement();
                video.src = findMediaFile('video', 'content/test');
                waitForEvent('canplaythrough', function () { startTrackMenuTest(startTest); });
            }
        </script>
    </head>

    <body onload="start()">
        <p>Test that we are able to trigger the list of captions, and select from the list.</p>
        <video width="500" height="300" controls>
            <track kind="captions" src="track/captions-webvtt/captions-fast.vtt" srclang="fr">
            <track kind="captions" src="track/captions-webvtt/captions-fast.vtt" srclang="en">
            <track kind="captions" src="track/captions-webvtt/captions-fast.vtt" srclang="ja">
        </video>
    </body>
</html>

