#include "libublsettingsui-gtk3.h"

struct return_struct {
    config_str chosen_apps;
    int size;
};

int yon_apps_already_init=0;

void yon_block_visibility_if_unallowed(GtkWidget *self, GParamSpec* pspec,yon_app_chooser_window *window){
    if (gtk_widget_get_visible(window->MainWindow)){
        if (!window->visible_allowed)
            gtk_widget_set_visible(window->MainWindow,0);
        else g_signal_handlers_block_by_func(G_OBJECT(window->MainWindow),yon_block_visibility_if_unallowed,window);
    }
}

config_str yon_app_chooser_window_run(yon_app_chooser_window *window, int *size){
    gtk_widget_show(window->MainWindow);
    gtk_main();
    if (!yon_apps_already_init){
        yon_apps_uninit();
    }
    config_str final = window->final->chosen_apps;
    (*size)=window->final->size;
    free(window);
    return final;
}

void on_app_selection_toggled(GtkWidget *, char *path, yon_app_chooser_window *window){
    GtkTreeIter iter;
    int status;
    gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(window->treestore),&iter,path);
    gtk_tree_model_get(GTK_TREE_MODEL(window->treestore),&iter,0,&status,-1);
    gtk_tree_store_set(window->treestore,&iter,0,!status,-1);
}

void on_app_chooser_window_closed(GtkWidget *, yon_app_chooser_window *window){
    gtk_main_quit();
}

void on_app_chooser_accept(GtkWidget *, yon_app_chooser_window *window){
    GtkTreeIter iter;
    GtkTreeModel *model = GTK_TREE_MODEL(window->treestore);
    if (window->multiple){
        for_iter(model,&iter){
            int status;
            char *name;
            gtk_tree_model_get(GTK_TREE_MODEL(window->treestore),&iter,0,&status,1,&name,-1);
            if (status){
                yon_char_parsed_add_or_create_if_exists(window->final->chosen_apps,&window->final->size,name);
            }
        }
    } else {
        if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(window->MainTree)),&model,&iter)){
            char *name;
            gtk_tree_model_get(GTK_TREE_MODEL(window->treestore),&iter,1,&name,-1);
            yon_char_parsed_add_or_create_if_exists(window->final->chosen_apps,&window->final->size,name);
        }
    }
    gtk_widget_destroy(window->MainWindow);
}

int yon_app_chooser_window_select(yon_app_chooser_window *window,config_str selection,int size){
    GtkTreeIter iter;
    for(int i=0;i<size;i++){
        for_iter(GTK_TREE_MODEL(window->treestore),&iter){
            char *target;
            gtk_tree_model_get(GTK_TREE_MODEL(window->treestore),&iter,6,&target,-1);
            if (!yon_char_is_empty(target)&&!yon_char_is_empty(selection[i])&&!strcmp(target,selection[i])){
                gtk_tree_store_set(window->treestore,&iter,0,1,-1);
            }
        }
    }
}

yon_app_chooser_window *yon_app_chooser_window_new(int multiple_choise,...){
    if (yon_apps_check_init()){
        yon_apps_already_init=1;
    } else {
        yon_apps_init();
    }
    yon_app_chooser_window *window = new(yon_app_chooser_window);
    GtkBuilder *builder = gtk_builder_new_from_resource(ui_glade_path_app_chooser);
    window->MainWindow = yon_gtk_builder_get_widget(builder,"MainWindow");
    window->StatusBox = yon_gtk_builder_get_widget(builder,"StatusBox");
    window->HeadLabel = yon_gtk_builder_get_widget(builder,"HeadLabel");
    window->WindowImage = yon_gtk_builder_get_widget(builder,"WindowImage");

    window->CancelButton = yon_gtk_builder_get_widget(builder,"CancelButton");
    window->AcceptButton = yon_gtk_builder_get_widget(builder,"AcceptButton");

    window->MainTree = yon_gtk_builder_get_widget(builder,"MainTree");
    window->SelectionCell = GTK_CELL_RENDERER(gtk_builder_get_object(builder,"SelectionCell"));
    window->treestore = GTK_TREE_STORE(gtk_builder_get_object(builder,"treestore1"));

    window->MainIconView = yon_gtk_builder_get_widget(builder,"MainIconView");
    window->liststore = GTK_LIST_STORE(gtk_builder_get_object(builder,"liststore1"));

    window->visible_allowed=0;
    window->final = new(struct return_struct);

    memset(window->final,0,sizeof(struct return_struct));

    g_signal_connect(G_OBJECT(window->MainWindow),"notify::visibile",G_CALLBACK(yon_block_visibility_if_unallowed),window);
    g_signal_connect(G_OBJECT(window->MainWindow),"destroy",G_CALLBACK(on_app_chooser_window_closed),window);
    g_signal_connect(G_OBJECT(window->CancelButton),"clicked",G_CALLBACK(on_subwindow_close),NULL);
    g_signal_connect(G_OBJECT(window->AcceptButton),"clicked",G_CALLBACK(on_app_chooser_accept),window);
    g_signal_connect(G_OBJECT(window->SelectionCell),"toggled",G_CALLBACK(on_app_selection_toggled),window);
    
    window->multiple = multiple_choise;
    
    if (!window->multiple){
        gtk_cell_renderer_set_visible(GTK_CELL_RENDERER(window->SelectionCell),0);
    }

    va_list list;
    va_start(list,multiple_choise);
    char *cur_section = NULL;
    int sections_size;
    config_str sections_list = NULL;
    int section_titles_size;
    config_str section_titles_list = NULL;
    while ((cur_section = va_arg(list,char*))){
        if (yon_char_is_empty(cur_section)) break;
        yon_char_parsed_add_or_create_if_exists(section_titles_list,&section_titles_size,cur_section);
        cur_section = va_arg(list,char*);
        yon_char_parsed_add_or_create_if_exists(sections_list,&sections_size,cur_section);
    }

    for (int i=0;i<sections_size;i+=1){
        GtkTreeIter parent, child;
        int apps_size;
        config_str apps_list = yon_apps_get_by_categories(&(sections_list[i]),1,&apps_size);
        gtk_tree_store_append(window->treestore,&parent,NULL);
        gtk_tree_store_set(window->treestore,&parent,1,section_titles_list[i],2,1,-1);
        for (int k=0;k<apps_size;k++){
            apps *cur_app = yon_apps_get(apps_list[k]);
            gtk_tree_store_append(window->treestore,&child,&parent);
            gtk_tree_store_set(window->treestore,&child,1,cur_app->Name,3,cur_app->Icon,-1);
        }
        yon_char_parsed_free(apps_list,apps_size);
    }

    return window;
}