home *** CD-ROM | disk | FTP | other *** search
- //<script>
- //****************************************************************
- // ⌐2000 Microsoft Corporation. All rights reserved.
- //****************************************************************
- //
- // JScript Query Object
- //
- // This object allows for a skin to query the media library for
- // one of many different attributes.
- //****************************************************************
-
-
-
-
-
-
- //****************************************************************
- //****************************************************************
- //
- // query object
- //
- //****************************************************************
- //****************************************************************
-
- function query( progressbar, completeQuery )
- {
- // Controls
-
- this.progressbar = progressbar;
-
- // Public Properties
-
- this.genre_collection = null; // A string collection of genres from core
- this.genre_include_array = new Array(); // An array (integer based) of genres to include
- this.genre_exclude_array = new Array(); // An array (integer based) of genres to exclude
-
- this.artist_collection = null; // A string collection of artists from core
- this.artist_include_array = new Array(); // An array (integer based) of artists to include
- this.artist_exclude_array = new Array(); // An array (integer based) of artists to exclude
-
- this.album_collection = null; // A string collection of albums from core
- this.album_include_array = new Array(); // An array (integer based) of albums to include
- this.album_exclude_array = new Array(); // An array (integer based) of albums to exclude
-
- this.playlist_collection = null; // A playlist collection from core
- this.playlist_include_array = new Array(); // An array (integer based) of playlists to include
- this.playlist_exclude_array = new Array(); // An array (integer based) of playlists to exclude
-
- this.search_include_array_txt = new Array(); // Description for each playlist in the include array
- this.search_include_array_pl = new Array(); // Array of playlists to include
- this.search_exclude_array_txt = new Array(); // Description for each playlist in the exclude array
- this.search_exclude_array_pl = new Array(); // Array of playlist to exclude
-
- this.allow_playlists = false; // True to allow *.m3u and *.asx into the query
- this.allow_urls = false; // True to allow '://' source URLs into the query
- this.allow_blank = false; // True to allow blank artist & album metadata into the query
-
- this.playcount_filter = false; // Use the playcount filter?
- this.playcount_filter_comparison = 0; // Comparison operator - 0 = less than, 1 = equal to, 2 = greater than
- this.playcount_filter_count = 5; // Value to compare against
-
- this.playcount_favoring = false; // Use playcount favoring when deleting tracks?
- this.playcount_favoring_comparison = 0; // Comparison operator - 0 = played most often, 1 = played least often
- this.playcount_favoring_sample = 15; // Number of tracks to sample to do favoring
-
- this.playlength_filter = false; // Use a playlength filter?
- this.playlength_filter_comparison = 0; // Comparison operator - 0 = at least, 1 = at most
- this.playlength_filter_length = 30; // Value (in seconds) to compare against
-
- this.generic_search = false; // Use a generic search?
- this.generic_search_name = ''; // Generic search attribute name to use
- this.generic_search_comparison = 0; // Comparison operator - 0 = contains, 1 = doesn't contain, 2 = equals, 3 = doesn't equal
- this.generic_search_value = ''; // Value to match search against
-
- this.playlength_limit = true; // Use a cap on the possible length of the playlist?
- this.playlength_limit_length = 14400; // Value (in seconds) to keep the playlist under (default 4hr)
-
- this.shuffle_playlist = true; // Do we shuffle the resultant playlist?
-
- this.performing_query = false; // Are we performing the query?
- this.query_aborted = false; // Has the query been aborted?
-
- this.plQueryResult = null; // The resultant query playlist after the query completes
- this.plLibraryResult = null; // The resultant library playlist (if requested) after the query completes
-
- // Public Methods
-
- this.getGenreCountQ = getGenreCountQ; // Retrieves the number of genres in the collection
- this.getGenreListQ = getGenreListQ; // Retrieves a (/r delimited) list of genres in the collection
- this.addGenreIncludeQ = addGenreIncludeQ; // Adds a genre include to the query (integer based)
- this.addGenreExcludeQ = addGenreExcludeQ; // Adds a genre exclude to the query (integer based)
-
- this.getArtistCountQ = getArtistCountQ; // Retrieves the number of artists in the collection
- this.getArtistListQ = getArtistListQ; // Retrieves a (/r delimited) list of artists in the collection
- this.addArtistIncludeQ = addArtistIncludeQ; // Adds an artist include to the query (integer based)
- this.addArtistExcludeQ = addArtistExcludeQ; // Adds an artist exclude ot the query (integer based)
-
- this.getAlbumCountQ = getAlbumCountQ; // Retrieves the number of albums in the collection
- this.getAlbumListQ = getAlbumListQ; // Retrieves a (/r delimited) list of albums in the collection
- this.addAlbumIncludeQ = addAlbumIncludeQ; // Adds an album include to the query (integer based)
- this.addAlbumExcludeQ = addAlbumExcludeQ; // Adds an album exclude to the query (integer based)
-
- this.getPlaylistCountQ = getPlaylistCountQ; // Retrieves the number of playlists in the library
- this.getPlaylistListQ = getPlaylistListQ; // Retrieves a (/r delimited) list of playlists in the library
- this.addPlaylistIncludeQ = addPlaylistIncludeQ; // Adds a library playlist to include to the query (integer based)
- this.addPlaylistExcludeQ = addPlaylistExcludeQ; // Adds a library playlist to exclude to the query (integer based)
-
- this.addSearchPlaylistIncludeQ = addSearchPlaylistIncludeQ; // Adds a generic playlist (with description) to the query include
- this.addSearchPlaylistExcludeQ = addSearchPlaylistExcludeQ; // Adds a genreic playlist (with description) to the query exclude
-
- this.getPlaycountFilterComparisonStringQ = getPlaycountFilterComparisonStringQ; // Retrieves a brief description of the playcount comparison string
- this.getPlaycountFavoringComparisonStringQ = getPlaycountFavoringComparisonStringQ; // Retrieves a brief description of the playcount favoring string
- this.getPlaylengthFilterComparisonStringQ = getPlaylengthFilterComparisonStringQ; // Retrieves a brief description of the playlength comparison string
- this.getGenericSearchComparisonStringQ = getGenericSearchComparisonStringQ; // Retrieves a brief description of the search comparison string
- this.getQueryDescriptionQ = getQueryDescriptionQ; // Retrieves a string description of the query
-
- this.performQueryQ = performQueryQ; // Starts the query
- this.continueQueryQ = continueQueryQ; // Continues the query (must be called from progressbar_onendmove)
-
- // Public events
-
- this.completeQuery = completeQuery; // Event to be notified of the query's completion
-
-
- // Private Member Variables (do not modify)
-
- this.nQueryPosition = 0;
-
- this.fConcatenating = false;
- this.nConcatIndex = 0;
- this.plDest = null;
- this.plSource = null;
-
- this.plIncludeResult = null;
- this.plExcludeResult = null;
-
- this.nQueryIndex = 0;
-
- this.rgGenre = null;
- this.rgArtist = null;
- this.rgAlbum = null;
- this.rgPlaylist = null;
- this.rgSearch = null;
-
- this.nCurrentLength = 0;
- this.nOriginalLength = 0;
- this.nExcludeCount = 0;
-
- this.playlistname = '';
- }
-
-
- //****************************************************************
- // Genre Operations
- //****************************************************************
-
- function getGenreCountQ()
- {
- if (this.genre_collection == null)
- {
- this.genre_collection = player.mediaCollection.getAttributeStringCollection( "Genre", "Audio" );
- }
- return (this.genre_collection ? this.genre_collection.count : 0);
- }
-
- //****************************************************************
-
- function getGenreListQ()
- {
- this.getGenreCountQ();
- if (this.genre_collection == null)
- {
- return '';
- }
- return getStringFromAttributeStringCollection( this.genre_collection );
- }
-
- //****************************************************************
-
- function addGenreIncludeQ( nIndex )
- {
- addInclude( nIndex, this.genre_include_array, this.genre_exclude_array );
- }
-
- //****************************************************************
-
- function addGenreExcludeQ( nIndex )
- {
- addExclude( nIndex, this.genre_include_array, this.genre_exclude_array );
- }
-
-
- //****************************************************************
- // Artist Operations
- //****************************************************************
-
- function getArtistCountQ()
- {
- if (this.artist_collection == null)
- {
- this.artist_collection = player.mediaCollection.getAttributeStringCollection( "Artist", "Audio" );
- }
- return (this.artist_collection ? this.artist_collection.count : 0);
- }
-
- //****************************************************************
-
- function getArtistListQ()
- {
- this.getArtistCountQ();
- if (this.artist_collection == null)
- {
- return '';
- }
- return getStringFromAttributeStringCollection( this.artist_collection );
- }
-
- //****************************************************************
-
- function addArtistIncludeQ( nIndex )
- {
- addInclude( nIndex, this.artist_include_array, this.artist_exclude_array );
- }
-
- //****************************************************************
-
- function addArtistExcludeQ( nIndex )
- {
- addExclude( nIndex, this.artist_include_array, this.artist_exclude_array );
- }
-
-
- //****************************************************************
- // Album Operations
- //****************************************************************
-
- function getAlbumCountQ()
- {
- if (this.album_collection == null)
- {
- this.album_collection = player.mediaCollection.getAttributeStringCollection( "Album", "Audio" );
- }
- return (this.album_collection ? this.album_collection.count : 0);
- }
-
- //****************************************************************
-
- function getAlbumListQ()
- {
- this.getAlbumCountQ();
- if (this.album_collection == null)
- {
- return '';
- }
- return getStringFromAttributeStringCollection( this.album_collection );
- }
-
- //****************************************************************
-
- function addAlbumIncludeQ( nIndex )
- {
- addInclude( nIndex, this.album_include_array, this.album_exclude_array );
- }
-
- //****************************************************************
-
- function addAlbumExcludeQ( nIndex )
- {
- addExclude( nIndex, this.album_include_array, this.album_exclude_array );
- }
-
-
- //****************************************************************
- // Playlist Operations
- //****************************************************************
-
- function getPlaylistCountQ()
- {
- if (this.playlist_collection == null)
- {
- this.playlist_collection = player.playlistCollection.getAll();
- }
- return (this.playlist_collection ? this.playlist_collection.count : 0);
- }
-
- //****************************************************************
-
- function getPlaylistListQ()
- {
- // We need to ensure a refresh, but we also need to make sure
- // our old and new items still line up... if not, then we need
- // to fix them.
-
- var oldList = this.playlist_collection;
- this.playlist_collection = null;
-
- this.getPlaylistCountQ();
- if (this.playlist_collection == null)
- {
- return '';
- }
-
- var string = '';
-
- for (var nIndex = 0; nIndex < this.playlist_collection.count; nIndex++)
- {
- if (string != '')
- {
- string += '\r';
- }
- string += this.playlist_collection.item( nIndex ).name;
- }
-
- if ((oldList != null) && (this.playlist_include_array.length != 0 || this.playlist_exclude_array.length != 0))
- {
- reconcilePlaylistArray( oldList, this.playlist_collection, this.playlist_include_array );
- reconcilePlaylistArray( oldList, this.playlist_collection, this.playlist_exclude_array );
- }
-
- return string;
- }
-
- //****************************************************************
-
- function addPlaylistIncludeQ( nIndex )
- {
- addInclude( nIndex, this.playlist_include_array, this.playlist_exclude_array );
- }
-
- //****************************************************************
-
- function addPlaylistExcludeQ( nIndex )
- {
- addExclude( nIndex, this.playlist_include_array, this.playlist_exclude_array );
- }
-
-
- //****************************************************************
- // Search Playlist Operations
- //****************************************************************
-
- function addSearchPlaylistIncludeQ( description, playlist )
- {
- if (inArray( description, this.search_include_array_txt ))
- {
- var nPos = arrayPosition( description, this.search_include_array_txt );
-
- removeItemFromArray( this.search_include_array_txt[nPos], this.search_include_array_txt );
- removeItemFromArray( this.search_include_array_pl[nPos], this.search_include_array_pl );
- }
- else
- {
- if (inArray( description, this.search_exclude_array_txt ))
- {
- // remove it...
-
- this.addSearchPlaylistExcludeQ( description, playlist );
- }
-
- this.search_include_array_txt[ this.search_include_array_txt.length ] = description;
- this.search_include_array_pl[ this.search_include_array_pl.length ] = playlist;
- }
- }
-
- //****************************************************************
-
- function addSearchPlaylistExcludeQ( description, playlist )
- {
- if (inArray( description, this.search_exclude_array_txt ))
- {
- var nPos = arrayPosition( description, this.search_exclude_array_txt );
-
- removeItemFromArray( this.search_exclude_array_txt[nPos], this.search_exclude_array_txt );
- removeItemFromArray( this.search_exclude_array_pl[nPos], this.search_exclude_array_pl );
- }
- else
- {
- if (inArray( description, this.search_include_array_txt ))
- {
- // remove it...
-
- this.addSearchPlaylistIncludeQ( description, playlist );
- }
-
- this.search_exclude_array_txt[ this.search_exclude_array_txt.length ] = description;
- this.search_exclude_array_pl[ this.search_exclude_array_pl.length ] = playlist;
- }
- }
-
-
- //****************************************************************
- // Query Description Methods
- //****************************************************************
-
- function getPlaycountFilterComparisonStringQ()
- {
- switch (this.playcount_filter_comparison)
- {
- case 0:
- return 'less than';
- case 1:
- return 'equal to';
- case 2:
- return 'greater than';
- }
- }
-
- //****************************************************************
-
- function getPlaycountFavoringComparisonStringQ()
- {
- switch (this.playcount_favoring_comparison)
- {
- case 0:
- return 'most';
- case 1:
- return 'least';
- }
- }
-
- //****************************************************************
-
- function getPlaylengthFilterComparisonStringQ()
- {
- switch (this.playlength_filter_comparison)
- {
- case 0:
- return 'at least';
- case 1:
- return 'at most';
- }
- }
-
- //****************************************************************
-
- function getGenericSearchComparisonStringQ()
- {
- switch (this.generic_search_comparison)
- {
- case 0:
- return 'contains';
- case 1:
- return 'doesn\'t contain';
- case 2:
- return 'equals';
- case 3:
- return 'doesn\'t equal';
- }
- }
-
- //****************************************************************
-
- function getQueryDescriptionQ()
- {
- var string = 'Add (Include):';
- var nAdded = 0;
-
- for (var nIndex = 0; nIndex < this.genre_include_array.length; nIndex++)
- {
- string += '\r Genre: ' + this.genre_collection.item( this.genre_include_array[nIndex] );
- nAdded++;
- }
- for (var nIndex = 0; nIndex < this.artist_include_array.length; nIndex++)
- {
- string += '\r Artist: ' + this.artist_collection.item( this.artist_include_array[nIndex] );
- nAdded++;
- }
- for (var nIndex = 0; nIndex < this.album_include_array.length; nIndex++)
- {
- string += '\r Album: ' + this.album_collection.item( this.album_include_array[nIndex] );
- nAdded++;
- }
- for (var nIndex = 0; nIndex < this.playlist_include_array.length; nIndex++)
- {
- string += '\r Playlist: ' + this.playlist_collection.item( this.playlist_include_array[nIndex] ).name;
- nAdded++;
- }
- for (var nIndex = 0; nIndex < this.search_include_array_txt.length; nIndex++)
- {
- string += '\r Search: ' + this.search_include_array_txt[nIndex];
- nAdded++;
- }
-
- if (nAdded == 0)
- {
- if (this.playlength_limit)
- {
- string += '\r Any Track';
- }
- else
- {
- string += '\r All Tracks';
- }
- }
-
- string += '\r\r\Leave out (Exclude):';
- nAdded = 0;
-
- for (var nIndex = 0; nIndex < this.genre_exclude_array.length; nIndex++)
- {
- string += '\r Genre: ' + this.genre_collection.item( this.genre_exclude_array[nIndex] );
- nAdded++;
- }
- for (var nIndex = 0; nIndex < this.artist_exclude_array.length; nIndex++)
- {
- string += '\r Artist: ' + this.artist_collection.item( this.artist_exclude_array[nIndex] );
- nAdded++;
- }
- for (var nIndex = 0; nIndex < this.album_exclude_array.length; nIndex++)
- {
- string += '\r Album: ' + this.album_collection.item( this.album_exclude_array[nIndex] );
- nAdded++;
- }
- for (var nIndex = 0; nIndex < this.playlist_exclude_array.length; nIndex++)
- {
- string += '\r Playlist: ' + this.playlist_collection.item( this.playlist_exclude_array[nIndex] ).name;
- nAdded++;
- }
- for (var nIndex = 0; nIndex < this.search_exclude_array_txt.length; nIndex++)
- {
- string += '\r Search: ' + this.search_exclude_array_txt[nIndex];
- nAdded++;
- }
-
- if (nAdded == 0)
- {
- string += '\r Nothing';
- }
-
- if ( this.playlength_limit ||
- this.allow_playlists ||
- this.allow_urls ||
- this.allow_blank ||
- this.playcount_filter ||
- this.playlength_filter ||
- this.generic_search )
- {
- string += '\r\r\Additional Options:';
-
- if (this.playlength_limit)
- {
- string += '\r Length limit: ' + formatMinutesString( this.playlength_limit_length );
-
- if (this.playcount_favoring)
- {
- string += '\r Favor ' + this.getPlaycountFavoringComparisonStringQ() + ' played tracks';
- }
- }
- if (this.allow_playlists)
- {
- string += '\r Allow nested playlists';
- }
- if (this.allow_urls)
- {
- string += '\r Allow URLs';
- }
- if (this.allow_blank)
- {
- string += '\r Allow blank artist/album';
- }
- if (this.playcount_filter)
- {
- string += '\r Playcount ' + this.getPlaycountFilterComparisonStringQ() + ' ' + this.playcount_filter_count;
- }
- if (this.playlength_filter)
- {
- string += '\r Duration ' + this.getPlaylengthFilterComparisonStringQ() + ' ' + formatSecondsString( this.playlength_filter_length );
- }
- if (this.generic_search)
- {
- string += '\r ' + this.generic_search_name + ' ' + this.getGenericSearchComparisonStringQ() + ' ' + this.generic_search_value;
- }
- }
-
- return string;
- }
-
-
- //****************************************************************
- // Perform the Query
- //****************************************************************
-
- function performQueryQ( playlistname )
- {
- // This function does not complete its work completely
- // synchronously. So, we need to keep someone from re-entering
- // us while we're in the middle of performing the query.
-
- if (this.performing_query)
- {
- return;
- }
-
- // Set us up for performing the query
-
- this.performing_query = true;
- this.query_aborted = false;
-
- // We need to setup our UI to perform the query
-
- this.progressbar.min = 0;
- this.progressbar.max = 1 + // include / exclude intersection
- 1 + // filtering options
- (this.playlength_limit ? 1 : 0) + // playcount filtering ?
- (this.playlistname != '' ? 1 : 0) + // library playlist save ?
- (this.shuffle_playlist ? 1 : 0) + // shuffling ?
- (
- this.genre_include_array.length + this.genre_exclude_array.length +
- this.artist_include_array.length + this.artist_exclude_array.length +
- this.album_include_array.length + this.album_exclude_array.length +
- this.playlist_include_array.length + this.playlist_exclude_array.length +
- this.search_include_array_pl.length + this.search_exclude_array_pl.length
- );
- this.progressbar.value = 0;
-
- this.generic_search_value = this.generic_search_value.toLowerCase();
-
- this.playlistname = playlistname;
- this.nQueryPosition = 0;
- this.continueQueryQ();
- }
-
- //****************************************************************
-
- function continueQueryQ()
- {
- xxxDoQuery( this );
-
- if (this.nQueryPosition < 100)
- {
- this.progressbar.moveTo( this.progressbar.left, this.progressbar.top, 10 );
- }
- }
-
-
- //****************************************************************
- // Private non-member functions that perform the query
- //****************************************************************
-
- function xxxDoQuery( query )
- {
- if (query.query_aborted)
- {
- xxxCompleteQuery( query );
- return;
- }
-
- if (query.fConcatenating)
- {
- xxxContinueConcat( query );
- return;
- }
-
- switch (query.nQueryPosition)
- {
- case 0:
- xxxSetupForIncludePlaylist( query );
- break;
-
- case 1:
- xxxDoGenreQuery( query );
- break;
-
- case 2:
- xxxDoArtistQuery( query );
- break;
-
- case 3:
- xxxDoAlbumQuery( query );
- break;
-
- case 4:
- xxxEnsureQueryPlaylistExists( query );
- break;
-
- case 5:
- xxxCollectLibraryPlaylists( query );
- break;
-
- case 6:
- xxxCollectSearchPlaylists( query );
- break;
-
- case 7:
- xxxSetupForExcludePlaylist( query );
- break;
-
- case 8:
- xxxRemoveExcludeIntersection( query );
- break;
-
- case 9:
- xxxRemoveFilteringOptions( query );
- break;
-
- case 10:
- xxxMatchLengthLimit( query );
- break;
-
- case 11:
- xxxShufflePlaylist( query );
- break;
-
- case 12:
- xxxPrepareLibraryPlaylist( query );
- break;
-
- case 13:
- xxxSaveLibraryPlaylist( query );
- break;
-
- case 14:
- xxxCompleteQuery( query );
- break;
- }
- }
-
- //****************************************************************
-
- function xxxConcatPlaylists( query, dest_playlist, source_playlist )
- {
- query.nConcatIndex = 0;
- query.plDest = dest_playlist;
- query.plSource = source_playlist;
- query.fConcatenating = true;
- xxxContinueConcat( query );
- }
-
- //****************************************************************
-
- function xxxContinueConcat( query )
- {
- var nMaxIterate = 100;
-
- while (query.nConcatIndex < query.plSource.count)
- {
- if (--nMaxIterate <= 0)
- {
- return;
- }
-
- var item = query.plSource.item( query.nConcatIndex++ );
-
- // We'd like to use item.isMemberOf( query.plDest ) here,
- // but it doesn't work quite right for base playlists.
- // So we have to do this by hand...
-
- var fFound = false;
- for (var nIndex = 0; nIndex < query.plDest.count; nIndex++)
- {
- if (item.isIdentical( query.plDest.item(nIndex) ))
- {
- fFound = true;
- break;
- }
- }
- if (!fFound)
- {
- query.plDest.appendItem( item );
- }
- }
-
- query.plDest = null;
- query.plSource = null;
- query.fConcatenating = false;
- }
-
- //****************************************************************
-
- function xxxSetupForIncludePlaylist( query )
- {
- query.plQueryResult = null;
- query.plIncludeResult = null;
- query.rgGenre = query.genre_include_array;
- query.rgArtist = query.artist_include_array;
- query.rgAlbum = query.album_include_array;
- query.rgPlaylist = query.playlist_include_array;
- query.rgSearch = query.search_include_array_pl;
-
- query.nQueryIndex = 0;
- query.nQueryPosition++;
- }
-
- //****************************************************************
-
- function xxxDoGenreQuery( query )
- {
- while (query.nQueryIndex < query.rgGenre.length)
- {
- query.progressbar.value = Math.floor(query.progressbar.value) + 1;
-
- var newPl = player.mediaCollection.getByGenre( query.genre_collection.item( query.rgGenre[ query.nQueryIndex++ ] ) );
-
- if (query.plQueryResult == null)
- {
- query.plQueryResult = newPl;
- }
- else
- {
- xxxConcatPlaylists( query, query.plQueryResult, newPl );
- return;
- }
- }
-
- query.nQueryIndex = 0;
- query.nQueryPosition++;
- }
-
- //****************************************************************
-
- function xxxDoArtistQuery( query )
- {
- while (query.nQueryIndex < query.rgArtist.length)
- {
- query.progressbar.value = Math.floor(query.progressbar.value) + 1;
-
- var newPl = player.mediaCollection.getByAttribute( "Artist", query.artist_collection.item( query.rgArtist[ query.nQueryIndex++ ] ) );
-
- if (query.plQueryResult == null)
- {
- query.plQueryResult = newPl;
- }
- else
- {
- xxxConcatPlaylists( query, query.plQueryResult, newPl );
- return;
- }
- }
-
- query.nQueryIndex = 0;
- query.nQueryPosition++;
- }
-
- //****************************************************************
-
- function xxxDoAlbumQuery( query )
- {
- while (query.nQueryIndex < query.rgAlbum.length)
- {
- query.progressbar.value = Math.floor(query.progressbar.value) + 1;
-
- var newPl = player.mediaCollection.getByAlbum( query.album_collection.item( query.rgAlbum[ query.nQueryIndex++ ] ) );
-
- if (query.plQueryResult == null)
- {
- query.plQueryResult = newPl;
- }
- else
- {
- xxxConcatPlaylists( query, query.plQueryResult, newPl );
- return;
- }
- }
-
- query.nQueryIndex = 0;
- query.nQueryPosition++;
- }
-
- //****************************************************************
-
- function xxxEnsureQueryPlaylistExists( query )
- {
- // At this point, we need to ensure that plQueryResult contains
- // a valid query playlist. We do this by performing a dummy
- // query if necessary.
-
- if (query.plQueryResult == null)
- {
- // if we're trying to form the include playlist, then we'll
- // want a playlist consisting of all media if we have nothing
- // specifically to include
-
- if (query.plIncludeResult == null)
- {
- if ((query.rgPlaylist.length == 0) && (query.rgSearch.length == 0))
- {
- query.plQueryResult = player.mediaCollection.getByAttribute( "MediaType", "Audio" );
- }
- }
-
- // if we're the exclude playlist, or we've got things to add to
- // the include playlist, then we just want an empty playlist to
- // work with... so we do a silly query to get us an empty one.
-
- if (query.plQueryResult == null)
- {
- query.plQueryResult = player.mediaCollection.getByAlbum( "xxx_foo_i_dont_exist_xxx" );
- }
- }
-
- query.nQueryIndex = 0;
- query.nQueryPosition++;
- }
-
- //****************************************************************
-
- function xxxCollectLibraryPlaylists( query )
- {
- while (query.nQueryIndex < query.rgPlaylist.length)
- {
- query.progressbar.value = Math.floor(query.progressbar.value) + 1;
-
- var newPl = query.playlist_collection.item( query.rgPlaylist[ query.nQueryIndex++ ] );
-
- xxxConcatPlaylists( query, query.plQueryResult, newPl );
- return;
- }
-
- query.nQueryIndex = 0;
- query.nQueryPosition++;
- }
-
- //****************************************************************
-
- function xxxCollectSearchPlaylists( query )
- {
- while (query.nQueryIndex < query.rgSearch.length)
- {
- query.progressbar.value = Math.floor(query.progressbar.value) + 1;
-
- xxxConcatPlaylists( query, query.plQueryResult, query.rgSearch[ query.nQueryIndex++ ] );
- return;
- }
-
- query.nQueryIndex = 0;
- query.nQueryPosition++;
- }
-
- //****************************************************************
-
- function xxxSetupForExcludePlaylist( query )
- {
- // OK, so we've just finished collecting us a search results
- // playlist. We now need to see if that playlist was an include
- // or an exclude playlist and do the appropriate thing for both.
-
- if (query.plIncludeResult == null)
- {
- query.plIncludeResult = query.plQueryResult;
- query.plQueryResult = null;
- query.plExcludeResult = null;
- query.rgGenre = query.genre_exclude_array;
- query.rgArtist = query.artist_exclude_array;
- query.rgAlbum = query.album_exclude_array;
- query.rgPlaylist = query.playlist_exclude_array;
- query.rgSearch = query.search_exclude_array_pl;
-
- // now reset the query position back to 1 so we wrap
- // back around and form a new query playlist for the exclude
- // side of things
-
- query.nQueryPosition = 1;
- return;
- }
-
- query.plExcludeResult = query.plQueryResult;
- query.plQueryResult = null;
- query.nExcludeCount = query.plExcludeResult.count;
-
- query.nQueryIndex = 0;
- query.nQueryPosition++;
- }
-
- //****************************************************************
-
- function xxxRemoveExcludeIntersection( query )
- {
- var nMaxIterate = 100;
-
- while (query.plExcludeResult.count > 0)
- {
- if (--nMaxIterate <= 0)
- {
- query.progressbar.value = Math.floor(query.progressbar.value) + (query.nQueryIndex / nExcludeCount);
- return;
- }
-
- query.nQueryIndex++;
-
- // We must remove the item from the playlist in order to get
- // isMemberOf to function properly. We want to use this
- // method rather than looping through the items directly
-
- var item = query.plExcludeResult.item( query.plExcludeResult.count - 1 );
- query.plExcludeResult.removeItem( item );
-
- if (item.isMemberOf( query.plIncludeResult ))
- {
- query.plIncludeResult.removeItem( item );
- }
- }
-
- query.plExcludeResult = null;
- query.progressbar.value = Math.floor(query.progressbar.value) + 1;
-
- query.nQueryIndex = 0;
- query.nQueryPosition++;
- }
-
- //****************************************************************
-
- function xxxRemoveFilteringOptions( query )
- {
- var nMaxIterate = 100;
-
- while (query.nQueryIndex < query.plIncludeResult.count)
- {
- if (--nMaxIterate <= 0)
- {
- query.progressbar.value = Math.floor(query.progressbar.value) + (query.nQueryIndex / query.plIncludeResult.count);
- return;
- }
-
- var item = query.plIncludeResult.item( query.nQueryIndex );
-
- // Remove playlists and urls
-
- if (!query.allow_playlists || !query.allow_urls)
- {
- var url = new String( item.sourceURL );
-
- if ( (!query.allow_playlists && ((-1 != url.search( 'asx$' )) || (-1 != url.search( 'm3u$' )))) ||
- (!query.allow_urls && (-1 != url.search( '://' ))) )
- {
- query.plIncludeResult.removeItem( item );
- continue;
- }
- }
-
- // Remove blank metadata
-
- if (!query.allow_blank)
- {
- if (('' == item.getItemInfo('Artist')) && ('' == item.getItemInfo('Album')))
- {
- query.plIncludeResult.removeItem( item );
- continue;
- }
- }
-
- // Remove items not matching our playcount specification
-
- if (query.playcount_filter)
- {
- var count = item.getItemInfo( 'PlayCount' );
-
- if ( (query.playcount_filter_comparison == 0 && query.playcount_filter_count <= count) ||
- (query.playcount_filter_comparison == 1 && query.playcount_filter_count != count) ||
- (query.playcount_filter_comparison == 2 && query.playcount_filter_count >= count) )
- {
- query.plIncludeResult.removeItem( item );
- continue;
- }
- }
-
- // Remove items not matching our play length specification
-
- if (query.playlength_filter)
- {
- var duration = item.duration;
-
- if ( (query.playlength_filter_comparison == 0 && duration <= query.playlength_filter_length) ||
- (query.playlength_filter_comparison == 1 && duration >= query.playlength_filter_length) )
- {
- query.plIncludeResult.removeItem( item );
- continue;
- }
- }
-
- if (query.generic_search)
- {
- var attrib = item.getItemInfo( query.generic_search_name );
- var sval = new String( attrib.toLowerCase() );
-
- if ( (query.generic_search_comparison == 0 && (-1 == sval.search( query.generic_search_value ))) ||
- (query.generic_search_comparison == 1 && (-1 != sval.search( query.generic_search_value ))) ||
- (query.generic_search_comparison == 2 && (sval != query.generic_search_value)) ||
- (query.generic_search_comparison == 3 && (sval == query.generic_search_value)) )
- {
- query.plIncludeResult.removeItem( item );
- continue;
- }
- }
-
- // we'll keep this one
-
- query.nQueryIndex++;
- }
-
- // now that we've removed everything we want to, get an initial length
- // from the playlist so that we may do length limiting
-
- query.nCurrentLength = getPlaylistLength( query.plIncludeResult );
- query.nOriginalLength = query.nCurrentLength;
-
- query.progressbar.value = Math.floor(query.progressbar.value) + 1;
-
- query.nQueryIndex = 0;
- query.nQueryPosition++;
- }
-
- //****************************************************************
-
- function xxxMatchLengthLimit( query )
- {
- if (query.playlength_limit)
- {
- var nMaxIterate = 25;
-
- while (query.nCurrentLength > query.playlength_limit_length)
- {
- if (--nMaxIterate <= 0)
- {
- query.progressbar.value = Math.floor(query.progressbar.value) + ((query.nOriginalLength - query.nCurrentLength) / (query.nOriginalLength - query.playlength_limit_length));
- return;
- }
-
- var nDelIndex = 0;
-
- if (query.playcount_favoring)
- {
- // for playcount favoring we take a sample of items to pick the item to
- // delete. We then delete the one with the highest (or lowest)
- // playcount avaialable.
-
- var rgPlaycount = new Array();
- var rgIndex = new Array();
- var nMax = 0;
-
- for (var nIndex = 0; nIndex < query.playcount_favoring_sample; nIndex++)
- {
- rgIndex[nIndex] = rand( query.plIncludeResult.count );
- rgPlaycount[nIndex] = query.plIncludeResult.item( rgIndex[nIndex] ).getItemInfo( 'PlayCount' );
- }
-
- var nSelection = 0;
-
- for (var nIndex = 1; nIndex < rgPlaycount.length; nIndex++)
- {
- if ( (query.playcount_favoring_comparison == 0 && rgPlaycount[nIndex] < rgPlaycount[nSelection]) ||
- (query.playcount_favoring_comparison == 1 && rgPlaycount[nIndex] > rgPlaycount[nSelection]) )
- {
- nSelection = nIndex;
- }
- }
-
- nDelIndex = rgIndex[ nSelection ];
- }
- else
- {
- nDelIndex = rand( query.plIncludeResult.count );
- }
-
- var item = query.plIncludeResult.item( nDelIndex );
- query.nCurrentLength -= item.duration;
- query.plIncludeResult.removeItem( item );
- }
-
- query.progressbar.value = Math.floor(query.progressbar.value) + 1;
- }
-
- query.nQueryIndex = 0;
- query.nQueryPosition++;
- }
-
- //****************************************************************
-
- function xxxShufflePlaylist( query )
- {
- if (query.shuffle_playlist)
- {
- var nMaxIterate = 100;
-
- while (query.nQueryIndex < (query.plIncludeResult.count * 2))
- {
- if (--nMaxIterate <= 0)
- {
- query.progressbar.value = Math.floor(query.progressbar.value) + (query.nQueryIndex / (query.plIncludeResult.count * 2));
- return;
- }
-
- query.plIncludeResult.moveItem( rand(query.plIncludeResult.count), rand(query.plIncludeResult.count) );
- query.nQueryIndex++;
- }
-
- query.progressbar.value = Math.floor(query.progressbar.value) + 1;
- }
-
- query.nQueryIndex = 0;
- query.nQueryPosition++;
- }
-
- //****************************************************************
-
- function xxxPrepareLibraryPlaylist( query )
- {
- query.plLibraryResult = null;
-
- if (query.playlistname != '')
- {
- query.plLibraryResult = getLibraryPlaylist( query.playlistname );
-
- if (query.plLibraryResult != null)
- {
- // If this is the playlist on core, then we need to make
- // sure that an empty playlist is thrown on core to avoid
- // being overwhelmed with playlist rebuilding while we make
- // changes.
-
- if (!player.currentPlaylist || query.plLibraryResult.isIdentical( player.currentPlaylist ))
- {
- player.currentPlaylist = player.mediaCollection.getByAlbum( "xxx_foo_i_dont_exist_xxx" );
- }
-
- player.playlistCollection.remove( query.plLibraryResult );
- query.plLibraryResult = null;
- }
- }
-
- query.nQueryIndex = 0;
- query.nQueryPosition++;
- }
-
- //****************************************************************
-
- function xxxSaveLibraryPlaylist( query )
- {
- if (query.playlistname != '')
- {
- query.plIncludeResult.name = query.playlistname;
- query.plLibraryResult = player.playlistCollection.importPlaylist( query.plIncludeResult );
-
- query.progressbar.value = Math.floor(query.progressbar.value) + 1;
- }
-
- query.nQueryIndex = 0;
- query.nQueryPosition++;
- }
-
- //****************************************************************
-
- function xxxCompleteQuery( query )
- {
- query.progressbar.value = query.progressbar.max;
-
- // max out query position to end the query
-
- query.plQueryResult = query.plIncludeResult;
- query.plIncludeResult = null;
- query.plExcludeResult = null;
- query.performing_query = false;
- query.nQueryPosition = 1000;
-
- if (query.completeQuery)
- {
- query.completeQuery();
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //****************************************************************
- // utility functions
- //****************************************************************
-
- function getStringFromAttributeStringCollection( collection )
- {
- var string = '';
-
- for (var nIndex = 0; nIndex < collection.count; nIndex++)
- {
- if (string != '')
- {
- string += '\r';
- }
- string += collection.item( nIndex );
- }
-
- return string;
- }
-
- //****************************************************************
-
- function inArray( nValue, array )
- {
- var i = 0;
- while (i < array.length)
- {
- if (array[i++] == nValue)
- {
- return true;
- }
- }
- return false;
- }
-
- //****************************************************************
-
- function arrayPosition( nValue, array )
- {
- var i = 0;
- while (i < array.length)
- {
- if (array[i++] == nValue)
- {
- return (i-1);
- }
- }
- return -1;
- }
-
- //****************************************************************
-
- function removeItemFromArray( nValue, array )
- {
- var i = 0;
- while (i < array.length)
- {
- if (array[i++] == nValue)
- {
- while (i < array.length)
- {
- array[i - 1] = array[i];
- i++;
- }
- break;
- }
- }
- array.length = (array.length - 1);
- }
-
- //****************************************************************
-
- function addInclude( nIndex, include_array, exclude_array )
- {
- if (inArray( nIndex, include_array ))
- {
- removeItemFromArray( nIndex, include_array );
- }
- else
- {
- if (inArray( nIndex, exclude_array ))
- {
- removeItemFromArray( nIndex, exclude_array );
- }
- include_array[ include_array.length ] = nIndex;
- }
- }
-
- //****************************************************************
-
- function addExclude( nIndex, include_array, exclude_array )
- {
- if (inArray( nIndex, exclude_array ))
- {
- removeItemFromArray( nIndex, exclude_array );
- }
- else
- {
- if (inArray( nIndex, include_array ))
- {
- removeItemFromArray( nIndex, include_array );
- }
- exclude_array[ exclude_array.length ] = nIndex;
- }
- }
-
- //****************************************************************
- // This function is a utility function used to return a readable
- // string from a number of seconds (basically a duration string)
-
- function formatSecondsString( seconds )
- {
- var str = '';
-
- var hours = Math.floor( seconds / (60 * 60) );
- var minutes = Math.floor( (seconds - (hours * 60 * 60)) / 60 );
- var seconds = Math.floor( seconds % 60 );
-
- if (hours > 0)
- {
- str += hours + ':';
- if (minutes < 10)
- {
- str += '0';
- }
- }
- str += minutes + ':';
- if (seconds < 10)
- {
- str += '0';
- }
- str += seconds;
-
- return str;
- }
-
- //****************************************************************
- // This function is a utility function used to return a readable
- // string from a number of seconds (basically a duration string)
-
- function formatMinutesString( seconds )
- {
- var str = '';
-
- var hours = Math.floor( seconds / (60 * 60) );
- var minutes = Math.floor( (seconds - (hours * 60 * 60)) / 60 );
-
- if (hours > 0)
- {
- str += hours + ' hr';
- if (minutes > 0)
- {
- str += ' ';
- }
- }
-
- if (minutes > 0)
- {
- str += minutes + ' min';
- }
-
- return str;
- }
-
- //****************************************************************
- // This is a simple function designed to return the length (in
- // seconds) of a given playlist
-
- function getPlaylistLength( playlist )
- {
- var plLength = 0;
-
- for (var nIndex = 0; nIndex < playlist.count; nIndex++)
- {
- plLength += playlist.item(nIndex).duration;
- }
-
- return plLength;
- }
-
-
- //****************************************************************
- // This function allows fetching of a random number
-
- var now = new Date();
- var seed = now.getTime() % 0xffffffff;
-
- function rand(n)
- {
- seed = (0x015a4e35 * seed) % 0x7fffffff;
- return (seed >> 16) % n;
- }
-
-
- //****************************************************************
- // This function allows fetching of a random number
-
- function getLibraryPlaylist( playlistname )
- {
- var collection = player.playlistCollection.getAll();
- for (var nIndex = 0; nIndex < collection.count; nIndex++)
- {
- if (collection.item(nIndex).name == playlistname)
- {
- return collection.item(nIndex);
- }
- }
- return null;
- }
-
-
- //****************************************************************
- // This function assures that indexes pointing to an old playlist
- // collection are valid in a new playlsit collection
-
- function reconcilePlaylistArray( oldCollection, newCollection, verify_array )
- {
- for (var nIndex = 0; nIndex < verify_array.length; nIndex++)
- {
- var found = false;
- var name = oldCollection.item( verify_array[nIndex] ).name;
-
- for (var nInner = 0; nInner < newCollection.count; nInner++)
- {
- if (name == newCollection.item( nInner ).name)
- {
- found = true;
- verify_array[nIndex] = nInner;
- break;
- }
- }
-
- if (!found)
- {
- // If we didn't find it, then we need to remove it
- // from the array
-
- var nInner = nIndex + 1;
- while (nInner < verify_array.length)
- {
- verify_array[nInner - 1] = verify_array[nInner];
- nInner++;
- }
- verify_array.length = verify_array.length - 1;
-
- nIndex--;
- }
- }
- }
-
-