<!DOCTYPE html>
<title>Test that user preference for text track kind is honored.</title>
<script src="../media-file.js"></script>
<script src="../media-controls.js"></script>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<video>
    <track src="captions-webvtt/styling.vtt" kind="captions" srclang="de">
    <track src="captions-webvtt/styling.vtt" kind="captions" srclang="es">
    <track src="captions-webvtt/styling.vtt" kind="captions" srclang="en">
    <track src="captions-webvtt/styling.vtt" kind="subtitles" srclang="fr">
    <track src="captions-webvtt/styling.vtt" kind="subtitles" srclang="es">
    <track src="captions-webvtt/styling.vtt" kind="subtitles" srclang="ar" default>
    <track src="captions-webvtt/styling.vtt" kind="captions" srclang="fr" default>
</video>
<script>
async_test(function(t) {
    var video = document.querySelector("video");
    t.add_cleanup(function() {
        internals.setUserPreferredLanguages([]);
        internals.settings.setTextTrackKindUserPreference("default");
    });
    internals.setUserPreferredLanguages(["jp", "es", "en", "fr"]);
    video.src = findMediaFile("video", "../content/test");

    var tracks;
    var expectedTrack;
    video.oncanplaythrough = t.step_func(function() {
        tracks = video.textTracks;
        assert_equals(tracks.length, 7);
        testUserPreferencesDefault();
        testUserPreferencesSubtitles();
        testUserPreferencesCaptions();
    });

    function testUserPreferencesDefault() {
        // User preference is initialized to pick tracks marked as default.
        // When multiple default tracks exist, pick the first default track.
        expectedTrack = tracks[5];
        checkExpected("showing", "subtitles", "ar");
    }

    function testUserPreferencesSubtitles() {
        internals.settings.setTextTrackKindUserPreference("subtitles");
        // Displays subtitle track over caption track when both exist in the same language.
        expectedTrack = tracks[4];
        checkExpected("showing", "subtitles", "es");
    }

    function testUserPreferencesCaptions() {
        internals.settings.setTextTrackKindUserPreference("captions");
        expectedTrack = tracks[1];
        checkExpected("showing", "captions", "es");

        // Add a subtitle track in user"s first preferred language "jp".
        // This track must be displayed over a caption track with a
        // language less preferred by the user.
        var track = document.createElement("track");
        track.setAttribute("kind", "subtitles");
        track.setAttribute("src", "captions-webvtt/styling.vtt");
        track.setAttribute("srclang", "jp");

        track.onload = t.step_func_done(trackLoaded);
        video.appendChild(track);
    }

    function trackLoaded() {
        track = event.target;
        expectedTrack = track.track;
        assert_equals(track.readyState, HTMLTrackElement.LOADED);
        checkExpected("showing", "subtitles", "jp");
    }

    function checkExpected(mode, kind, language) {
        assert_equals(expectedTrack.mode, mode);
        assert_equals(expectedTrack.kind, kind);
        assert_equals(expectedTrack.language, language);
    }
});
</script>