<script src="../../../resources/js-test-pre.js"></script>
<script src="../resources/media-controls-loader.js" type="text/javascript"></script>
<script src="../resources/media-controls-utils.js" type="text/javascript"></script>
<body>
<script type="text/javascript">

window.jsTestIsAsync = true;

description("Testing the <code>TimeLabel</code> class.");

const timeLabel = new TimeLabel;

shouldBe("timeLabel.value", "0");
shouldBeEqualToString("timeLabel.element.localName", "div");
shouldBeEqualToString("timeLabel.element.className", "time-label");

timeLabel.element.id = "elasped";

const NaNTimeLabel = new TimeLabel;
NaNTimeLabel.setValueWithNumberOfDigits(NaN, 4);

const digits = [3, 4, 5, 6];
let elapsedTimeLabels = new Map;
let remainingTimeLabels = new Map;
for (let numberOfDigits of digits) {
    elapsedTimeLabels[numberOfDigits] = new TimeLabel(TimeLabel.Types.Elapsed);
    elapsedTimeLabels[numberOfDigits].setValueWithNumberOfDigits(1, numberOfDigits);
    remainingTimeLabels[numberOfDigits] = new TimeLabel(TimeLabel.Types.Remaining);
    remainingTimeLabels[numberOfDigits].setValueWithNumberOfDigits(1, numberOfDigits);
}

const remainingTimeLabel = new TimeLabel(TimeLabel.Types.Remaining);
remainingTimeLabel.element.id = "remaining";
remainingTimeLabel.setValueWithNumberOfDigits(0, 4);

const elaspedTimeLabel = new TimeLabel(TimeLabel.Types.Elasped);
elaspedTimeLabel.element.id = "elasped";
elaspedTimeLabel.setValueWithNumberOfDigits(0, 4);

let style;
let elaspedLabel;
let remainingLabel;
scheduler.frameDidFire = function()
{
    document.body.appendChild(timeLabel.element);
    document.body.appendChild(remainingTimeLabel.element);
    document.body.appendChild(elaspedTimeLabel.element);

    style = window.getComputedStyle(timeLabel.element);

    shouldBeEqualToString("style.position", "absolute");
    shouldBeEqualToString("style.fontFamily", "-apple-system-monospaced-numbers");
    shouldBeEqualToString("style.fontSize", "12px");

    debug("");
    debug(`NaNTimeLabel.element.textContent = ${NaNTimeLabel.element.textContent}`);

    debug("");

    elaspedLabel = elaspedTimeLabel.element.getAttribute("aria-label").split(":")[0];
    remainingLabel = remainingTimeLabel.element.getAttribute("aria-label").split(":")[0];
    shouldBeEqualToString("elaspedLabel", "Elapsed");
    shouldBeEqualToString("remainingLabel", "Remaining");

    timeLabel.element.remove();
    remainingTimeLabel.element.remove();
    elaspedTimeLabel.element.remove();

    for (numberOfDigits of digits) {
        debug("");
        debug(`elapsedTimeLabels[${numberOfDigits}].element.textContent = ${elapsedTimeLabels[numberOfDigits].element.textContent}`);
        debug(`elapsedTimeLabels[${numberOfDigits}].width = ${elapsedTimeLabels[numberOfDigits].width}`);
        debug(`remainingTimeLabels[${numberOfDigits}].element.textContent = ${remainingTimeLabels[numberOfDigits].element.textContent}`);
        debug(`remainingTimeLabels[${numberOfDigits}].width = ${remainingTimeLabels[numberOfDigits].width}`);
    }

    debug("");
    finishMediaControlsTest();
};

</script>
<script src="../../../resources/js-test-post.js"></script>
</body>
