#include "playlist.h"
#include <stdlib.h>
#include <string.h>

/* Tree view columns */
enum {
    COL_INDEX,
    COL_TITLE,
    COL_PATH,
    COL_PLAYING,
    N_COLUMNS
};

struct Playlist {
    Player *player;
    
    /* Main container */
    GtkWidget *vbox;
    GtkWidget *scrolled_window;
    GtkWidget *tree_view;
    GtkListStore *list_store;
    
    /* Toolbar */
    GtkWidget *toolbar;
    GtkWidget *btn_add;
    GtkWidget *btn_remove;
    GtkWidget *btn_clear;
    GtkWidget *btn_shuffle;
    GtkWidget *btn_move_up;
    GtkWidget *btn_move_down;
    
    /* Repeat/Shuffle */
    GtkWidget *btn_repeat;
    PlaylistRepeatMode repeat_mode;
    gboolean shuffle_enabled;
    
    /* Current playing index */
    int current_index;
    
    /* Callback */
    PlaylistItemActivatedCallback item_callback;
    gpointer item_callback_data;
};

/* Forward declarations */
static void on_add_clicked(GtkButton *button, gpointer data);
static void on_remove_clicked(GtkButton *button, gpointer data);
static void on_clear_clicked(GtkButton *button, gpointer data);
static void on_shuffle_toggled(GtkToggleToolButton *button, gpointer data);
static void on_move_up_clicked(GtkButton *button, gpointer data);
static void on_move_down_clicked(GtkButton *button, gpointer data);
static void on_repeat_toggled(GtkToggleToolButton *button, gpointer data);
static void on_row_activated(GtkTreeView *tree_view, GtkTreePath *path,
                             GtkTreeViewColumn *column, gpointer data);

static void update_playing_indicator(Playlist *playlist);
static char* get_filename_from_path(const char *path);

Playlist* playlist_new(Player *player)
{
    Playlist *playlist = g_new0(Playlist, 1);
    playlist->player = player;
    playlist->current_index = -1;
    playlist->repeat_mode = PLAYLIST_REPEAT_NONE;
    playlist->shuffle_enabled = FALSE;
    
    /* Main vertical box */
    playlist->vbox = gtk_vbox_new(FALSE, 0);
    
    /* Toolbar */
    playlist->toolbar = gtk_toolbar_new();
    gtk_toolbar_set_style(GTK_TOOLBAR(playlist->toolbar), GTK_TOOLBAR_ICONS);
    gtk_toolbar_set_icon_size(GTK_TOOLBAR(playlist->toolbar), GTK_ICON_SIZE_SMALL_TOOLBAR);
    
    /* Add button */
    GtkToolItem *add_item = gtk_tool_button_new_from_stock(GTK_STOCK_ADD);
    gtk_widget_set_tooltip_text(GTK_WIDGET(add_item), "Add files");
    g_signal_connect(add_item, "clicked", G_CALLBACK(on_add_clicked), playlist);
    gtk_toolbar_insert(GTK_TOOLBAR(playlist->toolbar), add_item, -1);
    
    /* Remove button */
    GtkToolItem *remove_item = gtk_tool_button_new_from_stock(GTK_STOCK_REMOVE);
    gtk_widget_set_tooltip_text(GTK_WIDGET(remove_item), "Remove selected");
    g_signal_connect(remove_item, "clicked", G_CALLBACK(on_remove_clicked), playlist);
    gtk_toolbar_insert(GTK_TOOLBAR(playlist->toolbar), remove_item, -1);
    
    /* Clear button */
    GtkToolItem *clear_item = gtk_tool_button_new_from_stock(GTK_STOCK_CLEAR);
    gtk_widget_set_tooltip_text(GTK_WIDGET(clear_item), "Clear playlist");
    g_signal_connect(clear_item, "clicked", G_CALLBACK(on_clear_clicked), playlist);
    gtk_toolbar_insert(GTK_TOOLBAR(playlist->toolbar), clear_item, -1);
    
    /* Separator */
    gtk_toolbar_insert(GTK_TOOLBAR(playlist->toolbar), gtk_separator_tool_item_new(), -1);
    
    /* Move up */
    GtkToolItem *up_item = gtk_tool_button_new_from_stock(GTK_STOCK_GO_UP);
    gtk_widget_set_tooltip_text(GTK_WIDGET(up_item), "Move up");
    g_signal_connect(up_item, "clicked", G_CALLBACK(on_move_up_clicked), playlist);
    gtk_toolbar_insert(GTK_TOOLBAR(playlist->toolbar), up_item, -1);
    
    /* Move down */
    GtkToolItem *down_item = gtk_tool_button_new_from_stock(GTK_STOCK_GO_DOWN);
    gtk_widget_set_tooltip_text(GTK_WIDGET(down_item), "Move down");
    g_signal_connect(down_item, "clicked", G_CALLBACK(on_move_down_clicked), playlist);
    gtk_toolbar_insert(GTK_TOOLBAR(playlist->toolbar), down_item, -1);
    
    /* Separator */
    gtk_toolbar_insert(GTK_TOOLBAR(playlist->toolbar), gtk_separator_tool_item_new(), -1);
    
    /* Shuffle button */
    GtkToolItem *shuffle_item = gtk_toggle_tool_button_new();
    gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(shuffle_item), "media-playlist-shuffle");
    gtk_tool_button_set_label(GTK_TOOL_BUTTON(shuffle_item), "Shuffle");
    gtk_tool_item_set_is_important(shuffle_item, TRUE);
    gtk_widget_set_tooltip_text(GTK_WIDGET(shuffle_item), "Shuffle");
    g_signal_connect(shuffle_item, "toggled", G_CALLBACK(on_shuffle_toggled), playlist);
    gtk_toolbar_insert(GTK_TOOLBAR(playlist->toolbar), shuffle_item, -1);
    playlist->btn_shuffle = GTK_WIDGET(shuffle_item);
    
    /* Repeat button - back to toggle button */
    GtkToolItem *repeat_item = gtk_toggle_tool_button_new();
    gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(repeat_item), "media-playlist-repeat");
    gtk_tool_button_set_label(GTK_TOOL_BUTTON(repeat_item), "Repeat");
    gtk_tool_item_set_is_important(repeat_item, TRUE);
    gtk_widget_set_tooltip_text(GTK_WIDGET(repeat_item), "Repeat: Off");
    g_signal_connect(repeat_item, "toggled", G_CALLBACK(on_repeat_toggled), playlist);
    gtk_toolbar_insert(GTK_TOOLBAR(playlist->toolbar), repeat_item, -1);
    playlist->btn_repeat = GTK_WIDGET(repeat_item);
    
    gtk_box_pack_start(GTK_BOX(playlist->vbox), playlist->toolbar, FALSE, FALSE, 0);
    
    /* List store */
    playlist->list_store = gtk_list_store_new(N_COLUMNS, 
                                               G_TYPE_INT,     /* Index */
                                               G_TYPE_STRING,  /* Title */
                                               G_TYPE_STRING,  /* Path */
                                               G_TYPE_BOOLEAN);/* Playing */
    
    /* Tree view */
    playlist->tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(playlist->list_store));
    g_object_unref(playlist->list_store);
    
    /* Index column */
    GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
    GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(
        "#", renderer, "text", COL_INDEX, NULL);
    gtk_tree_view_column_set_min_width(column, 30);
    gtk_tree_view_append_column(GTK_TREE_VIEW(playlist->tree_view), column);
    
    /* Playing indicator (using bold font for now playing) */
    renderer = gtk_cell_renderer_text_new();
    g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
    column = gtk_tree_view_column_new_with_attributes(
        "Title", renderer, "text", COL_TITLE, NULL);
    gtk_tree_view_column_set_expand(column, TRUE);
    gtk_tree_view_append_column(GTK_TREE_VIEW(playlist->tree_view), column);
    
    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(playlist->tree_view), TRUE);
    gtk_tree_view_set_reorderable(GTK_TREE_VIEW(playlist->tree_view), TRUE);
    
    /* Double-click to play */
    g_signal_connect(playlist->tree_view, "row-activated", G_CALLBACK(on_row_activated), playlist);
    
    /* Scrolled window */
    playlist->scrolled_window = gtk_scrolled_window_new(NULL, NULL);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(playlist->scrolled_window),
                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
    gtk_container_add(GTK_CONTAINER(playlist->scrolled_window), playlist->tree_view);
    
    gtk_box_pack_start(GTK_BOX(playlist->vbox), playlist->scrolled_window, TRUE, TRUE, 0);
    
    /* Show all internal widgets, but hide the main container initially */
    gtk_widget_show_all(playlist->vbox);
    gtk_widget_hide(playlist->vbox);
    
    return playlist;
}

void playlist_destroy(Playlist *playlist)
{
    if (!playlist) return;
    g_free(playlist);
}

GtkWidget* playlist_get_widget(Playlist *playlist)
{
    if (!playlist) return NULL;
    return playlist->vbox;
}

static char* get_filename_from_path(const char *path)
{
    if (!path) return g_strdup("Unknown");
    
    const char *filename = strrchr(path, '/');
    if (filename) {
        return g_strdup(filename + 1);
    }
    return g_strdup(path);
}

void playlist_add_file(Playlist *playlist, const char *path, gboolean append)
{
    if (!playlist || !path) return;
    
    GtkTreeIter iter;
    gtk_list_store_append(playlist->list_store, &iter);
    
    int count = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(playlist->list_store), NULL);
    char *title = get_filename_from_path(path);
    
    gtk_list_store_set(playlist->list_store, &iter,
                       COL_INDEX, count,
                       COL_TITLE, title,
                       COL_PATH, path,
                       COL_PLAYING, FALSE,
                       -1);
    
    g_free(title);
    
    /* Also add to mpv playlist */
    player_load_file(playlist->player, path, append);
}

void playlist_add_files(Playlist *playlist, GSList *paths)
{
    if (!playlist || !paths) return;
    
    GSList *iter;
    for (iter = paths; iter != NULL; iter = iter->next) {
        playlist_add_file(playlist, (const char *)iter->data, TRUE);
    }
}

void playlist_remove_selected(Playlist *playlist)
{
    if (!playlist) return;
    
    GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(playlist->tree_view));
    GtkTreeIter iter;
    GtkTreeModel *model = GTK_TREE_MODEL(playlist->list_store);
    
    if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
        GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
        int *indices = gtk_tree_path_get_indices(path);
        int index = indices[0];
        gtk_tree_path_free(path);
        
        gtk_list_store_remove(playlist->list_store, &iter);
        player_playlist_remove(playlist->player, index);
        
        /* Renumber remaining items */
        if (gtk_tree_model_get_iter_first(model, &iter)) {
            int i = 1;
            do {
                gtk_list_store_set(playlist->list_store, &iter, COL_INDEX, i++, -1);
            } while (gtk_tree_model_iter_next(model, &iter));
        }
    }
}

void playlist_clear(Playlist *playlist)
{
    if (!playlist) return;
    
    gtk_list_store_clear(playlist->list_store);
    player_playlist_clear(playlist->player);
    playlist->current_index = -1;
}

void playlist_refill_player(Playlist *playlist)
{
    if (!playlist) return;
    
    GtkTreeIter iter;
    GtkTreeModel *model = GTK_TREE_MODEL(playlist->list_store);
    
    if (gtk_tree_model_get_iter_first(model, &iter)) {
        gboolean first = TRUE;
        do {
            char *path = NULL;
            gtk_tree_model_get(model, &iter, COL_PATH, &path, -1);
            if (path) {
                player_load_file(playlist->player, path, !first);
                g_free(path);
                first = FALSE;
            }
        } while (gtk_tree_model_iter_next(model, &iter));
    }
}

void playlist_save_to_file(Playlist *playlist, const char *filename)
{
    if (!playlist || !filename) return;
    
    FILE *f = fopen(filename, "w");
    if (!f) return;
    
    fprintf(f, "#EXTM3U\n");
    
    GtkTreeModel *model = GTK_TREE_MODEL(playlist->list_store);
    GtkTreeIter iter;
    
    if (gtk_tree_model_get_iter_first(model, &iter)) {
        do {
            char *path = NULL;
            gtk_tree_model_get(model, &iter, COL_PATH, &path, -1);
            if (path) {
                fprintf(f, "%s\n", path);
                g_free(path);
            }
        } while (gtk_tree_model_iter_next(model, &iter));
    }
    
    fclose(f);
}

void playlist_play_selected(Playlist *playlist)
{
    if (!playlist) return;
    
    GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(playlist->tree_view));
    GtkTreeIter iter;
    GtkTreeModel *model = GTK_TREE_MODEL(playlist->list_store);
    
    if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
        GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
        int *indices = gtk_tree_path_get_indices(path);
        int index = indices[0];
        gtk_tree_path_free(path);
        
        playlist_play_index(playlist, index);
    }
}

void playlist_play_index(Playlist *playlist, int index)
{
    if (!playlist) return;
    
    int count = playlist_get_count(playlist);
    if (index < 0 || index >= count) return;
    
    player_playlist_play_index(playlist->player, index);
    playlist->current_index = index;
    update_playing_indicator(playlist);
}

void playlist_play_next(Playlist *playlist)
{
    if (!playlist) return;
    
    int count = playlist_get_count(playlist);
    if (count == 0) return;
    
    int next_index = playlist->current_index + 1;
    
    if (next_index >= count) {
        if (playlist->repeat_mode == PLAYLIST_REPEAT_ALL) {
            next_index = 0;
        } else {
            return; /* End of playlist */
        }
    }
    
    player_playlist_play_index(playlist->player, next_index);
    
    playlist->current_index = next_index;
    update_playing_indicator(playlist);
}

void playlist_play_prev(Playlist *playlist)
{
    if (!playlist) return;
    
    int count = playlist_get_count(playlist);
    if (count == 0) return;
    
    int prev_index = playlist->current_index - 1;
    
    if (prev_index < 0) {
        if (playlist->repeat_mode == PLAYLIST_REPEAT_ALL) {
            prev_index = count - 1;
        } else {
            prev_index = 0;
        }
    }
    
    player_playlist_play_index(playlist->player, prev_index);
    playlist->current_index = prev_index;
    update_playing_indicator(playlist);
}

int playlist_get_count(Playlist *playlist)
{
    if (!playlist) return 0;
    return gtk_tree_model_iter_n_children(GTK_TREE_MODEL(playlist->list_store), NULL);
}

int playlist_get_current_index(Playlist *playlist)
{
    if (!playlist) return -1;
    return playlist->current_index;
}

void playlist_set_current_index(Playlist *playlist, int index)
{
    if (!playlist) return;
    playlist->current_index = index;
    update_playing_indicator(playlist);
}

void playlist_set_repeat_mode(Playlist *playlist, PlaylistRepeatMode mode)
{
    if (!playlist) return;
    playlist->repeat_mode = mode;
    
    /* Update button state */
    g_signal_handlers_block_by_func(playlist->btn_repeat, on_repeat_toggled, playlist);
    gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(playlist->btn_repeat), 
                                      (mode == PLAYLIST_REPEAT_ALL));
    g_signal_handlers_unblock_by_func(playlist->btn_repeat, on_repeat_toggled, playlist);
    
    const char *tooltip = (mode == PLAYLIST_REPEAT_ALL) ? "Repeat: All" : "Repeat: Off";
    gtk_widget_set_tooltip_text(playlist->btn_repeat, tooltip);
    
    /* Sync with mpv */
    player_set_loop(playlist->player, (mode == PLAYLIST_REPEAT_ALL));
}

PlaylistRepeatMode playlist_get_repeat_mode(Playlist *playlist)
{
    if (!playlist) return PLAYLIST_REPEAT_NONE;
    return playlist->repeat_mode;
}

void playlist_set_shuffle(Playlist *playlist, gboolean shuffle)
{
    if (!playlist) return;
    playlist->shuffle_enabled = shuffle;
    
    /* Update button state */
    g_signal_handlers_block_by_func(playlist->btn_shuffle, on_shuffle_toggled, playlist);
    gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(playlist->btn_shuffle), shuffle);
    g_signal_handlers_unblock_by_func(playlist->btn_shuffle, on_shuffle_toggled, playlist);
    
    /* Synchronize with player */
    player_set_shuffle(playlist->player, shuffle);
}

gboolean playlist_get_shuffle(Playlist *playlist)
{
    if (!playlist) return FALSE;
    return playlist->shuffle_enabled;
}

void playlist_shuffle_now(Playlist *playlist)
{
    /* Legacy - now handled by player_set_shuffle property */
    (void)playlist;
}

void playlist_move_up(Playlist *playlist)
{
    if (!playlist) return;
    
    GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(playlist->tree_view));
    GtkTreeIter iter, prev;
    GtkTreeModel *model = GTK_TREE_MODEL(playlist->list_store);
    
    if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
        GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
        int index = gtk_tree_path_get_indices(path)[0];
        
        if (gtk_tree_path_prev(path)) {
            if (gtk_tree_model_get_iter(model, &prev, path)) {
                gtk_list_store_swap(playlist->list_store, &iter, &prev);
                player_playlist_move(playlist->player, index, index - 1);
                
                /* Renumber */
                GtkTreeIter it;
                if (gtk_tree_model_get_iter_first(model, &it)) {
                    int i = 1;
                    do {
                        gtk_list_store_set(playlist->list_store, &it, COL_INDEX, i++, -1);
                    } while (gtk_tree_model_iter_next(model, &it));
                }
            }
        }
        gtk_tree_path_free(path);
    }
}

void playlist_move_down(Playlist *playlist)
{
    if (!playlist) return;
    
    GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(playlist->tree_view));
    GtkTreeIter iter, next;
    GtkTreeModel *model = GTK_TREE_MODEL(playlist->list_store);
    
    if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
        GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
        int index = gtk_tree_path_get_indices(path)[0];
        
        next = iter;
        if (gtk_tree_model_iter_next(model, &next)) {
            gtk_list_store_swap(playlist->list_store, &iter, &next);
            player_playlist_move(playlist->player, index, index + 1);
            
            /* Renumber */
            GtkTreeIter it;
            if (gtk_tree_model_get_iter_first(model, &it)) {
                int i = 1;
                do {
                    gtk_list_store_set(playlist->list_store, &it, COL_INDEX, i++, -1);
                } while (gtk_tree_model_iter_next(model, &it));
            }
        }
        gtk_tree_path_free(path);
    }
}

void playlist_set_item_activated_callback(Playlist *playlist,
                                          PlaylistItemActivatedCallback callback,
                                          gpointer user_data)
{
    if (!playlist) return;
    playlist->item_callback = callback;
    playlist->item_callback_data = user_data;
}

void playlist_sync_from_player(Playlist *playlist)
{
    /* This would sync the UI playlist from mpv's internal playlist */
    /* For now, we keep them in sync by adding files through our interface */
    if (!playlist) return;
    
    /* Update current playing position */
    playlist->current_index = player_get_playlist_pos(playlist->player);
    update_playing_indicator(playlist);
}

static void update_playing_indicator(Playlist *playlist)
{
    if (!playlist) return;
    
    GtkTreeModel *model = GTK_TREE_MODEL(playlist->list_store);
    GtkTreeIter iter;
    
    if (!gtk_tree_model_get_iter_first(model, &iter)) return;
    
    int i = 0;
    do {
        gtk_list_store_set(playlist->list_store, &iter, 
                           COL_PLAYING, (i == playlist->current_index), -1);
        i++;
    } while (gtk_tree_model_iter_next(model, &iter));
    
    /* Highlight and scroll to the current item if valid */
    if (playlist->current_index >= 0 && playlist->current_index < i) {
        GtkTreePath *path = gtk_tree_path_new_from_indices(playlist->current_index, -1);
        gtk_tree_view_set_cursor(GTK_TREE_VIEW(playlist->tree_view), path, NULL, FALSE);
        gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(playlist->tree_view), path, NULL, FALSE, 0.5, 0.0);
        gtk_tree_path_free(path);
    }
}

/* Signal handlers */

static void on_add_clicked(GtkButton *button, gpointer data)
{
    (void)button;
    Playlist *playlist = (Playlist *)data;
    
    GtkWidget *dialog = gtk_file_chooser_dialog_new(
        "Add Files",
        GTK_WINDOW(gtk_widget_get_toplevel(playlist->vbox)),
        GTK_FILE_CHOOSER_ACTION_OPEN,
        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
        GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
        NULL);
    
    gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
    
    /* Add file filters */
    GtkFileFilter *video_filter = gtk_file_filter_new();
    gtk_file_filter_set_name(video_filter, "Video Files");
    gtk_file_filter_add_mime_type(video_filter, "video/*");
    gtk_file_filter_add_pattern(video_filter, "*.mkv");
    gtk_file_filter_add_pattern(video_filter, "*.mp4");
    gtk_file_filter_add_pattern(video_filter, "*.avi");
    gtk_file_filter_add_pattern(video_filter, "*.wmv");
    gtk_file_filter_add_pattern(video_filter, "*.mov");
    gtk_file_filter_add_pattern(video_filter, "*.webm");
    gtk_file_filter_add_pattern(video_filter, "*.flv");
    gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), video_filter);
    
    GtkFileFilter *all_filter = gtk_file_filter_new();
    gtk_file_filter_set_name(all_filter, "All Files");
    gtk_file_filter_add_pattern(all_filter, "*");
    gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), all_filter);
    
    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
        GSList *filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
        playlist_add_files(playlist, filenames);
        g_slist_free_full(filenames, g_free);
    }
    
    gtk_widget_destroy(dialog);
}

static void on_remove_clicked(GtkButton *button, gpointer data)
{
    (void)button;
    Playlist *playlist = (Playlist *)data;
    playlist_remove_selected(playlist);
}

static void on_clear_clicked(GtkButton *button, gpointer data)
{
    (void)button;
    Playlist *playlist = (Playlist *)data;
    playlist_clear(playlist);
}

static void on_shuffle_toggled(GtkToggleToolButton *button, gpointer data)
{
    Playlist *playlist = (Playlist *)data;
    gboolean active = gtk_toggle_tool_button_get_active(button);
    playlist_set_shuffle(playlist, active);
}

static void on_move_up_clicked(GtkButton *button, gpointer data)
{
    (void)button;
    Playlist *playlist = (Playlist *)data;
    playlist_move_up(playlist);
}

static void on_move_down_clicked(GtkButton *button, gpointer data)
{
    (void)button;
    Playlist *playlist = (Playlist *)data;
    playlist_move_down(playlist);
}

static void on_repeat_toggled(GtkToggleToolButton *button, gpointer data)
{
    Playlist *playlist = (Playlist *)data;
    gboolean active = gtk_toggle_tool_button_get_active(button);
    
    if (active) {
        playlist_set_repeat_mode(playlist, PLAYLIST_REPEAT_ALL);
    } else {
        playlist_set_repeat_mode(playlist, PLAYLIST_REPEAT_NONE);
    }
}

static void on_row_activated(GtkTreeView *tree_view, GtkTreePath *path,
                             GtkTreeViewColumn *column, gpointer data)
{
    (void)tree_view;
    (void)column;
    Playlist *playlist = (Playlist *)data;
    
    int *indices = gtk_tree_path_get_indices(path);
    int index = indices[0];
    
    /* If mpv playlist is empty (e.g. after stop), refill it */
    if (player_get_playlist_count(playlist->player) == 0) {
        playlist_refill_player(playlist);
    }
    
    player_playlist_play_index(playlist->player, index);
    player_play(playlist->player); /* Force playback if paused */
    playlist->current_index = index;
    update_playing_indicator(playlist);
    
    if (playlist->item_callback) {
        GtkTreeIter iter;
        GtkTreeModel *model = GTK_TREE_MODEL(playlist->list_store);
        if (gtk_tree_model_get_iter(model, &iter, path)) {
            char *file_path;
            gtk_tree_model_get(model, &iter, COL_PATH, &file_path, -1);
            playlist->item_callback(file_path, playlist->item_callback_data);
            g_free(file_path);
        }
    }
}
