define([], function () { 'use strict'; var currentId = 0; function addUniquePlaylistItemId(item) { if (!item.PlaylistItemId) { item.PlaylistItemId = 'playlistItem' + currentId; currentId++; } } function findPlaylistIndex(playlistItemId, list) { for (var i = 0, length = list.length; i < length; i++) { if (list[i].PlaylistItemId === playlistItemId) { return i; } } return -1; } function PlayQueueManager() { this._sortedPlaylist = []; this._playlist = []; this._repeatMode = 'RepeatNone'; this._shuffleMode = 'Sorted'; } PlayQueueManager.prototype.getPlaylist = function () { return this._playlist.slice(0); }; PlayQueueManager.prototype.setPlaylist = function (items) { items = items.slice(0); for (var i = 0, length = items.length; i < length; i++) { addUniquePlaylistItemId(items[i]); } this._currentPlaylistItemId = null; this._playlist = items; this._repeatMode = 'RepeatNone'; }; PlayQueueManager.prototype.queue = function (items) { for (var i = 0, length = items.length; i < length; i++) { addUniquePlaylistItemId(items[i]); this._playlist.push(items[i]); } }; PlayQueueManager.prototype.shufflePlaylist = function () { this._sortedPlaylist = []; for (const item of this._playlist) { this._sortedPlaylist.push(item); } const currentPlaylistItem = this._playlist.splice(this.getCurrentPlaylistIndex(), 1)[0]; for (let i = this._playlist.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * i); const temp = this._playlist[i]; this._playlist[i] = this._playlist[j]; this._playlist[j] = temp; } this._playlist.unshift(currentPlaylistItem); this._shuffleMode = 'Shuffle'; }; PlayQueueManager.prototype.sortShuffledPlaylist = function () { this._playlist = []; for (let item of this._sortedPlaylist) { this._playlist.push(item); } this._sortedPlaylist = []; this._shuffleMode = 'Sorted'; }; PlayQueueManager.prototype.clearPlaylist = function (clearCurrentItem = false) { const currentPlaylistItem = this._playlist.splice(this.getCurrentPlaylistIndex(), 1)[0]; this._playlist = []; if (!clearCurrentItem) { this._playlist.push(currentPlaylistItem); } }; function arrayInsertAt(destArray, pos, arrayToInsert) { var args = []; args.push(pos); // where to insert args.push(0); // nothing to remove args = args.concat(arrayToInsert); // add on array to insert destArray.splice.apply(destArray, args); // splice it in } PlayQueueManager.prototype.queueNext = function (items) { var i; var length; for (i = 0, length = items.length; i < length; i++) { addUniquePlaylistItemId(items[i]); } var currentIndex = this.getCurrentPlaylistIndex(); if (currentIndex === -1) { currentIndex = this._playlist.length; } else { currentIndex++; } arrayInsertAt(this._playlist, currentIndex, items); }; PlayQueueManager.prototype.getCurrentPlaylistIndex = function () { return findPlaylistIndex(this.getCurrentPlaylistItemId(), this._playlist); }; PlayQueueManager.prototype.getCurrentItem = function () { var index = findPlaylistIndex(this.getCurrentPlaylistItemId(), this._playlist); return index === -1 ? null : this._playlist[index]; }; PlayQueueManager.prototype.getCurrentPlaylistItemId = function () { return this._currentPlaylistItemId; }; PlayQueueManager.prototype.setPlaylistState = function (playlistItemId, playlistIndex) { this._currentPlaylistItemId = playlistItemId; }; PlayQueueManager.prototype.setPlaylistIndex = function (playlistIndex) { if (playlistIndex < 0) { this.setPlaylistState(null); } else { this.setPlaylistState(this._playlist[playlistIndex].PlaylistItemId); } }; PlayQueueManager.prototype.removeFromPlaylist = function (playlistItemIds) { if (this._playlist.length <= playlistItemIds.length) { return { result: 'empty' }; } var currentPlaylistItemId = this.getCurrentPlaylistItemId(); var isCurrentIndex = playlistItemIds.indexOf(currentPlaylistItemId) !== -1; this._sortedPlaylist = this._sortedPlaylist.filter(function (item) { return !playlistItemIds.includes(item.PlaylistItemId); }); this._playlist = this._playlist.filter(function (item) { return !playlistItemIds.includes(item.PlaylistItemId); }); return { result: 'removed', isCurrentIndex: isCurrentIndex }; }; function moveInArray(array, from, to) { array.splice(to, 0, array.splice(from, 1)[0]); } PlayQueueManager.prototype.movePlaylistItem = function (playlistItemId, newIndex) { var playlist = this.getPlaylist(); var oldIndex; for (var i = 0, length = playlist.length; i < length; i++) { if (playlist[i].PlaylistItemId === playlistItemId) { oldIndex = i; break; } } if (oldIndex === -1 || oldIndex === newIndex) { return { result: 'noop' }; } if (newIndex >= playlist.length) { throw new Error('newIndex out of bounds'); } moveInArray(playlist, oldIndex, newIndex); this._playlist = playlist; return { result: 'moved', playlistItemId: playlistItemId, newIndex: newIndex }; }; PlayQueueManager.prototype.reset = function () { this._sortedPlaylist = []; this._playlist = []; this._currentPlaylistItemId = null; this._repeatMode = 'RepeatNone'; this._shuffleMode = 'Sorted'; }; PlayQueueManager.prototype.setRepeatMode = function (value) { const repeatModes = ['RepeatOne', 'RepeatAll', 'RepeatNone']; if (repeatModes.includes(value)) { this._repeatMode = value; } else { throw new TypeError('invalid value provided for setRepeatMode'); } }; PlayQueueManager.prototype.getRepeatMode = function () { return this._repeatMode; }; PlayQueueManager.prototype.setShuffleMode = function (value) { switch (value) { case 'Shuffle': this.shufflePlaylist(); break; case 'Sorted': this.sortShuffledPlaylist(); break; default: throw new TypeError('invalid value provided to setShuffleMode'); } }; PlayQueueManager.prototype.toggleShuffleMode = function () { switch (this._shuffleMode) { case 'Shuffle': this.setShuffleMode('Sorted'); break; case 'Sorted': this.setShuffleMode('Shuffle'); break; default: throw new TypeError('current value for shufflequeue is invalid'); } }; PlayQueueManager.prototype.getShuffleMode = function () { return this._shuffleMode; }; PlayQueueManager.prototype.getNextItemInfo = function () { var newIndex; var playlist = this.getPlaylist(); var playlistLength = playlist.length; switch (this.getRepeatMode()) { case 'RepeatOne': newIndex = this.getCurrentPlaylistIndex(); break; case 'RepeatAll': newIndex = this.getCurrentPlaylistIndex() + 1; if (newIndex >= playlistLength) { newIndex = 0; } break; default: newIndex = this.getCurrentPlaylistIndex() + 1; break; } if (newIndex < 0 || newIndex >= playlistLength) { return null; } var item = playlist[newIndex]; if (!item) { return null; } return { item: item, index: newIndex }; }; return PlayQueueManager; });