<html>
    <head>
        <title>Test of 'played' attribute</title>
        <script src=video-test.js></script>
        <script src=video-played.js></script>
        <script>
    
            var testFunctions = 
            [ 
                PlayWithNoRanges,
                CreateANewRange,
                JumpAndCollapseTwoRanges,
                TestLoopingAndPassToTheEnd
            ];
    
            // NOTE: Result details are not printed for this test because time values are different from machine
            // to machine and run to run. Commenting out the following line turns on detailed logging back on, which
            // can be useful for debugging test failure.
            disableFullTestDetailsPrinting(); 

            function PlayWithNoRanges()
            {
                consoleWrite("<br><b><em>Test playing when there are no ranges</em></b>");

                timeRangeCount = currentTimeRange = 0;
                runSilently("video.currentTime = 0.5");

                currentTimeRange++;
                startPlayingInNewRange();
            }
    

            function CreateANewRange()
            {
                consoleWrite("<br><b><em>Create a new range</em></b>");
        
                var newTime = (video.played.end(0) + 0.05).toFixed(2);
                runSilently("video.currentTime = " + newTime);

                startPlayingInNewRange();
            }

            function JumpAndCollapseTwoRanges()
            {
                consoleWrite("<br><b><em>Test playing from one range into another, should collapse the two ranges</em></b>");
    
                timeRangeCount--;
                currentTimeRange = timeRangeCount - 1;
                var startTime = expectedStartTimes[0] - 0.1;
                expectedStartTimes[0] = startTime;
                expectedEndTimes[0] = expectedEndTimes[1];

                willPauseInExistingRange = false;
                runSilently("video.currentTime = " + startTime);

                playForMillisecs(secToMilli(expectedEndTimes[1] - startTime + 0.1)); // Triggers pause()
            }

            function TestLoopingAndPassToTheEnd()
            {
                playForMillisecs(100); // Triggers pause()
                return;
                consoleWrite("<br><b><em>Test looping</em></b>");
    
                var newTime = (video.duration - 0.05).toFixed(2);
                runSilently("video.currentTime = " + newTime);
                run("video.loop = true");
                
                currentTimeRange = 0; // We'll end in the very first time range

                timeRangeCount++;
                expectedStartTimes[timeRangeCount-1] = newTime;
                expectedEndTimes[timeRangeCount-1] = video.duration.toFixed(2);

                willPauseInExistingRange = true;
                willExtendAnExistingRange = true;

                playForMillisecs(100); // Triggers pause()
            }

        </script>
     </head>

<body onload="videoPlayedMain()">

    <video controls></video>
    <p>Test of the media element 'played' attribute</p>

</body>
</html>
