+/***************************************************************************
+ * The following functions are local
+ ***************************************************************************/
+
+/* Enqueue an item for preparsing, and play it, if needed */
+static void GoAndPreparse( playlist_t *p_playlist, int i_mode,
+ playlist_item_t *p_item_cat,
+ playlist_item_t *p_item_one )
+{
+ if( (i_mode & PLAYLIST_GO ) )
+ {
+ playlist_item_t *p_parent = p_item_one;
+ playlist_item_t *p_toplay = NULL;
+ while( p_parent )
+ {
+ if( p_parent == p_playlist->p_root_category )
+ {
+ p_toplay = p_item_cat; break;
+ }
+ else if( p_parent == p_playlist->p_root_onelevel )
+ {
+ p_toplay = p_item_one; break;
+ }
+ p_parent = p_parent->p_parent;
+ }
+ assert( p_toplay );
+ p_playlist->request.b_request = VLC_TRUE;
+ p_playlist->request.i_skip = 0;
+ p_playlist->request.p_item = p_toplay;
+ if( p_playlist->p_input )
+ input_StopThread( p_playlist->p_input );
+ p_playlist->request.i_status = PLAYLIST_RUNNING;
+ vlc_cond_signal( &p_playlist->object_wait );
+ }
+ /* Preparse if PREPARSE or SPREPARSE & not enough meta */
+ if( p_playlist->b_auto_preparse &&
+ (i_mode & PLAYLIST_PREPARSE ||
+ ( i_mode & PLAYLIST_SPREPARSE &&
+ ( !p_item_cat->p_input->p_meta || (p_item_cat->p_input->p_meta &&
+ ( EMPTY_STR( p_item_cat->p_input->p_meta->psz_artist ) ||
+ EMPTY_STR( p_item_cat->p_input->p_meta->psz_album ) )
+ )
+ )
+ ) ) )
+ playlist_PreparseEnqueue( p_playlist, p_item_cat->p_input );
+ /* If we already have it, signal it */
+ else if( p_item_cat->p_input->p_meta &&
+ !EMPTY_STR( p_item_cat->p_input->p_meta->psz_artist ) &&
+ !EMPTY_STR( p_item_cat->p_input->p_meta->psz_album ) )
+ p_item_cat->p_input->p_meta->i_status = ITEM_PREPARSED;
+}
+
+/* Add the playlist item to the requested node and fire a notification */
+static void AddItem( playlist_t *p_playlist, playlist_item_t *p_item,
+ playlist_item_t *p_node, int i_mode, int i_pos )
+{
+ ARRAY_APPEND(p_playlist->items, p_item);
+ ARRAY_APPEND(p_playlist->all_items, p_item);
+ p_playlist->i_enabled ++;
+
+ if( i_pos == PLAYLIST_END )
+ playlist_NodeAppend( p_playlist, p_item, p_node );
+ else
+ playlist_NodeInsert( p_playlist, p_item, p_node, i_pos );
+
+ if( !p_playlist->b_doing_ml )
+ playlist_SendAddNotify( p_playlist, p_item->i_id, p_node->i_id,
+ !( i_mode & PLAYLIST_NO_REBUILD ) );
+}
+
+/* Actually convert an item to a node */
+static void ChangeToNode( playlist_t *p_playlist, playlist_item_t *p_item )