<template>
<div class="word-timing-selector-root">
    <span>{{ minTime }}</span>

    <div class="words-container" ref="wordsContainer">
        <input type="range" class="slider-continuous" ref="slider" />

        <div class="surround-word" v-for="word in mySurroundingWords" :key="word.id" :style="{ left: word.left, width: word.length }">
            <span>{{ word.word }}</span>
        </div>
    </div>

    <span>{{ maxTime }}</span>
</div>
</template>

<style scoped lang="scss">
.word-timing-selector-root {
    display: flex;
    align-items: center;
    gap: 1em;
}

.words-container {
    flex-grow: 0.5;
    position: relative;
    height: 2.5em;
}

.surround-word {
    position: absolute;
    text-align: center;

    user-select: none;
    text-overflow: ellipsis;
    white-space: nowrap;

    overflow: hidden;
    background-color: rgba(var(--bg-color-raw), 0.3);
    border: 1px solid rgba(var(--bg-color-raw), 0.6);
}
</style>

<script>
import Util from "../js/Util"

class Word {
    constructor(word, startTime, endTime, left, length) {
        this.id = Util.generateUuid();
        this.word = word;
        this.startTime = startTime;
        this.endTime = endTime;
        this.left = `${left}px`;
        this.length = `${length}px`;
    }
}

export default {
    name: "WordTimingSelector",
    props: {
        /** @type {Array<{ word: String, startTime: Number, endTime: Number }>} */
        surroundingWords: Array,
        word: { word: String, startTime: Number, endTime: Number },
        upperBound: Number
    },
    data() {
        return {
            isMounted: false,
            mySurroundingWords: []
        }
    },
    emits: [ "update:word", "update:word" ],
    computed: {
        minTime() {
            if (this.surroundingWords.length === 0) {
                return 0;
            }

            return Util.formatSecondsTimeString(this.surroundingWords[0].startTime, false, 2);
        },
        maxTime() {
            if (this.surroundingWords.length === 0) {
                return 0;
            }

            return Util.formatSecondsTimeString(this.surroundingWords[this.surroundingWords.length - 1].endTime, false, 2);
        }
    },
    watch: {
        surroundingWords() {
            this.scaleWords();
        }
    },
    methods: {
        scaleWords() {
            if (!this.isMounted) {
                return;
            }

            const myWords = [];
            if (this.surroundingWords.length === 0) {
                return myWords;
            }

            const audioLength = this.surroundingWords[this.surroundingWords.length - 1].endTime - this.surroundingWords[0].startTime;
            const sliderLengthPx = this.$refs.slider.offsetWidth;

            const scalingFactor = sliderLengthPx / audioLength;

            const offset = this.surroundingWords[0].startTime * scalingFactor;

            for (const word of this.surroundingWords) {
                const left = (word.startTime * scalingFactor - offset);
                const length = (word.endTime - word.startTime) * scalingFactor;

                myWords.push(new Word(word.word, word.startTime, word.endTime, left, length));
            }

            this.mySurroundingWords = myWords;
        }
    },
    mounted() {
        this.isMounted = true;
        this.scaleWords();
    }
}
</script>
