#include "dialogs.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include "ui.h"
#include "plugin_manager.h"

/* File filter helpers */
static void add_video_filters(GtkFileChooser *chooser)
{
    GtkFileFilter *media_filter = gtk_file_filter_new();
    gtk_file_filter_set_name(media_filter, "Media Files");
    gtk_file_filter_add_mime_type(media_filter, "video/*");
    gtk_file_filter_add_mime_type(media_filter, "audio/*");
    
    /* Common patterns */
    const char *patterns[] = {
        "*.mkv", "*.mp4", "*.avi", "*.wmv", "*.mov", "*.webm", "*.flv", "*.m4v", "*.ts", "*.m2ts", "*.vob", "*.ogv", "*.3gp",
        "*.mp3", "*.flac", "*.ogg", "*.wav", "*.m4a", "*.aac", "*.opus", NULL
    };
    for (int i = 0; patterns[i]; i++) {
        gtk_file_filter_add_pattern(media_filter, patterns[i]);
    }
    gtk_file_chooser_add_filter(chooser, media_filter);

    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/*");
    for (int i = 0; i < 13; i++) { /* First 13 are video */
        gtk_file_filter_add_pattern(video_filter, patterns[i]);
    }
    gtk_file_chooser_add_filter(chooser, video_filter);
    
    GtkFileFilter *audio_filter = gtk_file_filter_new();
    gtk_file_filter_set_name(audio_filter, "Audio Files");
    gtk_file_filter_add_mime_type(audio_filter, "audio/*");
    for (int i = 13; patterns[i]; i++) { /* Remaining are audio */
        gtk_file_filter_add_pattern(audio_filter, patterns[i]);
    }
    gtk_file_chooser_add_filter(chooser, audio_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(chooser, all_filter);
}

static void add_subtitle_filters(GtkFileChooser *chooser)
{
    GtkFileFilter *sub_filter = gtk_file_filter_new();
    gtk_file_filter_set_name(sub_filter, "Subtitle Files");
    gtk_file_filter_add_pattern(sub_filter, "*.srt");
    gtk_file_filter_add_pattern(sub_filter, "*.ass");
    gtk_file_filter_add_pattern(sub_filter, "*.ssa");
    gtk_file_filter_add_pattern(sub_filter, "*.sub");
    gtk_file_filter_add_pattern(sub_filter, "*.vtt");
    gtk_file_filter_add_pattern(sub_filter, "*.idx");
    gtk_file_filter_add_pattern(sub_filter, "*.pgs");
    gtk_file_filter_add_pattern(sub_filter, "*.sup");
    gtk_file_chooser_add_filter(chooser, sub_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(chooser, all_filter);
}

GSList* dialogs_open_files(GtkWindow *parent, Preferences *prefs)
{
    GtkWidget *dialog = gtk_file_chooser_dialog_new(
        "Open File(s)",
        parent,
        GTK_FILE_CHOOSER_ACTION_OPEN,
        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
        GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
        NULL);
    
    if (prefs && prefs->remember_last_dir && prefs->last_dir) {
        gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), prefs->last_dir);
    }
    
    gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
    add_video_filters(GTK_FILE_CHOOSER(dialog));
    
    GSList *result = NULL;
    
    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
        result = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
        
        if (prefs && prefs->remember_last_dir && result) {
            char *dir = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog));
            if (dir) {
                g_free(prefs->last_dir);
                prefs->last_dir = dir;
                preferences_save(prefs);
            }
        }
    }
    
    gtk_widget_destroy(dialog);
    return result;
}

char* dialogs_open_directory(GtkWindow *parent, Preferences *prefs)
{
    GtkWidget *dialog = gtk_file_chooser_dialog_new(
        "Open Folder",
        parent,
        GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
        GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
        NULL);
    
    if (prefs && prefs->remember_last_dir && prefs->last_dir) {
        gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), prefs->last_dir);
    }
    
    char *result = NULL;
    
    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
        result = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
        
        if (prefs && prefs->remember_last_dir && result) {
            char *dir = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog));
            if (dir) {
                g_free(prefs->last_dir);
                prefs->last_dir = dir;
                preferences_save(prefs);
            }
        }
    }
    
    gtk_widget_destroy(dialog);
    return result;
}

char* dialogs_open_url(GtkWindow *parent, Preferences *prefs)
{
    (void)prefs;
    GtkWidget *dialog = gtk_dialog_new_with_buttons(
        "Open URL",
        parent,
        GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
        GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
        NULL);
    
    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
    
    GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
    gtk_container_set_border_width(GTK_CONTAINER(content), 10);
    
    GtkWidget *hbox = gtk_hbox_new(FALSE, 10);
    
    GtkWidget *label = gtk_label_new("URL:");
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
    
    GtkWidget *entry = gtk_entry_new();
    gtk_entry_set_width_chars(GTK_ENTRY(entry), 50);
    gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
    gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
    
    gtk_box_pack_start(GTK_BOX(content), hbox, TRUE, TRUE, 0);
    gtk_widget_show_all(content);
    
    char *result = NULL;
    
    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
        const char *text = gtk_entry_get_text(GTK_ENTRY(entry));
        if (text && strlen(text) > 0) {
            result = g_strdup(text);
        }
    }
    
    gtk_widget_destroy(dialog);
    return result;
}

char* dialogs_open_subtitle(GtkWindow *parent, Preferences *prefs)
{
    GtkWidget *dialog = gtk_file_chooser_dialog_new(
        "Load Subtitle",
        parent,
        GTK_FILE_CHOOSER_ACTION_OPEN,
        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
        GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
        NULL);
    
    if (prefs && prefs->remember_last_dir && prefs->last_dir) {
        gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), prefs->last_dir);
    }
    
    add_subtitle_filters(GTK_FILE_CHOOSER(dialog));
    
    char *result = NULL;
    
    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
        result = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
        
        if (prefs && prefs->remember_last_dir && result) {
            char *dir = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog));
            if (dir) {
                g_free(prefs->last_dir);
                prefs->last_dir = dir;
                preferences_save(prefs);
            }
        }
    }
    
    gtk_widget_destroy(dialog);
    return result;
}

char* dialogs_save_playlist(GtkWindow *parent, Preferences *prefs)
{
    GtkWidget *dialog = gtk_file_chooser_dialog_new(
        "Save Playlist",
        parent,
        GTK_FILE_CHOOSER_ACTION_SAVE,
        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
        GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
        NULL);
    
    if (prefs && prefs->remember_last_dir && prefs->last_dir) {
        gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), prefs->last_dir);
    }
    
    gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
    gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), "playlist.m3u");
    
    GtkFileFilter *filter = gtk_file_filter_new();
    gtk_file_filter_set_name(filter, "M3U Playlist (*.m3u)");
    gtk_file_filter_add_pattern(filter, "*.m3u");
    gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), 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);
    
    char *result = NULL;
    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
        result = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
        
        if (prefs && prefs->remember_last_dir && result) {
            char *dir = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog));
            if (dir) {
                g_free(prefs->last_dir);
                prefs->last_dir = dir;
                preferences_save(prefs);
            }
        }
    }
    
    gtk_widget_destroy(dialog);
    return result;
}

char* dialogs_save_screenshot(GtkWindow *parent)
{
    GtkWidget *dialog = gtk_file_chooser_dialog_new(
        "Save Screenshot",
        parent,
        GTK_FILE_CHOOSER_ACTION_SAVE,
        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
        GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
        NULL);
    
    gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
    gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), "screenshot.png");
    
    GtkFileFilter *png_filter = gtk_file_filter_new();
    gtk_file_filter_set_name(png_filter, "PNG Images");
    gtk_file_filter_add_pattern(png_filter, "*.png");
    gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), png_filter);
    
    GtkFileFilter *jpg_filter = gtk_file_filter_new();
    gtk_file_filter_set_name(jpg_filter, "JPEG Images");
    gtk_file_filter_add_pattern(jpg_filter, "*.jpg");
    gtk_file_filter_add_pattern(jpg_filter, "*.jpeg");
    gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), jpg_filter);
    
    char *result = NULL;
    
    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
        result = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
    }
    
    gtk_widget_destroy(dialog);
    return result;
}

void dialogs_show_about(GtkWindow *parent)
{
    GtkWidget *dialog = gtk_dialog_new_with_buttons("About Kino",
                                                    parent,
                                                    GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
                                                    GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
                                                    NULL);
    gtk_window_set_default_size(GTK_WINDOW(dialog), 400, 320);

    GtkWidget *content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
    GtkWidget *notebook = gtk_notebook_new();
    gtk_box_pack_start(GTK_BOX(content_area), notebook, TRUE, TRUE, 0);

    /* --- Tab 1: About --- */
    GtkWidget *about_vbox = gtk_vbox_new(FALSE, 10);
    gtk_container_set_border_width(GTK_CONTAINER(about_vbox), 20);
    
    /* Icon */
    GdkPixbuf *pb = gdk_pixbuf_new_from_file("icon.png", NULL);
    if (!pb) pb = gdk_pixbuf_new_from_file("assets/icon.png", NULL);
    if (!pb) pb = gdk_pixbuf_new_from_file("/usr/local/lib/gtk2-mpv-player/icon.png", NULL);
    if (pb) {
        GdkPixbuf *scaled = gdk_pixbuf_scale_simple(pb, 64, 64, GDK_INTERP_BILINEAR);
        GtkWidget *image = gtk_image_new_from_pixbuf(scaled);
        gtk_box_pack_start(GTK_BOX(about_vbox), image, FALSE, FALSE, 0);
        g_object_unref(scaled);
        g_object_unref(pb);
    }

    GtkWidget *title_label = gtk_label_new(NULL);
    gtk_label_set_markup(GTK_LABEL(title_label), "<span size='xx-large' weight='bold'>Kino</span>");
    gtk_box_pack_start(GTK_BOX(about_vbox), title_label, FALSE, FALSE, 0);

    GtkWidget *version_label = gtk_label_new("Version 9.0");
    gtk_box_pack_start(GTK_BOX(about_vbox), version_label, FALSE, FALSE, 0);

    GtkWidget *comment_label = gtk_label_new("A lightweight GTK2 media player frontend (Kino) using libmpv.");
    gtk_label_set_line_wrap(GTK_LABEL(comment_label), TRUE);
    gtk_box_pack_start(GTK_BOX(about_vbox), comment_label, FALSE, FALSE, 10);

    GtkWidget *copyright_label = gtk_label_new("© 2026 laki");
    gtk_box_pack_start(GTK_BOX(about_vbox), copyright_label, FALSE, FALSE, 0);

    GtkWidget *link_label1 = gtk_link_button_new_with_label("https://github.com/mpv-player/mpv", "Powered by libmpv");
    gtk_box_pack_start(GTK_BOX(about_vbox), link_label1, FALSE, FALSE, 0);

    GtkWidget *link_label2 = gtk_link_button_new_with_label("https://lakiweb.net/article/gtk2/software-directory.html", "More GTK2 Software Available Here!");
    gtk_box_pack_start(GTK_BOX(about_vbox), link_label2, FALSE, FALSE, 0);

    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), about_vbox, gtk_label_new("About"));

    /* --- Tab 2: Credits --- */
    GtkWidget *credits_vbox = gtk_vbox_new(FALSE, 5);
    gtk_container_set_border_width(GTK_CONTAINER(credits_vbox), 15);
    
    const char *credits_text = 
        "<b>Developer:</b>\n"
        "laki\n\n"
        "<b>Core Technologies:</b>\n"
        "• mpv team (libmpv engine)\n"
        "• GTK team (UI toolkit)\n\n";
    
    GtkWidget *credits_label = gtk_label_new(NULL);
    gtk_label_set_markup(GTK_LABEL(credits_label), credits_text);
    gtk_label_set_justify(GTK_LABEL(credits_label), GTK_JUSTIFY_CENTER);
    gtk_box_pack_start(GTK_BOX(credits_vbox), credits_label, TRUE, TRUE, 0);

    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), credits_vbox, gtk_label_new("Credits"));

    /* --- Tab 3: License --- */
    GtkWidget *license_sw = gtk_scrolled_window_new(NULL, NULL);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(license_sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(license_sw), GTK_SHADOW_IN);
    
    GtkWidget *license_view = gtk_text_view_new();
    gtk_text_view_set_editable(GTK_TEXT_VIEW(license_view), FALSE);
    gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(license_view), FALSE);
    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(license_view), GTK_WRAP_WORD);
    gtk_container_set_border_width(GTK_CONTAINER(license_view), 10);
    
    const char *license_text = 
        "This program is free software: you can redistribute it and/or modify "
        "it under the terms of the GNU General Public License as published by "
        "the Free Software Foundation, either version 3 of the License, or "
        "(at your option) any later version.\n\n"
        "This program is distributed in the hope that it will be useful, "
        "but WITHOUT ANY WARRANTY; without even the implied warranty of "
        "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the "
        "GNU General Public License for more details.\n\n"
        "You should have received a copy of the GNU General Public License "
        "along with this program.  If not, see <https://www.gnu.org/licenses/>.";
    
    GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(license_view));
    gtk_text_buffer_set_text(buffer, license_text, -1);
    
    gtk_container_add(GTK_CONTAINER(license_sw), license_view);
    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), license_sw, gtk_label_new("License"));

    gtk_widget_show_all(dialog);
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
}

/* ============================================================================
 * Script Manager Dialog
 * ============================================================================ */

typedef struct {
    Player *player;
    GtkListStore *list_store;
    GtkTreeView *tree_view;
    GtkWidget *dialog;
} ScriptManagerData;

enum {
    COL_SCRIPT_STATUS = 0,
    COL_SCRIPT_NAME,
    COL_SCRIPT_PATH,
    COL_SCRIPT_ENABLED,
    NUM_SCRIPT_COLS
};

static void refresh_scripts_list(ScriptManagerData *data)
{
    gtk_list_store_clear(data->list_store);
    
    const char *config_dir = g_get_user_config_dir();
    char *scripts_dir = g_build_filename(config_dir, "gtk2-media-player", "scripts", NULL);
    
    DIR *dir = opendir(scripts_dir);
    if (dir) {
        struct dirent *entry;
        while ((entry = readdir(dir)) != NULL) {
            if (entry->d_name[0] == '.') continue;
            
            size_t len = strlen(entry->d_name);
            gboolean is_script = FALSE;
            gboolean is_enabled = TRUE;
            char *display_name = g_strdup(entry->d_name);
            
            if ((len > 4 && strcmp(entry->d_name + len - 4, ".lua") == 0) ||
                (len > 3 && strcmp(entry->d_name + len - 3, ".js") == 0)) {
                is_script = TRUE;
            } else if (len > 9 && strcmp(entry->d_name + len - 9, ".disabled") == 0) {
                is_script = TRUE;
                is_enabled = FALSE;
                /* Remove .disabled for display */
                display_name[len - 9] = '\0';
            }
            
            if (is_script) {
                GtkTreeIter iter;
                gtk_list_store_append(data->list_store, &iter);
                gtk_list_store_set(data->list_store, &iter,
                    COL_SCRIPT_STATUS, is_enabled ? "● Active" : "○ Disabled",
                    COL_SCRIPT_NAME, display_name,
                    COL_SCRIPT_PATH, entry->d_name,
                    COL_SCRIPT_ENABLED, is_enabled,
                    -1);
            }
            g_free(display_name);
        }
        closedir(dir);
    }
    g_free(scripts_dir);
}

static void on_script_toggled(GtkCellRendererToggle *cell, char *path_str, gpointer user_data)
{
    (void)cell;
    ScriptManagerData *data = (ScriptManagerData*)user_data;
    GtkTreeModel *model = GTK_TREE_MODEL(data->list_store);
    GtkTreeIter iter;

    if (gtk_tree_model_get_iter_from_string(model, &iter, path_str)) {
        char *filename;
        gboolean enabled;
        gtk_tree_model_get(model, &iter, COL_SCRIPT_PATH, &filename, COL_SCRIPT_ENABLED, &enabled, -1);
        
        const char *config_dir = g_get_user_config_dir();
        char *old_path = g_build_filename(config_dir, "gtk2-media-player", "scripts", filename, NULL);
        char *new_path;
        
        enabled = !enabled; /* Toggle state */
        
        if (!enabled) {
            new_path = g_strdup_printf("%s.disabled", old_path);
        } else {
            /* Remove .disabled suffix */
            size_t len = strlen(old_path);
            if (len > 9) {
                new_path = g_strndup(old_path, len - 9);
            } else {
                new_path = g_strdup(old_path);
            }
        }
        
        if (rename(old_path, new_path) == 0) {
            if (enabled) {
                player_load_script(data->player, new_path);
            }
            refresh_scripts_list(data);
        }
        
        g_free(old_path);
        g_free(new_path);
        g_free(filename);
    }
}

static void on_install_script_clicked(GtkButton *button, gpointer user_data)
{
    (void)button;
    ScriptManagerData *data = (ScriptManagerData*)user_data;
    
    GtkWidget *chooser = gtk_file_chooser_dialog_new("Install Script",
        GTK_WINDOW(data->dialog),
        GTK_FILE_CHOOSER_ACTION_OPEN,
        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
        GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
        NULL);
        
    GtkFileFilter *filter = gtk_file_filter_new();
    gtk_file_filter_set_name(filter, "Scripts (*.lua, *.js)");
    gtk_file_filter_add_pattern(filter, "*.lua");
    gtk_file_filter_add_pattern(filter, "*.js");
    gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(chooser), filter);
    
    if (gtk_dialog_run(GTK_DIALOG(chooser)) == GTK_RESPONSE_ACCEPT) {
        char *src_path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser));
        char *basename = g_path_get_basename(src_path);
        
        const char *config_dir = g_get_user_config_dir();
        char *dest_dir = g_build_filename(config_dir, "gtk2-media-player", "scripts", NULL);
        char *dest_path = g_build_filename(dest_dir, basename, NULL);
        
        /* Copy file */
        GFile *src = g_file_new_for_path(src_path);
        GFile *dest = g_file_new_for_path(dest_path);
        GError *error = NULL;
        
        if (g_file_copy(src, dest, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error)) {
            player_load_script(data->player, dest_path);
            refresh_scripts_list(data);
        } else {
            GtkWidget *msg = gtk_message_dialog_new(GTK_WINDOW(data->dialog),
                GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
                "Failed to install script: %s", error->message);
            gtk_dialog_run(GTK_DIALOG(msg));
            gtk_widget_destroy(msg);
            g_error_free(error);
        }
        
        g_object_unref(src);
        g_object_unref(dest);
        g_free(src_path);
        g_free(basename);
        g_free(dest_dir);
        g_free(dest_path);
    }
    
    gtk_widget_destroy(chooser);
}

void dialogs_show_script_manager(GtkWindow *parent, Player *player)
{
    ScriptManagerData *data = g_new0(ScriptManagerData, 1);
    data->player = player;
    
    GtkWidget *dialog = gtk_dialog_new_with_buttons("Script Manager",
        parent,
        GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
        GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
        NULL);
    data->dialog = dialog;
    gtk_window_set_default_size(GTK_WINDOW(dialog), 450, 400);
    
    GtkWidget *content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
    GtkWidget *vbox = gtk_vbox_new(FALSE, 10);
    gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
    gtk_box_pack_start(GTK_BOX(content_area), vbox, TRUE, TRUE, 0);
    
    GtkWidget *label = gtk_label_new(NULL);
    gtk_label_set_markup(GTK_LABEL(label), "<b>Manage MPV Scripts</b>\nEnabled scripts are loaded automatically on startup.");
    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
    
    /* Scrollable list */
    GtkWidget *sw = gtk_scrolled_window_new(NULL, NULL);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN);
    gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
    
    data->list_store = gtk_list_store_new(NUM_SCRIPT_COLS,
        G_TYPE_STRING,  /* Status text (optional display) */
        G_TYPE_STRING,  /* Name */
        G_TYPE_STRING,  /* Internal Path */
        G_TYPE_BOOLEAN  /* Enabled (for toggle) */
    );
    
    GtkWidget *tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(data->list_store));
    data->tree_view = GTK_TREE_VIEW(tree_view);
    gtk_container_add(GTK_CONTAINER(sw), tree_view);
    
    /* Enabled Toggle Column */
    GtkCellRenderer *toggle_renderer = gtk_cell_renderer_toggle_new();
    g_signal_connect(toggle_renderer, "toggled", G_CALLBACK(on_script_toggled), data);
    GtkTreeViewColumn *col_enabled = gtk_tree_view_column_new_with_attributes("On/Off", toggle_renderer, "active", COL_SCRIPT_ENABLED, NULL);
    gtk_tree_view_append_column(data->tree_view, col_enabled);
    
    /* Name Column */
    GtkCellRenderer *text_renderer = gtk_cell_renderer_text_new();
    GtkTreeViewColumn *col_name = gtk_tree_view_column_new_with_attributes("Script Name", text_renderer, "text", COL_SCRIPT_NAME, NULL);
    gtk_tree_view_append_column(data->tree_view, col_name);
    
    /* Sorting */
    gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(data->list_store), COL_SCRIPT_NAME, GTK_SORT_ASCENDING);
    
    /* Persistent Note */
    GtkWidget *note_label = gtk_label_new(NULL);
    gtk_label_set_markup(GTK_LABEL(note_label), "<small><i>Note: Running scripts cannot be fully unloaded without a restart.</i></small>");
    gtk_label_set_line_wrap(GTK_LABEL(note_label), TRUE);
    gtk_box_pack_start(GTK_BOX(vbox), note_label, FALSE, FALSE, 0);

    /* Buttons */
    GtkWidget *hbox = gtk_hbox_new(FALSE, 5);
    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
    
    GtkWidget *btn_install = gtk_button_new_with_label("Install Script");
    GtkWidget *icon_add = gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON);
    gtk_button_set_image(GTK_BUTTON(btn_install), icon_add);
    g_signal_connect(btn_install, "clicked", G_CALLBACK(on_install_script_clicked), data);
    gtk_box_pack_start(GTK_BOX(hbox), btn_install, TRUE, TRUE, 0);
    
    GtkWidget *btn_folder = gtk_button_new();
    GtkWidget *icon_dir = gtk_image_new_from_stock(GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_BUTTON);
    gtk_container_add(GTK_CONTAINER(btn_folder), icon_dir);
    gtk_widget_set_tooltip_text(btn_folder, "Open Scripts Folder");
    
    const char *cfg_dir = g_get_user_config_dir();
    char *s_dir = g_build_filename(cfg_dir, "gtk2-media-player", "scripts", NULL);
    char *cmd = g_strdup_printf("xdg-open '%s'", s_dir);
    g_signal_connect_swapped(btn_folder, "clicked", G_CALLBACK(system), cmd);
    gtk_box_pack_start(GTK_BOX(hbox), btn_folder, FALSE, FALSE, 0);
    
    refresh_scripts_list(data);
    
    gtk_widget_show_all(dialog);
    gtk_dialog_run(GTK_DIALOG(dialog));
    
    gtk_widget_destroy(dialog);
    g_object_unref(data->list_store);
    g_free(cmd);
    g_free(s_dir);
    g_free(data);
}


/* Preferences */

static char* get_config_path(void)
{
    const char *config_dir = g_get_user_config_dir();
    return g_build_filename(config_dir, "gtk2-media-player", "config", NULL);
}

Preferences* preferences_new(void)
{
    Preferences *prefs = g_new0(Preferences, 1);
    prefs->default_volume = 100.0;
    prefs->remember_position = FALSE;
    prefs->show_playlist = FALSE;
    prefs->auto_resize = FALSE;
    prefs->hide_cursor_windowed = FALSE;
    prefs->remember_last_dir = TRUE; /* Default to TRUE */
    prefs->use_mpris = TRUE; /* Default to TRUE */
    prefs->open_in_new_window = TRUE; /* Default to TRUE */
    prefs->seekbar_direct_jump = TRUE; /* Default to TRUE as requested earlier */
    prefs->hide_focus_rect = FALSE;
    prefs->enable_osd = TRUE;
    prefs->enable_chapters = TRUE;
    prefs->enable_volume_boost = FALSE;
    prefs->last_dir = NULL;
    prefs->screenshot_directory = g_strdup(g_get_home_dir());
    prefs->screenshot_format = g_strdup("png");
    
    const char *config_dir = g_get_user_config_dir();
    prefs->mpv_config_path = g_build_filename(config_dir, "gtk2-media-player", "mpv.conf", NULL);
    return prefs;
}

void preferences_free(Preferences *prefs)
{
    if (!prefs) return;
    g_free(prefs->screenshot_directory);
    g_free(prefs->screenshot_format);
    g_free(prefs->mpv_config_path);
    g_free(prefs->last_dir);
    g_free(prefs);
}

static void load_bool_pref(GKeyFile *keyfile, const char *key, gboolean *target) {
    GError *error = NULL;
    gboolean val = g_key_file_get_boolean(keyfile, "General", key, &error);
    if (!error) {
        *target = val;
    } else {
        g_clear_error(&error);
    }
}

void preferences_load(Preferences *prefs)
{
    if (!prefs) return;
    
    char *config_path = get_config_path();
    GKeyFile *keyfile = g_key_file_new();
    
    if (g_key_file_load_from_file(keyfile, config_path, G_KEY_FILE_NONE, NULL)) {
        GError *error = NULL;
        
        double volume = g_key_file_get_double(keyfile, "General", "volume", &error);
        if (!error) prefs->default_volume = volume;
        else { g_clear_error(&error); }
        
        load_bool_pref(keyfile, "remember_position", &prefs->remember_position);
        load_bool_pref(keyfile, "show_playlist_v3", &prefs->show_playlist);
        load_bool_pref(keyfile, "auto_resize", &prefs->auto_resize);
        load_bool_pref(keyfile, "hide_cursor_windowed", &prefs->hide_cursor_windowed);
        load_bool_pref(keyfile, "remember_last_dir", &prefs->remember_last_dir);
        load_bool_pref(keyfile, "use_mpris", &prefs->use_mpris);
        load_bool_pref(keyfile, "open_in_new_window", &prefs->open_in_new_window);
        load_bool_pref(keyfile, "seekbar_direct_jump", &prefs->seekbar_direct_jump);
        load_bool_pref(keyfile, "hide_focus_rect", &prefs->hide_focus_rect);
        load_bool_pref(keyfile, "enable_osd", &prefs->enable_osd);
        load_bool_pref(keyfile, "enable_chapters", &prefs->enable_chapters);
        load_bool_pref(keyfile, "enable_volume_boost", &prefs->enable_volume_boost);

        char *screenshot_dir = g_key_file_get_string(keyfile, "General", "screenshot_directory", &error);
        if (!error && screenshot_dir) {
            g_free(prefs->screenshot_directory);
            prefs->screenshot_directory = screenshot_dir;
        } else { 
            g_clear_error(&error);
            g_free(screenshot_dir);
        }

        char *last_dir = g_key_file_get_string(keyfile, "General", "last_dir", &error);
        if (!error && last_dir) {
            g_free(prefs->last_dir);
            prefs->last_dir = last_dir;
        } else {
            g_clear_error(&error);
            g_free(last_dir);
        }

        char *ss_format = g_key_file_get_string(keyfile, "General", "screenshot_format", &error);
        if (!error && ss_format) {
            g_free(prefs->screenshot_format);
            prefs->screenshot_format = ss_format;
        } else {
            g_clear_error(&error);
            g_free(ss_format);
        }

        char *mpv_cfg = g_key_file_get_string(keyfile, "General", "mpv_config_path", &error);
        if (!error && mpv_cfg) {
            g_free(prefs->mpv_config_path);
            prefs->mpv_config_path = mpv_cfg;
        } else {
            g_clear_error(&error);
            g_free(mpv_cfg);
        }
    }
    
    g_key_file_free(keyfile);
    g_free(config_path);
}

void preferences_save(Preferences *prefs)
{
    if (!prefs) return;
    
    char *config_path = get_config_path();
    char *config_dir = g_path_get_dirname(config_path);
    
    /* Create config directory if needed */
    g_mkdir_with_parents(config_dir, 0755);
    
    GKeyFile *keyfile = g_key_file_new();
    
    g_key_file_set_double(keyfile, "General", "volume", prefs->default_volume);
    
    struct { const char *key; gboolean val; } bool_prefs[] = {
        {"remember_position", prefs->remember_position},
        {"show_playlist_v3", prefs->show_playlist},
        {"auto_resize", prefs->auto_resize},
        {"hide_cursor_windowed", prefs->hide_cursor_windowed},
        {"remember_last_dir", prefs->remember_last_dir},
        {"use_mpris", prefs->use_mpris},
        {"open_in_new_window", prefs->open_in_new_window},
        {"seekbar_direct_jump", prefs->seekbar_direct_jump},
        {"hide_focus_rect", prefs->hide_focus_rect},
        {"enable_osd", prefs->enable_osd},
        {"enable_chapters", prefs->enable_chapters},
        {"enable_volume_boost", prefs->enable_volume_boost},
        {NULL, FALSE}
    };
    
    for (int i = 0; bool_prefs[i].key != NULL; i++) {
        g_key_file_set_boolean(keyfile, "General", bool_prefs[i].key, bool_prefs[i].val);
    }
    
    if (prefs->last_dir) {
        g_key_file_set_string(keyfile, "General", "last_dir", prefs->last_dir);
    }
    if (prefs->screenshot_directory) {
        g_key_file_set_string(keyfile, "General", "screenshot_directory", 
                              prefs->screenshot_directory);
    }
    if (prefs->screenshot_format) {
        g_key_file_set_string(keyfile, "General", "screenshot_format", prefs->screenshot_format);
    }
    if (prefs->mpv_config_path) {
        g_key_file_set_string(keyfile, "General", "mpv_config_path", prefs->mpv_config_path);
    }
    
    gsize length;
    char *data = g_key_file_to_data(keyfile, &length, NULL);
    if (data) {
        g_file_set_contents(config_path, data, length, NULL);
        g_free(data);
    }
    
    g_key_file_free(keyfile);
    g_free(config_dir);
    g_free(config_path);
}

static void on_cfg_browse_clicked(GtkButton *btn, gpointer data)
{
    GtkWindow *parent = GTK_WINDOW(data);
    GtkWidget *entry = g_object_get_data(G_OBJECT(btn), "entry");
    GtkWidget *file_dialog = gtk_file_chooser_dialog_new("Select mpv.conf", parent,
        GTK_FILE_CHOOSER_ACTION_OPEN,
        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
        GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
    
    if (gtk_dialog_run(GTK_DIALOG(file_dialog)) == GTK_RESPONSE_ACCEPT) {
        char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_dialog));
        gtk_entry_set_text(GTK_ENTRY(entry), filename);
        g_free(filename);
    }
    gtk_widget_destroy(file_dialog);
}

static void on_cfg_reset_clicked(GtkButton *btn, gpointer entry)
{
    (void)btn;
    const char *config_dir = g_get_user_config_dir();
    char *path = g_build_filename(config_dir, "gtk2-media-player", "mpv.conf", NULL);
    gtk_entry_set_text(GTK_ENTRY(entry), path);
    g_free(path);
}

static void on_speed_preset_clicked(GtkButton *button, gpointer data)
{
    (void)data;
    int speed_int = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button), "speed"));
    GtkWidget *spin = g_object_get_data(G_OBJECT(button), "spin");
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), speed_int / 100.0);
}

static GtkWidget* create_pref_check(GtkWidget *box, const char *label, gboolean is_active) {
    GtkWidget *check = gtk_check_button_new_with_label(label);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), is_active);
    gtk_box_pack_start(GTK_BOX(box), check, FALSE, FALSE, 0);
    return check;
}

gboolean dialogs_show_preferences(GtkWindow *parent, Preferences *prefs, PluginManager *pm)
{
    if (!prefs) return FALSE;
    
    GtkWidget *dialog = gtk_dialog_new_with_buttons(
        "Preferences",
        parent,
        GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
        GTK_STOCK_OK, GTK_RESPONSE_OK,
        NULL);
        
    gtk_window_set_default_size(GTK_WINDOW(dialog), 600, 500);
    
    GtkWidget *content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
    gtk_container_set_border_width(GTK_CONTAINER(content_area), 5);
    
    GtkWidget *notebook = gtk_notebook_new();
    gtk_box_pack_start(GTK_BOX(content_area), notebook, TRUE, TRUE, 0);
    
    /* 1. Interface Tab */
    GtkWidget *interface_vbox = gtk_vbox_new(FALSE, 10);
    gtk_container_set_border_width(GTK_CONTAINER(interface_vbox), 10);
    
    GtkWidget *playlist_check = create_pref_check(interface_vbox, "Show playlist by default", prefs->show_playlist);
    GtkWidget *resize_check = create_pref_check(interface_vbox, "Automatically resize window to fit video", prefs->auto_resize);
    GtkWidget *cursor_check = create_pref_check(interface_vbox, "Automatically hide mouse cursor in windowed mode", prefs->hide_cursor_windowed);
    GtkWidget *open_new_check = create_pref_check(interface_vbox, "Always open in a new window (Single-Instance off)", prefs->open_in_new_window);
    GtkWidget *jump_check = create_pref_check(interface_vbox, "Seek bar: Jump to clicked position immediately", prefs->seekbar_direct_jump);
    GtkWidget *focus_check = create_pref_check(interface_vbox, "Hide focus rectangles (dotted lines) around UI elements", prefs->hide_focus_rect);
    GtkWidget *osd_check = create_pref_check(interface_vbox, "Enable On-Screen Display (OSD)", prefs->enable_osd);
    GtkWidget *chapters_check = create_pref_check(interface_vbox, "Enable Chapters (markers, snapping, and menu)", prefs->enable_chapters);
    
    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), interface_vbox, gtk_label_new("Interface"));
    
    /* 2. Config File Tab */
    GtkWidget *config_vbox = gtk_vbox_new(FALSE, 10);
    gtk_container_set_border_width(GTK_CONTAINER(config_vbox), 10);
    
    GtkWidget *config_info_label = gtk_label_new(NULL);
    gtk_label_set_markup(GTK_LABEL(config_info_label), "<b>mpv Configuration File</b>\n"
                         "Specify an external mpv.conf file to load custom settings, shaders, and advanced options.\n"
                         "<i>Note: Standard MPV syntax is supported.</i>");
    gtk_label_set_line_wrap(GTK_LABEL(config_info_label), TRUE);
    gtk_box_pack_start(GTK_BOX(config_vbox), config_info_label, FALSE, FALSE, 5);
    
    GtkWidget *cfg_hbox = gtk_hbox_new(FALSE, 10);
    GtkWidget *cfg_entry = gtk_entry_new();
    gtk_entry_set_text(GTK_ENTRY(cfg_entry), prefs->mpv_config_path ? prefs->mpv_config_path : "");
    gtk_box_pack_start(GTK_BOX(cfg_hbox), cfg_entry, TRUE, TRUE, 0);
    
    GtkWidget *cfg_browse_btn = gtk_button_new_with_label("Browse...");
    g_object_set_data(G_OBJECT(cfg_browse_btn), "entry", cfg_entry);
    g_signal_connect(cfg_browse_btn, "clicked", G_CALLBACK(on_cfg_browse_clicked), dialog);
    gtk_box_pack_start(GTK_BOX(cfg_hbox), cfg_browse_btn, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(config_vbox), cfg_hbox, FALSE, FALSE, 5);
    
    GtkWidget *cfg_reset_btn = gtk_button_new_with_label("Reset to Default");
    g_signal_connect(cfg_reset_btn, "clicked", G_CALLBACK(on_cfg_reset_clicked), cfg_entry);
    gtk_box_pack_start(GTK_BOX(config_vbox), cfg_reset_btn, FALSE, FALSE, 0);
    
    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), config_vbox, gtk_label_new("Config File"));
    
    /* 3. Miscellaneous Tab */
    GtkWidget *misc_vbox = gtk_vbox_new(FALSE, 10);
    gtk_container_set_border_width(GTK_CONTAINER(misc_vbox), 10);
    
    GtkWidget *vol_hbox = gtk_hbox_new(FALSE, 10);
    gtk_box_pack_start(GTK_BOX(vol_hbox), gtk_label_new("Default Volume:"), FALSE, FALSE, 0);
    GtkAdjustment *adj = GTK_ADJUSTMENT(gtk_adjustment_new(prefs->default_volume, 0, 100, 1, 10, 0));
    GtkWidget *vol_spin = gtk_spin_button_new(adj, 1, 0);
    gtk_box_pack_start(GTK_BOX(vol_hbox), vol_spin, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(misc_vbox), vol_hbox, FALSE, FALSE, 0);
    
    GtkWidget *vol_boost_check = create_pref_check(misc_vbox, "Enable volume boost (up to 150%)", prefs->enable_volume_boost);
    GtkWidget *position_check = create_pref_check(misc_vbox, "Remember playback position", prefs->remember_position);
    GtkWidget *dir_check = create_pref_check(misc_vbox, "Remember last folder in file chooser", prefs->remember_last_dir);
    GtkWidget *mpris_check = create_pref_check(misc_vbox, "Enable MPRIS support (D-Bus)", prefs->use_mpris);
    
    /* Screenshot directory */
    GtkWidget *ss_hbox = gtk_hbox_new(FALSE, 10);
    gtk_box_pack_start(GTK_BOX(ss_hbox), gtk_label_new("Screenshot Directory:"), FALSE, FALSE, 0);
    GtkWidget *ss_entry = gtk_entry_new();
    gtk_entry_set_text(GTK_ENTRY(ss_entry), prefs->screenshot_directory ? prefs->screenshot_directory : "");
    gtk_box_pack_start(GTK_BOX(ss_hbox), ss_entry, TRUE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(misc_vbox), ss_hbox, FALSE, FALSE, 0);

    GtkWidget *format_hbox = gtk_hbox_new(FALSE, 10);
    gtk_box_pack_start(GTK_BOX(format_hbox), gtk_label_new("Screenshot Format:"), FALSE, FALSE, 0);
    GtkWidget *format_combo = gtk_combo_box_text_new();
    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(format_combo), "webp");
    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(format_combo), "png");
    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(format_combo), "jpg");
    
    if (g_strcmp0(prefs->screenshot_format, "webp") == 0) gtk_combo_box_set_active(GTK_COMBO_BOX(format_combo), 0);
    else if (g_strcmp0(prefs->screenshot_format, "png") == 0) gtk_combo_box_set_active(GTK_COMBO_BOX(format_combo), 1);
    else if (g_strcmp0(prefs->screenshot_format, "jpg") == 0) gtk_combo_box_set_active(GTK_COMBO_BOX(format_combo), 2);
    else gtk_combo_box_set_active(GTK_COMBO_BOX(format_combo), 0);
    
    gtk_box_pack_start(GTK_BOX(format_hbox), format_combo, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(misc_vbox), format_hbox, FALSE, FALSE, 0);
    
    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), misc_vbox, gtk_label_new("Miscellaneous"));
    
    /* 4. Plugins Tab */
    GtkWidget *plugins_vbox = plugin_manager_create_config_widget(pm);
    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), plugins_vbox, gtk_label_new("Plugins"));
    
    gtk_widget_show_all(dialog);
    
    gboolean result = FALSE;
    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) {
        prefs->default_volume = gtk_spin_button_get_value(GTK_SPIN_BUTTON(vol_spin));
        prefs->remember_position = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(position_check));
        prefs->show_playlist = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(playlist_check));
        prefs->auto_resize = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(resize_check));
        prefs->hide_cursor_windowed = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cursor_check));
        prefs->remember_last_dir = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dir_check));
        prefs->use_mpris = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mpris_check));
        prefs->open_in_new_window = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(open_new_check));
        prefs->seekbar_direct_jump = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(jump_check));
        prefs->hide_focus_rect = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(focus_check));
        prefs->enable_osd = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(osd_check));
        prefs->enable_chapters = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(chapters_check));
        prefs->enable_volume_boost = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(vol_boost_check));
        
        g_free(prefs->screenshot_directory);
        prefs->screenshot_directory = g_strdup(gtk_entry_get_text(GTK_ENTRY(ss_entry)));

        g_free(prefs->screenshot_format);
        prefs->screenshot_format = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(format_combo));

        g_free(prefs->mpv_config_path);
        prefs->mpv_config_path = g_strdup(gtk_entry_get_text(GTK_ENTRY(cfg_entry)));
        
        preferences_save(prefs);
        result = TRUE;
    }
    
    gtk_widget_destroy(dialog);
    return result;
}

double dialogs_goto_time(GtkWindow *parent, double current_time, double duration)
{
    GtkWidget *dialog = gtk_dialog_new_with_buttons(
        "Go to Time",
        parent,
        GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
        GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
        NULL);
    
    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
    
    GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
    gtk_container_set_border_width(GTK_CONTAINER(content), 10);
    
    GtkWidget *hbox = gtk_hbox_new(FALSE, 10);
    
    GtkWidget *label = gtk_label_new("Time (seconds):");
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
    
    GtkWidget *spin = gtk_spin_button_new_with_range(0, duration, 1);
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), current_time);
    gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), 1);
    gtk_box_pack_start(GTK_BOX(hbox), spin, TRUE, TRUE, 0);
    
    gtk_box_pack_start(GTK_BOX(content), hbox, TRUE, TRUE, 0);
    gtk_widget_show_all(content);
    
    double result = -1.0;
    
    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
        result = gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin));
    }
    
    gtk_widget_destroy(dialog);
    return result;
}

double dialogs_select_speed(GtkWindow *parent, double current_speed)
{
    GtkWidget *dialog = gtk_dialog_new_with_buttons(
        "Playback Speed",
        parent,
        GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
        GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
        NULL);
    
    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
    
    GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
    gtk_container_set_border_width(GTK_CONTAINER(content), 10);
    
    GtkWidget *vbox = gtk_vbox_new(FALSE, 5);
    
    /* Preset buttons */
    const double presets[] = {0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2.0, 3.0};
    const int num_presets = sizeof(presets) / sizeof(presets[0]);
    
    GtkWidget *hbox = gtk_hbox_new(TRUE, 5);
    GtkWidget *speed_spin = gtk_spin_button_new_with_range(0.1, 10.0, 0.1);
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(speed_spin), current_speed);
    gtk_spin_button_set_digits(GTK_SPIN_BUTTON(speed_spin), 2);
    
    for (int i = 0; i < num_presets; i++) {
        char label[16];
        snprintf(label, sizeof(label), "%.2fx", presets[i]);
        GtkWidget *btn = gtk_button_new_with_label(label);
        g_object_set_data(G_OBJECT(btn), "speed", GINT_TO_POINTER((int)(presets[i] * 100)));
        g_object_set_data(G_OBJECT(btn), "spin", speed_spin);
        g_signal_connect(btn, "clicked", G_CALLBACK(on_speed_preset_clicked), NULL);
        gtk_box_pack_start(GTK_BOX(hbox), btn, TRUE, TRUE, 0);
    }
    
    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
    
    /* Custom speed entry */
    GtkWidget *custom_hbox = gtk_hbox_new(FALSE, 10);
    GtkWidget *custom_label = gtk_label_new("Custom Speed:");
    gtk_box_pack_start(GTK_BOX(custom_hbox), custom_label, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(custom_hbox), speed_spin, TRUE, TRUE, 0);
    
    gtk_box_pack_start(GTK_BOX(vbox), custom_hbox, FALSE, FALSE, 0);
    
    gtk_box_pack_start(GTK_BOX(content), vbox, TRUE, TRUE, 0);
    gtk_widget_show_all(content);
    
    double result = -1.0;
    
    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
        result = gtk_spin_button_get_value(GTK_SPIN_BUTTON(speed_spin));
    }
    
    gtk_widget_destroy(dialog);
    return result;
}
