"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (g && (g = 0, op[0] && (_ = 0)), _) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var Player = /** @class */ (function () {
    function Player(playlist) {
        var _this = this;
        this.stateChangedHandlers = [];
        this.playlist = playlist;
        var controls = getOrThrow(document.getElementById('controls'));
        var timeVolume = getOrThrow(document.getElementById('timeVolume'));
        this.nowPlaying = getOrThrow(document.getElementById('nowPlaying'));
        this.rewButton = getOrThrow(controls.getElementsByTagName('button').item(0));
        this.playButton = getOrThrow(controls.getElementsByTagName('button').item(1));
        this.playButtonPath = getOrThrow(this.playButton.getElementsByTagName('path').item(0));
        this.ffwButton = getOrThrow(controls.getElementsByTagName('button').item(2));
        this.skipButton = getOrThrow(controls.getElementsByTagName('button').item(3));
        this.cover = getOrThrow(this.nowPlaying.getElementsByTagName('img').item(0));
        this.seriesName = getOrThrow(this.nowPlaying.getElementsByTagName('span').item(0));
        this.episodeName = getOrThrow(this.nowPlaying.getElementsByTagName('span').item(1));
        this.timeDisplay = getOrThrow(timeVolume.getElementsByTagName('span').item(0));
        this.volumeSlider = getOrThrow(timeVolume.getElementsByTagName('input').item(0));
        this.progress = getOrThrow(document.getElementById('progress'));
        this.ticker = null;
        this.howl = null;
        this.episode = null;
        // initialize to stopped state
        this.stopPlaybackAndResetUi();
        // wire up static ui elements
        this.playButton.addEventListener('click', function () { return _this.playPause(); });
        this.rewButton.addEventListener('click', function () { return _this.rewind(); });
        this.ffwButton.addEventListener('click', function () { return _this.fastForward(); });
        this.skipButton.addEventListener('click', function () { return _this.nextEpisode(); });
        this.volumeSlider.addEventListener('change', function () { return _this.setVolume(); });
        // wire up mediaSession events
        if ('mediaSession' in navigator) {
            navigator.mediaSession.setActionHandler('pause', function () { return _this.playPause(); });
            navigator.mediaSession.setActionHandler('play', function () { return _this.playPause(); });
            navigator.mediaSession.setActionHandler('stop', function () {
                return _this.stopPlaybackAndResetUi();
            });
            navigator.mediaSession.setActionHandler('seekforward', function () {
                return _this.fastForward();
            });
            navigator.mediaSession.setActionHandler('seekbackward', function () {
                return _this.rewind();
            });
            navigator.mediaSession.setActionHandler('nexttrack', function () {
                return _this.nextEpisode();
            });
            // don't support previous track yet, queue removes them once finished
            // wire this up to rewind instead
            navigator.mediaSession.setActionHandler('previoustrack', function () {
                return _this.rewind();
            });
        }
        // set up playlist changed handler
        this.playlist.addPlaylistChangedHandler(function () {
            _this.skipButton.disabled = !_this.playlist.hasNextEpisode();
        });
    }
    Player.prototype.addStateChangedHandler = function (handler) {
        this.stateChangedHandlers.push(handler);
    };
    Player.prototype.currentEpisode = function () {
        return this.episode;
    };
    Player.prototype.playEpisode = function (episode, paused) {
        var _this = this;
        if (paused === void 0) { paused = false; }
        this.stopPlaybackAndResetUi();
        this.setPauseButtonUI();
        this.episode = episode;
        this.playlist.removeEpisode(episode, false, false);
        this.updateNowPlayingUI(true);
        void fetch("/api/r/".concat(episode.file))
            .then(function (res) { return __awaiter(_this, void 0, void 0, function () {
            var link;
            var _this = this;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!res.ok) {
                            this.setErrorUI("Error fetching episode (".concat(res.status, ")"));
                            return [2 /*return*/];
                        }
                        return [4 /*yield*/, res.json()];
                    case 1:
                        link = _a.sent();
                        if (this.howl)
                            this.howl.unload();
                        this.howl = new Howl({
                            src: "".concat(link.url, "?Authorization=").concat(link.token),
                            html5: true,
                            autoplay: !paused,
                            volume: this.getVolume(),
                            onload: function () {
                                _this.updateTimeUI();
                                _this.sendMediaSessionMetadata();
                                _this.updateNowPlayingUI();
                                _this.sendMediaSessionMetadata();
                                if (paused)
                                    _this.setPlayButtonUI();
                            },
                            onplay: function () {
                                _this.setPauseButtonUI();
                                _this.startTicker();
                                for (var _i = 0, _a = _this.stateChangedHandlers; _i < _a.length; _i++) {
                                    var handler = _a[_i];
                                    handler();
                                }
                            },
                            onpause: function () {
                                _this.setPlayButtonUI();
                                _this.stopTicker();
                                for (var _i = 0, _a = _this.stateChangedHandlers; _i < _a.length; _i++) {
                                    var handler = _a[_i];
                                    handler();
                                }
                            },
                            onend: function () { return _this.nextEpisode(); },
                            onloaderror: function () { return _this.setErrorUI('Error playing episode.'); },
                        });
                        return [2 /*return*/];
                }
            });
        }); })
            .catch(function () {
            _this.setErrorUI('Error downloading episode.');
        });
    };
    Player.prototype.isPlaying = function () {
        if (this.howl) {
            return this.howl.playing();
        }
        return false;
    };
    Player.prototype.playPause = function () {
        if (this.howl && this.howl.playing())
            this.howl.pause();
        else if (this.howl && !this.howl.playing())
            this.howl.play();
    };
    Player.prototype.stopPlaybackAndResetUi = function () {
        var _a;
        (_a = this.howl) === null || _a === void 0 ? void 0 : _a.unload();
        this.howl = null;
        this.episode = null;
        this.setPlayButtonUI();
        this.updateNowPlayingUI();
        this.sendMediaSessionMetadata();
        this.stopTicker();
        this.updateTimeUI();
        for (var _i = 0, _b = this.stateChangedHandlers; _i < _b.length; _i++) {
            var handler = _b[_i];
            handler();
        }
    };
    Player.prototype.nextEpisode = function () {
        var next = this.playlist.nextEpisode();
        if (next)
            this.playEpisode(next);
        else {
            this.stopPlaybackAndResetUi();
            // manually trigger playlist changed
            // so that currently playing media gets wiped
            this.playlist.triggerPlaylistChanged();
        }
    };
    Player.prototype.setErrorUI = function (message) {
        this.stopPlaybackAndResetUi();
        Toastify({
            text: message,
            gravity: 'bottom',
            position: 'right',
            stopOnFocus: false,
            style: {
                marginBottom: '10ex',
                background: '#a00',
                color: '#fff',
            },
        }).showToast();
    };
    Player.prototype.rewind = function () {
        if (this.howl && this.howl.state() === 'loaded') {
            var newPos = this.howl.seek() - 10;
            if (newPos < 0)
                newPos = 0;
            this.howl.seek(newPos);
            this.updateTimeUI();
        }
    };
    Player.prototype.fastForward = function () {
        if (this.howl && this.howl.state() === 'loaded') {
            var newPos = this.howl.seek() + 30;
            if (newPos > this.howl.duration())
                newPos = this.howl.duration();
            this.howl.seek(newPos);
            this.updateTimeUI();
        }
    };
    Player.prototype.setPlayButtonUI = function () {
        this.playButtonPath.setAttribute('d', 'M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM6.79 5.093A.5.5 0 0 0 6 5.5v5a.5.5 0 0 0 .79.407l3.5-2.5a.5.5 0 0 0 0-.814l-3.5-2.5z');
    };
    Player.prototype.setPauseButtonUI = function () {
        this.playButtonPath.setAttribute('d', 'M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM6.25 5C5.56 5 5 5.56 5 6.25v3.5a1.25 1.25 0 1 0 2.5 0v-3.5C7.5 5.56 6.94 5 6.25 5zm3.5 0c-.69 0-1.25.56-1.25 1.25v3.5a1.25 1.25 0 1 0 2.5 0v-3.5C11 5.56 10.44 5 9.75 5z');
    };
    Player.prototype.getVolume = function () {
        return parseFloat(this.volumeSlider.value) / 100;
    };
    Player.prototype.setVolume = function () {
        var _a;
        (_a = this.howl) === null || _a === void 0 ? void 0 : _a.volume(this.getVolume());
    };
    Player.prototype.updateNowPlayingUI = function (loading) {
        if (loading === void 0) { loading = false; }
        this.nowPlaying.classList.remove('error');
        if (this.episode) {
            this.seriesName.innerHTML = loading
                ? 'Loading episode'
                : this.episode.series.title;
            this.episodeName.innerHTML = this.episode.title;
            this.cover.src = loading ? '/loading.gif' : this.episode.series.cover;
            this.nowPlaying.title = "".concat(this.episode.series.title, "\n").concat(this.episode.title);
        }
        else {
            this.seriesName.innerHTML = 'No episode playing';
            this.episodeName.innerHTML = '';
            this.cover.src = '/transparent.png';
            this.nowPlaying.title = 'No episode playing';
        }
        if (loading || !this.episode) {
            this.playButton.disabled = true;
            this.rewButton.disabled = true;
            this.ffwButton.disabled = true;
            this.skipButton.disabled = true;
        }
        else {
            this.playButton.disabled = false;
            this.rewButton.disabled = false;
            this.ffwButton.disabled = false;
            this.skipButton.disabled = !this.playlist.hasNextEpisode();
        }
    };
    Player.prototype.sendMediaSessionMetadata = function () {
        if ('mediaSession' in navigator) {
            if (this.episode) {
                navigator.mediaSession.metadata = new MediaMetadata({
                    title: this.episode.title,
                    album: 'Radiostasis',
                    artist: this.episode.series.title,
                    artwork: [
                        {
                            src: this.episode.series.cover,
                            sizes: '256x256',
                            type: 'image/jpeg',
                        },
                    ],
                });
            }
            else {
                navigator.mediaSession.metadata = null;
            }
        }
    };
    Player.prototype.timeToDisplayString = function (time) {
        var mins = Math.floor(time / 60);
        var secs = Math.floor(time - mins * 60);
        var secStr = secs < 10 ? "0".concat(secs) : secs.toString();
        return "".concat(mins, ":").concat(secStr);
    };
    Player.prototype.updateTimeUI = function () {
        if (this.howl && this.howl.state() === 'loaded') {
            var total = this.howl.duration();
            var current = this.howl.seek();
            var pct = "".concat(Math.round((current / total) * 1000) / 10, "%");
            var timeStamp = "".concat(this.timeToDisplayString(current), " / ").concat(this.timeToDisplayString(total));
            // set the new values if they've changed since the last tick
            if (this.timeDisplay.innerHTML !== timeStamp)
                this.timeDisplay.innerHTML = timeStamp;
            if (this.progress.style.width !== pct)
                this.progress.style.width = pct;
        }
        else {
            this.timeDisplay.innerHTML = '--:-- / --:--';
            this.progress.style.width = '0%';
        }
    };
    Player.prototype.startTicker = function () {
        var _this = this;
        if (!this.ticker) {
            this.ticker = setInterval(function () { return _this.updateTimeUI(); }, 500);
        }
    };
    Player.prototype.stopTicker = function () {
        if (this.ticker) {
            clearInterval(this.ticker);
            this.ticker = null;
        }
    };
    return Player;
}());
var Playlist = /** @class */ (function () {
    function Playlist(playerDelegate) {
        var _this = this;
        this.queueExpandedHeight = 'calc(100% - 6ex)';
        // event handlers
        this.changedHandlers = [];
        // the actual episode queue
        this.episodes = [];
        this.episodeHash = new Set();
        this.playerDelegate = playerDelegate;
        this.queueContainer = getOrThrow(document.getElementById('queue-container'));
        this.queueInitialHeight = getComputedStyle(this.queueContainer).height;
        this.queueTab = getOrThrow(this.queueContainer.getElementsByTagName('h2').item(0));
        this.queueList = getOrThrow(this.queueContainer.getElementsByTagName('ol').item(0));
        this.overlay = getOrThrow(document.getElementById('overlay'));
        this.clearButton = getOrThrow(document.getElementById('clear-playlist'));
        // wire up global playlist controls
        this.queueTab.addEventListener('click', function () { return _this.toggleQueueUI(); });
        this.overlay.addEventListener('click', function () { return _this.toggleQueueUI(); });
        this.clearButton.addEventListener('click', function () { return _this.clearPlaylist(); });
    }
    Playlist.prototype.initialize = function () {
        var _this = this;
        this.playerDelegate().addStateChangedHandler(function () { return _this.stateChanged(); });
        this.unshiftCurrent();
    };
    Playlist.prototype.addPlaylistChangedHandler = function (handler) {
        this.changedHandlers.push(handler);
    };
    Playlist.prototype.hasNextEpisode = function () {
        return this.episodes.length > 0;
    };
    Playlist.prototype.nextEpisode = function () {
        if (this.episodes.length > 0) {
            return this.episodes[0][0];
        }
        return null;
    };
    Playlist.prototype.pushEpisode = function (episode) {
        this.pushEpisodes([episode]);
    };
    Playlist.prototype.pushEpisodes = function (episodes) {
        for (var _i = 0, episodes_1 = episodes; _i < episodes_1.length; _i++) {
            var episode = episodes_1[_i];
            if (this.isQueued(episode))
                this.removeEpisode(episode, true, false);
            var litem = this.createQueueListItem(episode);
            this.episodes.push([episode, litem]);
            this.episodeHash.add(episode.id);
            this.queueList.appendChild(litem);
        }
        this.notify(episodes.length == 1
            ? 'Episode added to queue.'
            : "".concat(episodes.length, " episodes added to queue."));
        this.playlistChanged();
    };
    Playlist.prototype.unshiftEpisodes = function (episodes) {
        this.shiftCurrent();
        var nowPlaying = this.playerDelegate().currentEpisode();
        if (nowPlaying) {
            var litem = this.createQueueListItem(nowPlaying);
            this.episodes.unshift([nowPlaying, litem]);
            this.episodeHash.add(nowPlaying.id);
            this.queueList.prepend(litem);
        }
        for (var i = episodes.length - 1; i >= 0; i--) {
            var episode = episodes[i];
            if (this.isQueued(episode))
                this.removeEpisode(episode, true, false);
            var litem = this.createQueueListItem(episode);
            this.episodes.unshift([episode, litem]);
            this.episodeHash.add(episode.id);
            this.queueList.prepend(litem);
        }
        this.notify(episodes.length == 1
            ? 'Episode added to queue.'
            : "".concat(episodes.length, " episodes added to queue."));
        this.unshiftCurrent();
        this.playlistChanged();
    };
    Playlist.prototype.removeEpisode = function (episode, ignoreChanged, notify) {
        if (ignoreChanged === void 0) { ignoreChanged = false; }
        if (notify === void 0) { notify = true; }
        if (this.isQueued(episode)) {
            var idx = this.episodes.findIndex(function (e) { return e[0].id == episode.id; });
            var deleted = this.episodes.splice(idx, 1);
            this.episodeHash.delete(episode.id);
            deleted[0][1].remove();
        }
        if (!ignoreChanged)
            this.playlistChanged();
        if (notify)
            this.notify('Episode removed from queue.');
    };
    Playlist.prototype.isQueued = function (episode) {
        return this.episodeHash.has(episode.id);
    };
    Playlist.prototype.triggerPlaylistChanged = function () {
        this.playlistChanged();
    };
    Playlist.prototype.clearPlaylist = function () {
        var removed = this.episodes.length;
        if (this.playerDelegate().currentEpisode() != null) {
            this.playerDelegate().stopPlaybackAndResetUi();
            removed++;
        }
        this.episodes.length = 0;
        this.episodeHash.clear();
        this.queueList.innerHTML = '';
        this.unshiftCurrent();
        this.playlistChanged();
        if (removed > 0) {
            this.notify('Playlist cleared.');
        }
    };
    Playlist.prototype.reQueueNowPlaying = function () {
        var currentEpisode = this.playerDelegate().currentEpisode();
        if (currentEpisode) {
            this.unshiftEpisodes([currentEpisode]);
        }
    };
    Playlist.prototype.playlistChanged = function () {
        this.shiftCurrent();
        this.unshiftCurrent();
        for (var _i = 0, _a = this.changedHandlers; _i < _a.length; _i++) {
            var handler = _a[_i];
            handler();
        }
    };
    Playlist.prototype.shiftCurrent = function () {
        var _a;
        (_a = this.queueList.firstChild) === null || _a === void 0 ? void 0 : _a.remove();
    };
    Playlist.prototype.stateChanged = function () {
        this.shiftCurrent();
        this.unshiftCurrent();
    };
    Playlist.prototype.unshiftCurrent = function () {
        var currentEpisode = this.playerDelegate().currentEpisode();
        if (currentEpisode) {
            this.queueList.prepend(this.createQueueListItem(currentEpisode, false));
        }
        else {
            var litem = document.createElement('li');
            litem.classList.add('episode');
            litem.title = 'No episode playing';
            var label = document.createElement('label');
            label.innerHTML = 'No episode playing';
            litem.appendChild(label);
            this.queueList.prepend(litem);
        }
    };
    Playlist.prototype.toggleQueueUI = function () {
        if (this.queueContainer.style.height !== this.queueExpandedHeight) {
            this.queueContainer.style.height = this.queueExpandedHeight;
            this.overlay.style.backgroundColor = 'rgba(255, 255, 255, 0.75)';
            this.overlay.style.backdropFilter = 'blur(5px)';
            this.overlay.style.pointerEvents = 'auto';
            this.queueTab.innerHTML = 'Close';
            this.queueTab.classList.add('expanded');
        }
        else {
            this.queueContainer.style.height = this.queueInitialHeight;
            this.overlay.style.backgroundColor = 'rgba(255, 255, 255, 0)';
            this.overlay.style.backdropFilter = 'none';
            this.overlay.style.pointerEvents = 'none';
            this.queueTab.innerHTML = 'Playlist';
            this.queueTab.classList.remove('expanded');
        }
    };
    Playlist.prototype.createQueueListItem = function (episode, queueControls) {
        var _this = this;
        if (queueControls === void 0) { queueControls = true; }
        var item = document.createElement('li');
        item.classList.add('episode');
        item.title = episode.title;
        var label = document.createElement('label');
        label.innerHTML = episode.title;
        var sspan = document.createElement('span');
        sspan.innerHTML = episode.series.title;
        var aside = document.createElement('aside');
        aside.appendChild(sspan);
        item.appendChild(label);
        item.appendChild(aside);
        if (queueControls) {
            // play now/remove buttons
            var controls = document.createElement('div');
            controls.classList.add('controls');
            var playBtn = document.createElement('a');
            playBtn.href = '#';
            playBtn.innerHTML = 'Play Now';
            playBtn.addEventListener('click', function (e) {
                _this.reQueueNowPlaying();
                _this.playerDelegate().playEpisode(episode);
                e.preventDefault();
            });
            var remBtn = document.createElement('a');
            remBtn.href = '#';
            remBtn.innerHTML = 'Remove';
            remBtn.addEventListener('click', function (e) {
                _this.removeEpisode(episode);
                e.preventDefault();
            });
            controls.appendChild(playBtn);
            controls.appendChild(remBtn);
            item.appendChild(controls);
        }
        else {
            // pause/skip buttons
            item.classList.add('playing');
            var controls = document.createElement('div');
            controls.classList.add('controls');
            var pauseBtn_1 = document.createElement('a');
            pauseBtn_1.href = '#';
            pauseBtn_1.innerHTML = this.playerDelegate().isPlaying() ? 'Pause' : 'Play';
            if (this.playerDelegate().isPlaying()) {
                pauseBtn_1.classList.add('pause');
            }
            pauseBtn_1.addEventListener('click', function () {
                _this.playerDelegate().playPause();
                pauseBtn_1.innerHTML = _this.playerDelegate().isPlaying()
                    ? 'Pause'
                    : 'Play';
            });
            var skipBtn = document.createElement('a');
            skipBtn.href = '#';
            skipBtn.innerHTML = 'Skip';
            skipBtn.addEventListener('click', function (e) {
                _this.playerDelegate().nextEpisode();
                e.preventDefault();
            });
            controls.appendChild(pauseBtn_1);
            controls.appendChild(skipBtn);
            item.appendChild(controls);
        }
        return item;
    };
    Playlist.prototype.notify = function (message) {
        Toastify({
            text: message,
            gravity: 'bottom',
            position: 'right',
            stopOnFocus: false,
            style: {
                marginBottom: '10ex',
                background: '#090',
                color: '#fff',
            },
        }).showToast();
    };
    return Playlist;
}());
var Radiostasis = /** @class */ (function () {
    function Radiostasis() {
        var _this = this;
        var _a;
        this.debouncer = null;
        this.playlist = new Playlist(function () { return _this.player; });
        this.player = new Player(this.playlist);
        this.playlist.initialize();
        this.main = getOrThrow(document.getElementsByTagName('main').item(0));
        // set up htmx event handlers
        document.addEventListener('htmx:historyRestore', function () {
            return _this.wireLoadedFragment();
        });
        (_a = document
            .getElementsByTagName('main')
            .item(0)) === null || _a === void 0 ? void 0 : _a.addEventListener('htmx:afterSwap', function () { return _this.wireLoadedFragment(); });
        // set up playlist changed handler
        this.playlist.addPlaylistChangedHandler(function () { return _this.episodeStateChanged(); });
        // set up prompt to prevent accidentally leaving the page while playing
        window.addEventListener('beforeunload', function (e) {
            if (!_this.player.isPlaying())
                return undefined;
            e.preventDefault();
            e.returnValue = '';
        });
    }
    Radiostasis.prototype.initialize = function () {
        var path = location.pathname == '/'
            ? '/partial/home.html'
            : "/partial/".concat(location.pathname, ".html");
        htmx.ajax('GET', path, 'main');
    };
    Radiostasis.prototype.wireLoadedFragment = function () {
        var _this = this;
        var _a, _b, _c, _d, _e, _f;
        // save a list of all episodes for the series play/queue buttons
        var seriesEpisodes = [];
        // episode play and queue buttons
        var episodes = this.main.getElementsByClassName('episode');
        var _loop_1 = function (i) {
            var el = episodes.item(i);
            if (!el || !el.dataset.episode)
                return "continue";
            var episode = JSON.parse(el.dataset.episode);
            // save and store this model for later use
            seriesEpisodes.push(episode);
            // play button
            (_a = el.getElementsByTagName('a')
                .item(0)) === null || _a === void 0 ? void 0 : _a.addEventListener('click', function (e) {
                var _a;
                if (((_a = _this.player.currentEpisode()) === null || _a === void 0 ? void 0 : _a.id) !== episode.id) {
                    _this.playlist.reQueueNowPlaying();
                    _this.player.playEpisode(episode);
                }
                e.preventDefault();
            });
            // queue button
            (_b = el.getElementsByTagName('a')
                .item(1)) === null || _b === void 0 ? void 0 : _b.addEventListener('click', function (e) {
                var _a;
                if (!_this.player.currentEpisode()) {
                    // if nothing is playing, first queued item gets loaded
                    // into the player but does not autoplay
                    _this.player.playEpisode(episode, true);
                }
                else if (((_a = _this.player.currentEpisode()) === null || _a === void 0 ? void 0 : _a.id) !== episode.id) {
                    if (_this.playlist.isQueued(episode)) {
                        _this.playlist.removeEpisode(episode);
                    }
                    else {
                        _this.playlist.pushEpisode(episode);
                    }
                }
                e.preventDefault();
            });
            // set playing/queued state
            this_1.updateEpisodeElementFromState(el, episode);
        };
        var this_1 = this;
        for (var i = 0; i < episodes.length; i++) {
            _loop_1(i);
        }
        // series play and queue buttons
        var series = (_c = document
            .getElementsByClassName('seriesDetails')
            .item(0)) === null || _c === void 0 ? void 0 : _c.getElementsByTagName('section').item(0);
        if (series) {
            // play series button
            (_d = series
                .getElementsByTagName('a')
                .item(0)) === null || _d === void 0 ? void 0 : _d.addEventListener('click', function () {
                var _a;
                _this.playlist.unshiftEpisodes(seriesEpisodes);
                if (((_a = _this.player.currentEpisode()) === null || _a === void 0 ? void 0 : _a.id) !== seriesEpisodes[0].id) {
                    _this.player.playEpisode(seriesEpisodes[0]);
                }
                else {
                    _this.playlist.removeEpisode(seriesEpisodes[0]);
                }
            });
            // queue series button
            (_e = series
                .getElementsByTagName('a')
                .item(1)) === null || _e === void 0 ? void 0 : _e.addEventListener('click', function () {
                var toQueue = seriesEpisodes.filter(function (e) { var _a; return ((_a = _this.player.currentEpisode()) === null || _a === void 0 ? void 0 : _a.id) !== e.id; });
                _this.playlist.pushEpisodes(toQueue);
                // if nothing is playing, peel off the first episode and load it
                // into the player without autoplay
                if (!_this.player.currentEpisode()) {
                    _this.player.playEpisode(seriesEpisodes[0], true);
                }
            });
        }
        // series filter input
        var filter = (this.main.getElementsByClassName('filter').item(0));
        if (filter) {
            filter.value = (_f = filter.dataset.search) !== null && _f !== void 0 ? _f : '';
            var allSeries_1 = this.main.getElementsByTagName('section');
            filter.addEventListener('input', function () {
                filter.dataset.search = filter.value;
                if (_this.debouncer)
                    clearTimeout(_this.debouncer);
                _this.debouncer = setTimeout(function () {
                    var terms = filter.value.toLowerCase().split(' ');
                    for (var i = 0; i < allSeries_1.length; i++) {
                        var series_1 = allSeries_1.item(i);
                        if (!series_1 || !series_1.dataset.filter)
                            continue;
                        var match = true;
                        for (var _i = 0, terms_1 = terms; _i < terms_1.length; _i++) {
                            var term = terms_1[_i];
                            if (term.length > 0 && series_1.dataset.filter.indexOf(term) < 0) {
                                match = false;
                                break;
                            }
                        }
                        if (match)
                            series_1.classList.remove('no-match');
                        else
                            series_1.classList.add('no-match');
                    }
                }, 499);
            });
        }
    };
    Radiostasis.prototype.updateEpisodeElementFromState = function (litem, episode) {
        var _a;
        if (((_a = this.player.currentEpisode()) === null || _a === void 0 ? void 0 : _a.id) === episode.id) {
            litem.classList.add('playing');
            getOrThrow(litem.getElementsByTagName('a').item(0)).innerHTML = 'Playing';
        }
        else {
            litem.classList.remove('playing');
            getOrThrow(litem.getElementsByTagName('a').item(0)).innerHTML =
                'Play Episode';
        }
        var queueBtn = getOrThrow(litem.getElementsByTagName('a').item(1));
        if (this.playlist.isQueued(episode)) {
            queueBtn.classList.add('queued');
            queueBtn.innerHTML = 'Remove from Queue';
        }
        else {
            queueBtn.classList.remove('queued');
            queueBtn.innerHTML = 'Queue Episode';
        }
    };
    Radiostasis.prototype.episodeStateChanged = function () {
        var episodes = this.main.getElementsByClassName('episode');
        for (var i = 0; i < episodes.length; i++) {
            var el = episodes.item(i);
            if (!el || !el.dataset.episode)
                continue;
            var episode = JSON.parse(el.dataset.episode);
            this.updateEpisodeElementFromState(el, episode);
        }
    };
    return Radiostasis;
}());
function getOrThrow(element) {
    if (!element) {
        throw new Error("tried to get an element that doesn't exist");
    }
    return element;
}
document.addEventListener('DOMContentLoaded', function () {
    // start application
    new Radiostasis().initialize();
});
