#include "ubinstall-gtk.h"

int yon_packages_tab_save(main_window *widgets){
    GtkTreeIter parentiter, subiter,packiter;
    if (yon_char_is_empty(config(packages_parameter))){
        yon_config_register(packages_parameter,packages_parameter_command,NULL);
        yon_config_set_status(packages_parameter,0);
    }
    for_iter(widgets->PackagesList,&parentiter){
        for (int valid2 = gtk_tree_model_iter_children(GTK_TREE_MODEL(widgets->PackagesList),&subiter,&parentiter);valid2;valid2 = gtk_tree_model_iter_next(GTK_TREE_MODEL(widgets->PackagesList),&subiter)){
            int selectable, status;
            int sensitive=0;
            char *package;
            gtk_tree_model_get(GTK_TREE_MODEL(widgets->PackagesList),&subiter,0,&status,1,&package,3,&selectable,4,&sensitive,-1);
            if (selectable&&status&&sensitive){
                yon_config_append_elements(packages_parameter,package,",");
            }else if (selectable&&!status){
                yon_config_remove_elements_all(packages_parameter,package,",");
            } else {
                for (int valid3 = gtk_tree_model_iter_children(GTK_TREE_MODEL(widgets->PackagesList),&packiter,&subiter);valid3;valid3 = gtk_tree_model_iter_next(GTK_TREE_MODEL(widgets->PackagesList),&packiter)){
                    gtk_tree_model_get(GTK_TREE_MODEL(widgets->PackagesList),&packiter,0,&status,1,&package,3,&selectable,4,&sensitive,-1);
                    if (status){
                        if (sensitive){
                            yon_config_append_elements(packages_parameter,package,",");
                        }
                    } else {
                        yon_config_remove_elements_all(packages_parameter,package,",");
                    }
                }
            }
        }
    }
    if (!main_config.configure_mode){
        yon_debug_output("%s\n",yon_config_save_args_simple(main_config.config_load_path,packages_parameter,NULL));
    }
    return 1;
}

GtkTreeIter *yon_category_check(GtkTreeStore *target,char *category);
GtkTreeIter *yon_category_check(GtkTreeStore *target,char *category){
    GtkTreeIter iter;
    GtkTreeIter *ret_iter = NULL;
    for_iter(target,&iter){
        char *cur_category;
        gtk_tree_model_get(GTK_TREE_MODEL(target),&iter,1,&cur_category,-1);
        if (!strcmp(cur_category,category)){
            ret_iter = gtk_tree_iter_copy(&iter);
        }
    }
    return ret_iter;
}

GtkTreeIter *yon_subcategory_check(GtkTreeStore *target, GtkTreeIter *parent_iter, char *category);
GtkTreeIter *yon_subcategory_check(GtkTreeStore *target, GtkTreeIter *parent_iter, char *category){
    GtkTreeIter iter;
    GtkTreeIter *ret_iter = NULL;
    int valid = gtk_tree_model_iter_children(GTK_TREE_MODEL(target),&iter,parent_iter);
    for(; valid; valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(target),&iter)){
        char *cur_category;
        gtk_tree_model_get(GTK_TREE_MODEL(target),&iter,1,&cur_category,-1);
        if ((yon_char_is_empty(cur_category)&&yon_char_is_empty(category))||!strcmp(cur_category,category)){
            ret_iter = gtk_tree_iter_copy(&iter);
        }
    }
    return ret_iter;
}

void on_software_info(GtkWidget*, main_window *widgets){
    char *packages;
    GtkTreeIter iter;
    GtkTreeModel *model;
    gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(widgets->PackagesTree)),&model,&iter);
    gtk_tree_model_get(GTK_TREE_MODEL(widgets->PackagesList),&iter,5,&packages,-1);
    int size=0;
    config_str parsed = yon_char_parse(packages,&size,",");
    for (int i=0;i<size;i++){
        yon_package_info_window_create(parsed[i]);
    }
    yon_char_parsed_free(parsed,size);
}

void yon_packages_remove_empty_groups(main_window *widgets){
    GtkTreeModel *model = GTK_TREE_MODEL(widgets->PackagesList);
    GtkTreeIter iter;
    for_iter(model,&iter){
        if (gtk_tree_model_iter_has_child(model,&iter)){
            GtkTreeIter subiter;
            for (int valid2 = gtk_tree_model_iter_children(model,&subiter,&iter);valid2;valid2 = gtk_tree_model_iter_next(model,&subiter)){
                char *packages;
                gtk_tree_model_get(model,&subiter,5,&packages,-1);
                if (yon_char_is_empty(packages)&&!gtk_tree_model_iter_has_child(model,&subiter)){
                    gtk_tree_store_remove(widgets->PackagesList,&subiter);
                    if (!gtk_tree_model_iter_children(model,&subiter,&iter)){
                        valid2=0;
                        break;
                    }
                }
            }
        } else {
            gtk_tree_store_remove(widgets->PackagesList,&iter);
            if (!gtk_tree_model_get_iter_first(model,&iter)){
                valid=0;
                break;
            }
        }
    }
}

void yon_packages_tab_init(main_window *widgets){
    on_status_update(NULL,widgets);
    if (!main_config.configure_mode){
        yon_config_update_by_args(main_config.config_load_path, packages_parameter,NULL);
    }
    if (!main_config.configure_mode){
        yon_config_remove_by_args(packages_parameter,NULL);
        char *command = yon_config_parameter_prepare_command(packages_parameter_command,main_config.config_load_path,NULL,NULL);
        yon_config_load_config(YON_CONFIG_CUSTOM,command,NULL);
        free(command);
    }
    while(gtk_events_pending()) gtk_main_iteration();
    gtk_tree_store_clear(widgets->PackagesList);
    char *modules = config(modules_parameter);
    if (modules&&!strcmp(modules,"auto")){
        int final_size;
        config_str final = NULL;
        for (int i=0;i<main_config.modules_size;i++){
            int parsed_size=0;
            config_str parsed = yon_char_parse(main_config.modules[i],&parsed_size,";");
                yon_char_parsed_add_or_create_if_exists(final,&final_size,parsed[1]);
            yon_char_parsed_free(parsed,parsed_size);
        }
        modules = yon_char_parsed_to_string(final,final_size,",");
    }  else if (!yon_char_is_empty(modules)){
        int final_size = 0;
        config_str final = NULL;
        for (int i=0;i<main_config.modules_size;i++){
            int parsed_size=0;
            config_str parsed = yon_char_parse(main_config.modules[i],&parsed_size,";");
            if (yon_char_check_element(modules,parsed[0],",")){
                yon_char_parsed_add_or_create_if_exists(final,&final_size,parsed[1]);
            }
            yon_char_parsed_free(parsed,parsed_size);
        }
        modules = yon_char_parsed_to_string(final,final_size,",");
    }
    while(gtk_events_pending()) gtk_main_iteration();
    int size;
    char *config_packages = config(packages_parameter);

    config_str packages = yon_resource_open_file(groups_list_path,&size);
    for (int i=1;i<size;i++){
        int parsed_size;
        config_str parsed = yon_char_parse(packages[i],&parsed_size,";");
        GtkTreeIter *category_iter = yon_category_check(widgets->PackagesList,parsed[0]);
        char *name_render = yon_char_replace(parsed[2],","," ");
        int final_size = 0;
        config_str final = NULL;
        int modules_parsed_size = 0;
        config_str modules_parsed = yon_char_parse(parsed[2],&modules_parsed_size," ");
        int empty=0;
        for (int j=0;j<modules_parsed_size;j++){
            if (!yon_packages_check_exist(modules_parsed[j])){
                empty = 1;
                continue;
            }
            yon_char_parsed_add_or_create_if_exists(final,&final_size,modules_parsed[j]);
        }
        while(gtk_events_pending()) gtk_main_iteration();
        yon_char_parsed_free(modules_parsed,modules_parsed_size);
        char *modules_string = yon_char_parsed_to_string(final,final_size,"\t");
        if (empty && !yon_char_check_elements(modules,modules_string,",")) continue;
        if (category_iter){
            if (!yon_char_is_empty(parsed[1])){
                GtkTreeIter *subcategory_iter = yon_subcategory_check(widgets->PackagesList,category_iter,parsed[1]);
                if (subcategory_iter){
                    GtkTreeIter package_iter;
                    gtk_tree_store_append(widgets->PackagesList,&package_iter,subcategory_iter);
                    char *full_string = yon_char_unite("<b>",name_render,"</b>\n",_(parsed[3]),NULL);
                    gtk_tree_store_set(widgets->PackagesList,&package_iter,0,!!yon_char_check_elements(config_packages,modules_string,",")||yon_char_check_elements(modules,modules_string,","),1,modules_string,2,full_string,3,1,4,!yon_char_check_elements(modules,modules_string,","),5,modules_string,-1);
                    free(full_string);
                    gtk_tree_iter_free(subcategory_iter);
                } else {
                    GtkTreeIter subcatiter;
                    GtkTreeIter package_iter;
                    gtk_tree_store_append(widgets->PackagesList,&subcatiter,category_iter);
                    gtk_tree_store_set(widgets->PackagesList,&subcatiter,1,parsed[1],2,_(parsed[1]),3,0,-1);
                    gtk_tree_store_append(widgets->PackagesList,&package_iter,&subcatiter);
                    char *full_string = yon_char_unite("<b>",name_render,"</b>\n",_(parsed[3]),NULL);
                    gtk_tree_store_set(widgets->PackagesList,&package_iter,0,!!yon_char_check_elements(config_packages,modules_string,",")||yon_char_check_elements(modules,modules_string,","),1,modules_string,2,full_string,3,1,4,!yon_char_check_elements(modules,modules_string,","),5,modules_string,-1);
                    free(full_string);
                }
            } else {
                    GtkTreeIter package_iter;
                    gtk_tree_store_append(widgets->PackagesList,&package_iter,category_iter);
                    char *full_string = yon_char_unite("<b>",name_render,"</b>\n",_(parsed[3]),NULL);
                    gtk_tree_store_set(widgets->PackagesList,&package_iter,0,!!yon_char_check_elements(config_packages,modules_string,",")||yon_char_check_elements(modules,modules_string,","),1,modules_string,2,full_string,3,1,4,!yon_char_check_elements(modules,modules_string,","),5,modules_string,-1);
                    free(full_string);
            }
            gtk_tree_iter_free(category_iter);
        } else {
            if (!yon_char_is_empty(parsed[1])){
                GtkTreeIter subcategory_iter;
                GtkTreeIter catiter;
                GtkTreeIter package_iter;
                gtk_tree_store_append(widgets->PackagesList,&catiter,NULL);
                gtk_tree_store_set(widgets->PackagesList,&catiter,1,parsed[0],2,_(parsed[0]),3,0,-1);
                gtk_tree_store_append(widgets->PackagesList,&subcategory_iter,&catiter);
                gtk_tree_store_set(widgets->PackagesList,&subcategory_iter,1,parsed[1],2,_(parsed[1]),3,0,-1);
                gtk_tree_store_append(widgets->PackagesList,&package_iter,&subcategory_iter);
                char *full_string = yon_char_unite("<b>",name_render,"</b>\n",_(parsed[3]),NULL);
                gtk_tree_store_set(widgets->PackagesList,&package_iter,0,!!yon_char_check_elements(config_packages,modules_string,",")||yon_char_check_elements(modules,modules_string,","),1,modules_string,2,full_string,3,1,4,!yon_char_check_elements(modules,modules_string,","),5,modules_string,-1);
                free(full_string);
            } else {
                GtkTreeIter package_iter;
                GtkTreeIter catiter;
                gtk_tree_store_append(widgets->PackagesList,&catiter,NULL);
                gtk_tree_store_set(widgets->PackagesList,&catiter,1,parsed[0],2,_(parsed[0]),3,0,-1);
                gtk_tree_store_append(widgets->PackagesList,&package_iter,&catiter);
                char *full_string = yon_char_unite("<b>",name_render,"</b>\n",_(parsed[3]),NULL);
                gtk_tree_store_set(widgets->PackagesList,&package_iter,0,!!yon_char_check_elements(config_packages,modules_string,",")||yon_char_check_elements(modules,modules_string,","),1,modules_string,2,full_string,3,1,4,!yon_char_check_elements(modules,modules_string,","),5,modules_string,-1);
                free(full_string);
            }
        }
        while(gtk_events_pending()) gtk_main_iteration();
    }
    yon_packages_remove_empty_groups(widgets);
    if (!yon_char_is_empty(modules)) free(modules);
    gtk_tree_view_expand_all(GTK_TREE_VIEW(widgets->PackagesTree));
}

void yon_on_packages_selected(GtkWidget *, main_window *widgets){
    GtkTreeIter iter;
    GtkTreeModel *model;
    if (!gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(widgets->PackagesTree)),&model,&iter)) return;
    GtkTreeIter cur_parent, cur_iter;
    int status;
    gtk_tree_model_get(model,&iter,3,&status,-1);
    if (status)
    return;
    if (!gtk_tree_model_iter_children(model,&cur_parent,&iter)) return;
    gtk_tree_model_get(model,&cur_parent,3,&status,-1);
    if (status){
        GtkTreePath *path = gtk_tree_model_get_path(model,&cur_parent);
        gtk_tree_view_expand_to_path(GTK_TREE_VIEW(widgets->PackagesTree),path);
        gtk_tree_path_free(path);
        gtk_tree_selection_select_iter(gtk_tree_view_get_selection(GTK_TREE_VIEW(widgets->PackagesTree)),&cur_parent);
        return;
    }
    gtk_tree_model_iter_children(model,&cur_iter,&cur_parent);
        GtkTreePath *path = gtk_tree_model_get_path(model,&cur_iter);
        gtk_tree_view_expand_to_path(GTK_TREE_VIEW(widgets->PackagesTree),path);
        gtk_tree_path_free(path);
    gtk_tree_selection_select_iter(gtk_tree_view_get_selection(GTK_TREE_VIEW(widgets->PackagesTree)),&cur_iter);
}

void yon_on_packages_chosen(GtkWidget *, char *path, main_window *widgets){
    GtkTreeIter iter;
    gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(widgets->PackagesList),&iter,path);
    int status;
    int sensitive;
    gtk_tree_model_get(GTK_TREE_MODEL(widgets->PackagesList),&iter,0,&status,4,&sensitive,-1);
    if (sensitive){
        gtk_tree_store_set(widgets->PackagesList,&iter,0,!status,-1);
    }
}

void yon_on_packages_activated(GtkWidget *, GtkTreePath* path, GtkTreeViewColumn* , main_window *widgets){
    GtkTreeIter iter;
    gtk_tree_model_get_iter(GTK_TREE_MODEL(widgets->PackagesList),&iter,path);
    int sensitive;
    int status;
    gtk_tree_model_get(GTK_TREE_MODEL(widgets->PackagesList),&iter,0,&status,4,&sensitive,-1);
    if (sensitive){
        gtk_tree_store_set(widgets->PackagesList,&iter,0,!status,-1);
    }
}