#include "libublsettingsui-gtk3.h"

typedef struct {
	GtkWidget *Window;
	GtkWidget *StatusBox;
	GtkWidget *UsersTree;
	GtkListStore *list;
	GtkWidget *CancelButton;
	GtkWidget *AcceptButton;
	GtkCellRenderer *StatusCell;
	GtkTreeViewColumn *GroupColumn;
    unsigned int selection_size;
    config_str selection;
} yon_user_window;

gboolean on_user_window_closed(GtkWidget *, yon_user_window *){
    gtk_main_quit();
    return 0;
}

void on_group_clicked(GtkCellRenderer *, char *path, yon_user_window *window){
	GtkTreeIter iter;
	gboolean status;
	gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(window->list),&iter,path);
	gtk_tree_model_get(GTK_TREE_MODEL(window->list),&iter,0,&status,-1);
	gtk_list_store_set(window->list,&iter,0,!status,-1);
    if (gtk_cell_renderer_toggle_get_radio(GTK_CELL_RENDERER_TOGGLE(window->StatusCell))){
    GtkTreeIter *prev = gtk_tree_iter_copy(&iter);
        for (int valid = gtk_tree_model_iter_previous(GTK_TREE_MODEL(window->list),prev); valid; valid = gtk_tree_model_iter_previous(GTK_TREE_MODEL(window->list),prev)){
            gtk_list_store_set(window->list,prev,0,0,-1);
        }
        gtk_tree_iter_free(prev);

        GtkTreeIter *next = gtk_tree_iter_copy(&iter);
        for (int valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(window->list),next); valid; valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(window->list),next)){
            gtk_list_store_set(window->list,next,0,0,-1);
        }
        gtk_tree_iter_free(next);
    }
}

void on_users_window_accept(GtkWidget *, yon_user_window *window){
    GtkTreeModel *model;
    GList *list = gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(window->UsersTree)),&model);
    GList *liter;
    for (liter=list;liter;liter=liter->next){
        GtkTreeIter iter;
        gtk_tree_model_get_iter(model,&iter,(GtkTreePath*)liter->data);
        int selected;
        char *target;
        int id;
        gtk_tree_model_get(model,&iter,0,&selected,1,&target,2,&id,-1);
        if (selected){
            char *id_string = yon_char_from_int(id);
            yon_char_parsed_add_or_create_if_exists(window->selection,&window->selection_size,target); //FIXME: IMPLEMENT USER AND GROUP SYSTEM AND SWITCH TARGET TO UID/GID 
            free(id_string);
        }
    }
    on_subwindow_close(window->Window);
}

yon_user_window *yon_user_window_new(enum YON_USER_WINDOW_MODE_TYPE mode){
	yon_user_window *window = malloc(sizeof(yon_user_window));
    memset(window,0,sizeof(yon_user_window));
	GtkBuilder *builder = gtk_builder_new_from_resource(ui_glade_path_userwindow);
	window->Window=yon_gtk_builder_get_widget(builder,"Window");
	window->StatusBox=yon_gtk_builder_get_widget(builder,"StatusBox");
	window->UsersTree=yon_gtk_builder_get_widget(builder,"UsersTree");
	window->StatusCell = GTK_CELL_RENDERER(gtk_builder_get_object(builder,"StatusCell"));
	window->GroupColumn = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder,"GroupColumn"));
	window->CancelButton=yon_gtk_builder_get_widget(builder,"CancelButton");
	window->AcceptButton=yon_gtk_builder_get_widget(builder,"AcceptButton");
	window->list = gtk_list_store_new(3,G_TYPE_BOOLEAN,G_TYPE_STRING,G_TYPE_INT);
	gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(window->list),2,GTK_SORT_ASCENDING);

    g_signal_connect(G_OBJECT(window->Window),"destroy",G_CALLBACK(on_user_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_users_window_accept),window);
	g_signal_connect(G_OBJECT(window->StatusCell),"toggled",G_CALLBACK(on_group_clicked),window);
	GtkTreeIter iter;
    int multiple = 0;
    switch (mode){
        case YON_USER_WINDOW_USERS_MULTIPLE:
            gtk_cell_renderer_toggle_set_radio(GTK_CELL_RENDERER_TOGGLE(window->StatusCell),0);
            multiple = 1;
        [[fallthrough]];
        case YON_USER_WINDOW_USERS:{
            yon_gtk_window_setup(GTK_WINDOW(window->Window),NULL,!multiple?_CHOOSE_USER_LABEL:_CHOOSE_USERS_LABEL,yon_dull_icon_path,"GroupWindow");
            gtk_tree_view_column_set_title(gtk_tree_view_get_column(GTK_TREE_VIEW(window->UsersTree),2),_USER_LABEL);
            int size;
            config_str system_param = yon_file_open("/etc/passwd",&size);
            for (int i=0;i<size;i++){
                int parsed_size;
                config_str parsed = yon_char_parse(system_param[i],&parsed_size,":"); 
                if (parsed_size>2&&!yon_char_is_empty(parsed[2])){
                    gtk_list_store_append(window->list,&iter);
                    gtk_list_store_set(window->list,&iter,0,0,1,parsed[0],2,atoi(parsed[2]),-1);
                }
            }
        } break;
        
        case YON_USER_WINDOW_GROUPS_MULTIPLE:
            gtk_cell_renderer_toggle_set_radio(GTK_CELL_RENDERER_TOGGLE(window->StatusCell),0);
            multiple = 1;
        [[fallthrough]];
        case YON_USER_WINDOW_GROUPS:{
            yon_gtk_window_setup(GTK_WINDOW(window->Window),NULL,!multiple?_CHOOSE_GROUP_LABEL:_CHOOSE_GROUPS_LABEL, yon_dull_icon_path,"GroupWindow");
            gtk_tree_view_column_set_title(gtk_tree_view_get_column(GTK_TREE_VIEW(window->UsersTree),2),_GROUP_LABEL);
            int size;
            config_str system_param = yon_file_open("/etc/group",&size);
            for (int i=0;i<size;i++){
                int parsed_size;
                config_str parsed = yon_char_parse(system_param[i],&parsed_size,":"); 
                if (parsed_size>2&&!yon_char_is_empty(parsed[2])){
                    gtk_list_store_append(window->list,&iter);
                    gtk_list_store_set(window->list,&iter,0,0,1,parsed[0],2,atoi(parsed[2]),-1);
                }
            }
        } break;
    }
	gtk_tree_view_set_model(GTK_TREE_VIEW(window->UsersTree),GTK_TREE_MODEL(window->list));


	g_signal_connect(G_OBJECT(window->CancelButton),"clicked",G_CALLBACK(on_subwindow_close),NULL);
return window;
}

config_str yon_users_window_select(enum YON_USER_WINDOW_MODE_TYPE mode, unsigned int *size){
    (*size) = 0;
    yon_user_window *window = yon_user_window_new(mode);
    gtk_widget_show(window->Window);
    gtk_main();
    (*size) = window->selection_size;
    config_str ret = window->selection;
    free(window);
    return ret;
}
