#include "ubinstall-gtk.h"

#define toggled_icon_name "com.ublinux.libublsettingsui-gtk3.toggled-symbolic"
#define untoggled_icon_name "com.ublinux.libublsettingsui-gtk3.untoggled-symbolic"

void on_advanced_part_toggled(GtkWidget *self){
    if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(self))){
        g_signal_handlers_block_by_func(G_OBJECT(self),on_advanced_part_toggled,NULL);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self),1);
        g_signal_handlers_unblock_by_func(G_OBJECT(self),on_advanced_part_toggled,NULL);
    }
    advanced_part_widgets *select_part = g_object_get_data(G_OBJECT(self),"advanced_part_widgets");
    g_signal_handlers_block_by_func(G_OBJECT(select_part->SystemSectionToggle),on_advanced_part_toggled,NULL);
    g_signal_handlers_block_by_func(G_OBJECT(select_part->UserDataSectionToggle),on_advanced_part_toggled,NULL);
    main_window *widgets = g_object_get_data(G_OBJECT(select_part->MainBox),"widgets");
    GList *list = gtk_container_get_children(GTK_CONTAINER(widgets->AdvancedPartitionAddBox));
    int size = g_list_length(list);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self == select_part->SystemSectionToggle?select_part->UserDataSectionToggle:select_part->SystemSectionToggle),!(size>1));
    
    GList *iter;
    for (iter=list;iter;iter=iter->next){
        advanced_part_widgets *cur_part = g_object_get_data(G_OBJECT(iter->data),"advanced_part_widgets");
        if (cur_part!=select_part){
            g_signal_handlers_block_by_func(G_OBJECT(cur_part->SystemSectionToggle),on_advanced_part_toggled,NULL);
            g_signal_handlers_block_by_func(G_OBJECT(cur_part->UserDataSectionToggle),on_advanced_part_toggled,NULL);
            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self == select_part->SystemSectionToggle ? cur_part->SystemSectionToggle : cur_part->UserDataSectionToggle),0);
            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self == select_part->SystemSectionToggle ? cur_part->UserDataSectionToggle : cur_part->SystemSectionToggle),1);
            g_signal_handlers_unblock_by_func(G_OBJECT(cur_part->SystemSectionToggle),on_advanced_part_toggled,NULL);
            g_signal_handlers_unblock_by_func(G_OBJECT(cur_part->UserDataSectionToggle),on_advanced_part_toggled,NULL);

        }
    }
    g_signal_handlers_unblock_by_func(G_OBJECT(select_part->SystemSectionToggle),on_advanced_part_toggled,NULL);
    g_signal_handlers_unblock_by_func(G_OBJECT(select_part->UserDataSectionToggle),on_advanced_part_toggled,NULL);
}

void on_advanced_part_remove_part(GtkWidget *self, main_window *widgets){
    advanced_part_widgets *part = g_object_get_data(G_OBJECT(self),"advanced_part_widgets");
    advanced_part_data *data = g_object_get_data(G_OBJECT(self),"advanced_part_data");
    GtkTreeIter iter;
    GtkTreeModel *model = GTK_TREE_MODEL(widgets->PartitionsList);
    for_iter (model, &iter){
        char *target;
        gtk_tree_model_get(model,&iter,0,&target,-1);
            gtk_widget_destroy(part->MainBox);
        if (data->partition&&!strcmp(data->partition,target)){
            gtk_list_store_set(widgets->PartitionsList,&iter,7,0,-1);
            free(part);
            gtk_widget_show(widgets->AdvancedAddButton);
        }
    }
}

void on_advanced_part_remove_device(GtkWidget *self, main_window *widgets){
    advanced_part_widgets *part = g_object_get_data(G_OBJECT(self),"advanced_part_widgets");
    advanced_part_data *data = g_object_get_data(G_OBJECT(self),"advanced_part_data");
    GtkTreeIter iter;
    GtkTreeModel *model = GTK_TREE_MODEL(widgets->DevicesList);
    for_iter (model, &iter){
        char *target;
        gtk_tree_model_get(model,&iter,0,&target,-1);
        if (!strcmp(data->device,target)){
            gtk_widget_destroy(part->MainBox);
            free(part);
            gtk_widget_show(widgets->AdvancedAddButton);
        }
    }
}

void on_advanced_part_remove_virtual(GtkWidget *, main_window *widgets){
    gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->AdvancedVirtualDeviceCombo),0);
}

void on_format_changed(GtkWidget *self, advanced_part_widgets *part){
    int active = gtk_combo_box_get_active(GTK_COMBO_BOX(self));
    switch (active){
        case 0:
        case 1: gtk_revealer_set_reveal_child(GTK_REVEALER(part->FormatRevealer),0);
        break;
        case 2: gtk_revealer_set_reveal_child(GTK_REVEALER(part->FormatRevealer),1);
    }
}

void on_advanced_password_clicked(GtkWidget *, advanced_part_widgets *part){
    yon_password_window *window = yon_password_open(GTK_ENTRY(part->EncryptionEntry));
    gtk_widget_hide(gtk_widget_get_parent(window->EncryptionCombo));
    gtk_widget_hide(window->HashBox);
    gtk_widget_hide(window->NoEncriptionCheck);
}

void on_advanced_part_content_changed(GtkWidget *, GtkWidget *, main_window *widgets){
    GList *list = gtk_container_get_children(GTK_CONTAINER(widgets->AdvancedPartitionAddBox));
    int size = g_list_length(list);
    if (!size){
        return;
    } else if (size == 1){
        advanced_part_widgets *part = g_object_get_data(G_OBJECT(list->data),"advanced_part_widgets");
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(part->SystemSectionToggle),1);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(part->UserDataSectionToggle),1);
    } else if (size == 2){
        advanced_part_widgets *part1 = g_object_get_data(G_OBJECT(list->data),"advanced_part_widgets");
        advanced_part_widgets *part2 = g_object_get_data(G_OBJECT(list->next->data),"advanced_part_widgets");
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(part1->SystemSectionToggle),1);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(part1->UserDataSectionToggle),0);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(part2->SystemSectionToggle),0);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(part2->UserDataSectionToggle),1);
    }
}

advanced_part_widgets *yon_advanced_part_get_for_name(const char *part_name,main_window *widgets){
    GList *list = gtk_container_get_children(GTK_CONTAINER(widgets->AdvancedPartitionAddBox));
    GList *iter;
    for (iter=list;iter;iter=iter->next){
        advanced_part_widgets *part = g_object_get_data(G_OBJECT(iter->data),"advanced_part_widgets");
        advanced_part_data *data = g_object_get_data(G_OBJECT(iter->data),"advanced_part_data");
        if (!yon_char_is_empty(data->device)){
            if (!strcmp(data->device,part_name)) return part;
        }
        if (!yon_char_is_empty(data->partition)){
            if (!strcmp(data->partition,part_name)) return part;
        }
    }
    return NULL;
}

void on_install_advanced_device_chosen(GtkCellRenderer *, gchar *path, main_window *widgets){
    GtkTreeIter iter;
    GtkTreeModel *model = GTK_TREE_MODEL(widgets->DevicesList);
    if (gtk_tree_model_get_iter_from_string(model,&iter,path)){
        int status;
        char *target;
        gtk_tree_model_get(model,&iter,0,&target,5,&status,-1);
            gtk_list_store_set(widgets->DevicesList,&iter,5,!status,-1);
        if (status){
            for_iter (model,&iter){
                gtk_list_store_set(widgets->DevicesList,&iter,6,1,-1);
            }
            yon_advanced_part_remove_parts_for_device(target,widgets);
        } else {
            yon_advanced_part_add_parts_for_device(target,widgets);
        }
    }
}

void yon_advanced_part_to_data(advanced_part_widgets *part, advanced_part_data *data){
    const char *format = gtk_combo_box_get_active_id(GTK_COMBO_BOX(part->FormatCombo));
    data->format = yon_char_new(format);
    if (gtk_combo_box_get_active(GTK_COMBO_BOX(part->FormatCombo))==2){
        gdouble size = gtk_spin_button_get_value(GTK_SPIN_BUTTON(part->SizeSpin));
        char *sizemod = (char*)gtk_combo_box_get_active_id(GTK_COMBO_BOX(part->SizeCombo));
        data->size = size;
        data->size_letter = sizemod[0];

        data->part_label = yon_char_new(gtk_entry_get_text(GTK_ENTRY(part->PartLabelEntry)));

        data->encryption = yon_char_new(gtk_combo_box_get_active_id(GTK_COMBO_BOX(part->EncryptionCombo)));
        data->encryption_password = yon_char_new(gtk_entry_get_text(GTK_ENTRY(part->EncryptionEntry)));

        data->fs_type = yon_char_new(gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(part->FileSystemTypeCombo)));
        data->fs_label = yon_char_new(gtk_entry_get_text(GTK_ENTRY(part->FileSystemLabelEntry)));
    }
}

void yon_advanced_part_clean_config(){
    yon_config_remove_by_key(device_parameter);
    yon_config_remove_by_key(part_parameter);
    yon_config_remove_by_key(part_size_parameter);
    yon_config_remove_by_key(part_label_parameter);
    yon_config_remove_by_key(part_fs_type_parameter);
    yon_config_remove_by_key(part_fs_label_parameter);
    yon_config_remove_by_key(part_crypt_parameter);
    yon_config_remove_by_key(part_format_parameter);
}

gboolean yon_advanced_part_save_part(advanced_part_data *data){
    if (!config(device_parameter)) yon_config_register(device_parameter,device_parameter_command,NULL);
    if (!config(part_parameter)) yon_config_register(part_parameter,part_parameter_command,NULL);
    if (!config(part_size_parameter)) yon_config_register(part_size_parameter,part_size_parameter_command,NULL);
    if (!config(part_label_parameter)) yon_config_register(part_label_parameter,part_label_parameter_command,NULL);
    if (!config(part_fs_type_parameter)) yon_config_register(part_fs_type_parameter,part_fs_type_parameter_command,NULL);
    if (!config(part_fs_label_parameter)) yon_config_register(part_fs_label_parameter,part_fs_label_parameter_command,NULL);
    if (!config(part_crypt_parameter)) yon_config_register(part_crypt_parameter,part_crypt_parameter_command,NULL);
    if (!config(part_format_parameter)) yon_config_register(part_format_parameter,part_format_parameter_command,NULL);

    if (!data){

        yon_config_force_append_element(device_parameter,"",",");
        yon_config_force_append_element(part_parameter,"",",");
        yon_config_force_append_element(part_size_parameter,"",",");
        yon_config_force_append_element(part_label_parameter,"",",");
        yon_config_force_append_element(part_fs_type_parameter,"",",");
        yon_config_force_append_element(part_fs_label_parameter,"",",");
        yon_config_force_append_element(part_crypt_parameter,"",",");
        yon_config_force_append_element(part_format_parameter,"",",");
        return 0;
    }
    yon_config_force_append_element(device_parameter,data->device,",");
    yon_config_force_append_element(part_parameter,data->partition,",");
    if (data->size>0){
        char *size_str = yon_char_from_long(data->size);
        char *temp = yon_char_append_c(size_str,data->size_letter);
        free(size_str);
        yon_config_force_append_element(part_size_parameter,temp,",");
    } else {
        yon_config_force_append_element(part_size_parameter,"",",");

    }
    yon_config_force_append_element(part_label_parameter,data->part_label,",");
    yon_config_force_append_element(part_fs_type_parameter,data->fs_type,",");
    yon_config_force_append_element(part_fs_label_parameter,data->fs_label,",");
    yon_config_force_append_element(part_crypt_parameter,data->encryption,",");
    yon_config_force_append_element(part_format_parameter,data->format,",");
    return 1;
}

gboolean  yon_advanced_part_save(main_window *widgets){
    GList *list = gtk_container_get_children(GTK_CONTAINER(widgets->AdvancedPartitionAddBox));
    
    advanced_part_data *data1 = NULL;
    if (list){
        data1 = g_object_get_data(list->data,"advanced_part_data");
        advanced_part_widgets *part1 = g_object_get_data(list->data,"advanced_part_widgets");
        yon_advanced_part_to_data(part1,data1);

        advanced_part_data *data2 = NULL;
        if (list->next){
            data2 = g_object_get_data(list->next->data,"advanced_part_data");
            advanced_part_widgets *part2 = g_object_get_data(list->next->data,"advanced_part_widgets");
            yon_advanced_part_to_data(part2,data2);
        }
        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(part1->SystemSectionToggle))){
            if (!yon_advanced_part_save_part(data1)&&!yon_advanced_part_save_part(data2)){
                yon_config_remove_by_args(device_parameter,
                    device_parameter,
                    part_parameter,
                    part_size_parameter,
                    part_label_parameter,
                    part_fs_type_parameter,
                    part_fs_label_parameter,
                    part_crypt_parameter,
                    part_format_parameter,
                    NULL);
                return 0;
            }
        } else {
            if (!yon_advanced_part_save_part(data2)&&!yon_advanced_part_save_part(data1)) {
                yon_config_remove_by_args(device_parameter,
                    device_parameter,
                    part_parameter,
                    part_size_parameter,
                    part_label_parameter,
                    part_fs_type_parameter,
                    part_fs_label_parameter,
                    part_crypt_parameter,
                    part_format_parameter,
                    NULL);
                return 0;
            }
        }
    return 1;
    }
    yon_ubl_status_box_spawn(GTK_CONTAINER(widgets->StatusBox),NOTHING_CHOSEN_LABEL,5,BACKGROUND_IMAGE_FAIL_TYPE);
    return 0;
}

int yon_advanced_save(main_window *widgets){
    yon_config_register(AUTOINSTALL_TYPE_INSTALL,AUTOINSTALL_TYPE_INSTALL_command,"custom");
    yon_advanced_part_clean_config();
    if (!yon_advanced_part_save(widgets)){
        return 0;
    }
    if (gtk_switch_get_active(GTK_SWITCH(widgets->AdvancedLoadTypeSwitch))){
        char *boot = NULL;
        if (gtk_switch_get_active(GTK_SWITCH(widgets->AdvancedBiosSectorSwitch))){
            char *temp = yon_char_append_element(boot,"bios","+");
            if(!yon_char_is_empty(boot)) free(boot);
            boot = temp;
        }
        if (gtk_switch_get_active(GTK_SWITCH(widgets->AdvancedEFISwitch))){
            char *temp = yon_char_append_element(boot,"efi","+");
            if(!yon_char_is_empty(boot)) free(boot);
            boot = temp;

        }
        if (!yon_char_is_empty(boot)){
            yon_config_register(boot_parameter,boot_parameter_command,boot);
        } else {
            yon_config_remove_by_key(boot_parameter);
        }
    } else {
        yon_config_remove_by_key(boot_parameter);
    }
    if (gtk_switch_get_active(GTK_SWITCH(widgets->AdvancedSwapSwitch))){
        if (gtk_switch_get_active(GTK_SWITCH(widgets->AdvancedSwapAutoSwitch))){
            yon_config_register(swap_parameter,swap_parameter_command,"auto");

        } else if (gtk_switch_get_active(GTK_SWITCH(widgets->AdvancedSwapRamSwitch))){
            yon_config_register(swap_parameter,swap_parameter_command,"yes");
            yon_config_register(swap_size_parameter,swap_parameter_command,"ram");

        } else if (gtk_switch_get_active(GTK_SWITCH(widgets->AdvancedSwapFixedSwitch))){
            yon_config_register(swap_parameter,swap_parameter_command,"yes");
            long swap_size = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widgets->AdvancedSwapFixedSpin));
            int size_letter = gtk_switch_get_active(GTK_SWITCH(widgets->AdvancedSwapFixedSizeSwitch));
            char *swap_str = yon_char_from_long(swap_size);
            char *size_final = yon_char_unite(swap_str,size_letter?"G":"M",NULL);
            yon_config_register(swap_size_parameter,swap_parameter_command,size_final);
        } else {
            yon_config_remove_by_key(swap_parameter);
            yon_config_remove_by_key(swap_size_parameter);
        }
    }
    yon_debug_output("%s\n",yon_config_get_all_info());
    return 1;
}

int yon_advanced_part_check_count(main_window *widgets){
    GList *list = gtk_container_get_children(GTK_CONTAINER(widgets->AdvancedPartitionAddBox));
    int len = g_list_length(list);
    g_list_free(list); 
    if (len<1) {
        gtk_widget_show(widgets->AdvancedAddButton);
    } else {
        gtk_widget_hide(widgets->AdvancedAddButton);
    }
    if (len<2) return 1;
    return 0;
}

void on_install_advanced_partition_chosen(GtkCellRenderer*, gchar *path, main_window *widgets){
    GtkTreeIter iter;
    GtkTreeModel *model = GTK_TREE_MODEL(widgets->PartitionsList);

    gtk_tree_model_get_iter_from_string(model,&iter,path);
    int status;
    char *target_part, *device;
    gulong part_size;
    gtk_tree_model_get(model,&iter,0,&target_part,5,&part_size,7,&status,9,&device,-1);
    if (status){
        advanced_part_widgets *part = yon_advanced_part_get_for_name(target_part,widgets);
        if (part){
            gtk_list_store_set(widgets->PartitionsList,&iter,7,0,-1);
            gtk_widget_destroy(part->MainBox);
            free(part);
        }
        
    } else if (yon_advanced_part_check_count(widgets)){

        gtk_list_store_set(widgets->PartitionsList,&iter,7,1,-1);
        yon_advanced_part_create_for_part(&iter,widgets);

    }
}

void on_advanced_virtual_device_changed(GtkWidget *, main_window *widgets){
    const char *device = gtk_combo_box_get_active_id(GTK_COMBO_BOX(widgets->AdvancedVirtualDeviceCombo));
    int size;
    config_str vfs_file = yon_resource_open_file(vfs_list_path,&size);
    for (int i=0;i<size;i++){
        int parsed_size;
        config_str parsed = yon_char_parse(vfs_file[i],&parsed_size,";");
        if (!yon_char_is_empty(device)&&!yon_char_is_empty(parsed[2])&&!strcmp(parsed[2],device)){
            gtk_label_set_text(GTK_LABEL(widgets->AdvancedVirtualDeviceLabel),_(parsed[1]));
            gtk_widget_show(gtk_widget_get_parent(widgets->AdvancedVirtualDeviceLabel));
            yon_char_parsed_free(parsed,parsed_size);
            break;
        } else {
            gtk_widget_hide(gtk_widget_get_parent(widgets->AdvancedVirtualDeviceLabel));
            yon_char_parsed_free(parsed,parsed_size);
        }
    }

    advanced_part_widgets *part = NULL;
    GList *list = gtk_container_get_children(GTK_CONTAINER(widgets->AdvancedPartitionAddBox));
    GList *iter;
    for (iter = list; iter; iter=iter->next){
        advanced_part_data *data = g_object_get_data(G_OBJECT(iter->data),"advanced_part_data");
        if (data->part_source == PART_SOURCE_VIRTUAL){
            part = g_object_get_data(G_OBJECT(iter->data),"advanced_part_widgets");
            break;
        }
    }

    if (!yon_char_is_empty(device)){

        if (part){
            advanced_part_data *data = g_object_get_data(G_OBJECT(part->MainBox),"advanced_part_data");
            free(data->device);
            data->device = yon_char_new(device);
            yon_advanced_part_update_from_data(part, data);
        yon_update_part_sections(widgets);
        } else {
            if (yon_advanced_part_check_count(widgets)){
                advanced_part_data *data = yon_advanced_part_data_new();
                data->part_source = PART_SOURCE_VIRTUAL;
                data->device = yon_char_new(device);
                advanced_part_widgets *part = yon_advanced_part_create(data);
                g_object_set_data(G_OBJECT(part->SystemSectionToggle),"advanced_part_widgets",part);
                g_object_set_data(G_OBJECT(part->UserDataSectionToggle),"advanced_part_widgets",part);
                g_object_set_data(G_OBJECT(part->MainBox),"widgets",widgets);
                gtk_box_pack_start(GTK_BOX(widgets->AdvancedPartitionAddBox),part->MainBox,0,0,0);
                g_signal_connect(G_OBJECT(part->RemoveButton),"clicked",G_CALLBACK(on_advanced_part_remove_virtual),widgets);
                yon_advanced_part_update_from_data(part, data);
        yon_update_part_sections(widgets);
                
            } else {
                gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->AdvancedVirtualDeviceCombo),0);
                yon_ubl_status_box_spawn(GTK_CONTAINER(widgets->StatusBox),ERROR_LABEL,5,BACKGROUND_IMAGE_FAIL_TYPE);
                return;
            }
        }
    } else {
        if (part){
            gtk_widget_destroy(part->MainBox);
            advanced_part_data *data = g_object_get_data(G_OBJECT(part->MainBox),"advanced_part_data");
            yon_advanced_part_data_unref(data);
            free(part);
        }
    }
    yon_char_parsed_free(vfs_file,size);
}

void yon_update_part_sections(main_window *widgets){
    GList *list = gtk_container_get_children(GTK_CONTAINER(widgets->AdvancedPartitionAddBox));
    if (list){
        advanced_part_widgets *part = g_object_get_data(G_OBJECT(list->data),"advanced_part_widgets");
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(part->SystemSectionToggle),1);
        if (list->next){
            advanced_part_widgets *part = g_object_get_data(G_OBJECT(list->next->data),"advanced_part_widgets");
            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(part->UserDataSectionToggle),1);

        }
        g_list_free(list);
    }
}

int yon_advanced_part_get_size(advanced_part_widgets *part, main_window *widgets){
    GList *list = NULL;
    if (widgets){
        list = gtk_container_get_children(GTK_CONTAINER(widgets->AdvancedPartitionAddBox));
    } else if (part){
        list = gtk_container_get_children(GTK_CONTAINER(gtk_widget_get_parent(part->MainBox)));
    }
    int size = g_list_length(list);
    g_list_free(list);
    return size;
}

int yon_advanced_part_get_pos(advanced_part_widgets *part, main_window *widgets){
    if (!part) return -1;
    GList *list = NULL;
    if (widgets){
        list = gtk_container_get_children(GTK_CONTAINER(widgets->AdvancedPartitionAddBox));
    } else {
        list = gtk_container_get_children(GTK_CONTAINER(gtk_widget_get_parent(part->MainBox)));
    }
    int pos = g_list_index(list,part->MainBox);
    g_list_free(list);
    return pos;
}

advanced_part_data *yon_advanced_part_data_new(){
    advanced_part_data *data = malloc(sizeof(advanced_part_data));
    memset(data,0,sizeof(advanced_part_data));
    return data;
}

void yon_advanced_part_data_unref(advanced_part_data *data){
    if (!data) return;
    if (!yon_char_is_empty(data->device)) free(data->device); 
    if (!yon_char_is_empty(data->part_label)) free(data->part_label); 
    if (!yon_char_is_empty(data->encryption)) free(data->encryption); 
    if (!yon_char_is_empty(data->encryption_password)) free(data->encryption_password); 
    if (!yon_char_is_empty(data->format)) free(data->format); 
    if (!yon_char_is_empty(data->fs_label)) free(data->fs_label); 
    if (!yon_char_is_empty(data->fs_type)) free(data->fs_type); 
    if (!yon_char_is_empty(data->part_label)) free(data->part_label); 
    if (!yon_char_is_empty(data->partition)) free(data->partition);
    free(data);
}

char *yon_advanced_part_data_get_parameter(const char *config_param, int pos){
    char *final = NULL;
    char *parameter = (char*)config((char*)config_param);
    if (!yon_char_is_empty(parameter)){
        int size;
        config_str parsed = yon_char_parse(parameter,&size,",");
        if (size&&pos<size){
            final = yon_char_new(parsed[pos]);
        }
        yon_char_parsed_free(parsed,size);
    }
    return final;
}

advanced_part_data *yon_advanced_get_config_data(int pos){
    advanced_part_data *data = yon_advanced_part_data_new();
    data->device = yon_advanced_part_data_get_parameter(device_parameter,pos);
    data->partition = yon_advanced_part_data_get_parameter(part_parameter,pos);
    data->part_label = yon_advanced_part_data_get_parameter(part_label_parameter,pos);
    data->fs_type = yon_advanced_part_data_get_parameter(part_fs_type_parameter,pos);
    data->fs_label = yon_advanced_part_data_get_parameter(part_fs_label_parameter,pos);
    data->encryption = yon_advanced_part_data_get_parameter(part_crypt_parameter,pos);
    data->format = yon_advanced_part_data_get_parameter(part_format_parameter,pos);
    data->encryption_password = yon_advanced_part_data_get_parameter(part_crypt_parameter, pos);
    char *size_str = yon_advanced_part_data_get_parameter(part_size_parameter,pos);
    if (!yon_char_is_empty(size_str)){
        data->size = atol(size_str);
    }
    return data;
}

void yon_advanced_part_update_from_data(advanced_part_widgets *part, advanced_part_data *data){
    if (!part||!data) return;
    char *source_string = NULL;
    if (!yon_char_is_empty(data->partition)){
        source_string = data->partition;
    } else if (!yon_char_is_empty(data->device)) {
        source_string = data->device;
    }
    gtk_label_set_text(GTK_LABEL(part->SectionLabel),source_string);

    // format
    int format = 0;
    if (yon_char_is_empty(data->format)) return;
    if (!strcmp(data->format,"yes")){
        format = 2;
    } else if (!strcmp(data->format,"no")){
        format = 1;
    }
    gtk_combo_box_set_active(GTK_COMBO_BOX(part->FormatCombo),format);

    //size
    char *mod = yon_char_new("\n");
    double size_convert = yon_size_long_convert_automatic(data->size,mod);
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(part->SizeSpin),size_convert);
    gtk_combo_box_set_active_id(GTK_COMBO_BOX(part->SizeCombo),mod);
    free(mod);

    // other
    gtk_entry_set_text(GTK_ENTRY(part->PartLabelEntry),data->part_label);
    gtk_combo_box_set_active_id(GTK_COMBO_BOX(part->EncryptionCombo),data->encryption);
    gtk_entry_set_text(GTK_ENTRY(part->EncryptionEntry),data->encryption_password);
    gtk_entry_set_text(GTK_ENTRY(part->FileSystemLabelEntry),data->fs_label);
    gtk_combo_box_set_active_id(GTK_COMBO_BOX(part->FileSystemTypeCombo),data->fs_type);

}

void yon_advanced_part_create_for_device(GtkTreeIter *iter, main_window *widgets){
    GtkTreeModel *model = GTK_TREE_MODEL(widgets->DevicesList);
    int status;
    char *target;
    gtk_tree_model_get(model,iter,0,&target,5,&status,-1);
    if (status&&yon_advanced_part_check_count(widgets)){
        advanced_part_data *data = yon_advanced_part_data_new();
        data->device = target;
        advanced_part_widgets *part = yon_advanced_part_create(data);
        g_signal_connect(G_OBJECT(part->RemoveButton),"clicked",G_CALLBACK(on_advanced_part_remove_device),widgets);
        g_object_set_data(G_OBJECT(part->SystemSectionToggle),"advanced_part_widgets",part);
        g_object_set_data(G_OBJECT(part->UserDataSectionToggle),"advanced_part_widgets",part);
        g_object_set_data(G_OBJECT(part->MainBox),"widgets",widgets);
        gtk_box_pack_start(GTK_BOX(widgets->AdvancedPartitionAddBox),part->MainBox,0,0,0);
        yon_advanced_part_update_from_data(part,data);
        yon_update_part_sections(widgets);
    }
}

void yon_advanced_part_create_for_part(GtkTreeIter *iter, main_window *widgets){
    if (yon_advanced_part_check_count(widgets)){
        char *target;
        gtk_tree_model_get(GTK_TREE_MODEL(widgets->PartitionsList),iter,0,&target,-1);
        advanced_part_data *data = yon_advanced_part_data_new();
        data->partition = target;
        advanced_part_widgets *part = yon_advanced_part_create(data);
        g_signal_connect(G_OBJECT(part->RemoveButton),"clicked",G_CALLBACK(on_advanced_part_remove_part),widgets);
        g_object_set_data(G_OBJECT(part->SystemSectionToggle),"advanced_part_widgets",part);
        g_object_set_data(G_OBJECT(part->UserDataSectionToggle),"advanced_part_widgets",part);
        g_object_set_data(G_OBJECT(part->MainBox),"widgets",widgets);
        gtk_box_pack_start(GTK_BOX(widgets->AdvancedPartitionAddBox),part->MainBox,0,0,0);
        yon_advanced_part_update_from_data(part,data);
        yon_update_part_sections(widgets);
    }
}

void yon_advanced_part_add_parts_for_device(const char *device_name, main_window *widgets){
    for (int i=0;i<main_config.part_size;i++){
        int size;
        config_str parsed = yon_char_parse(main_config.partitions[i],&size,";");
        if (strstr(device_name,parsed[0])){
            GtkTreeIter iter;
            long capacity = 0;
            if (size>3&&!yon_char_is_empty(parsed[3])){
                capacity = atol(parsed[3]);
            }
            char *capacity_string = capacity? yon_size_long_convert_automatic_to_string(capacity) : yon_char_new("");
            long free_space = 0;
            if (size>8&&!yon_char_is_empty(parsed[8])){
                free_space = capacity-atol(parsed[8]);
            }
            char *free_space_string = free_space ? yon_size_long_convert_automatic_to_string(free_space) : yon_char_new("");
            if (!strcmp(parsed[1],"part")){
            gtk_list_store_append(widgets->PartitionsList,&iter);
                gtk_list_store_set(widgets->PartitionsList,&iter,
                0,yon_char_return_if_exist(parsed[2],""),   1,capacity_string,
                2,free_space_string,                        3,yon_char_return_if_exist(parsed[4],""),
                4,yon_char_return_if_exist(parsed[5],""),   5,capacity,
                6,free_space,                               8,1,
                9,yon_char_return_if_exist(parsed[7],""),   10,yon_char_return_if_exist(parsed[0],""),
                11,yon_char_return_if_exist(parsed[10],""),-1);

            }
        }
    }
}

void yon_advanced_part_remove_for_part(const char *part_name, main_window *widgets){
    GList *list = gtk_container_get_children(GTK_CONTAINER(widgets->AdvancedPartitionAddBox));
    GList *iter;
    for (iter=list;iter;iter=iter->next){
        advanced_part_data *data = g_object_get_data(G_OBJECT(iter->data),"advanced_part_data");
        if (!yon_char_is_empty(data->partition)){
            if (!strcmp(data->partition,part_name)){
                advanced_part_widgets *part = g_object_get_data(G_OBJECT(iter->data),"advanced_part_widgets");
                on_advanced_part_remove_part(part->RemoveButton,widgets);
            }
        } else if (!yon_char_is_empty(data->device)){
            if (!strcmp(data->device,part_name)){
                advanced_part_widgets *part = g_object_get_data(G_OBJECT(iter->data),"advanced_part_widgets");
                on_advanced_part_remove_device(part->RemoveButton,widgets);
            }
        }
    }
    g_list_free(list);

}

void yon_advanced_part_remove_parts_for_device(const char *device_name, main_window *widgets){
    GtkTreeIter iter;
    GtkTreeModel *model = GTK_TREE_MODEL(widgets->PartitionsList);
    for_iter(model, &iter){
        char *target, *name;
        gtk_tree_model_get(model,&iter,0,&name,10,&target,-1);
        printf("%s\n",name);
        if (strstr(device_name,target)){
            yon_advanced_part_remove_for_part(name,widgets);
            gtk_list_store_remove(widgets->PartitionsList,&iter);
            if (!gtk_tree_model_get_iter_first(model,&iter)) break;
        }
    }
    if (gtk_tree_model_get_iter_first(model,&iter)) {
        char *target, *name;
        gtk_tree_model_get(model,&iter,0,&name,10,&target,-1);
        if (strstr(device_name,target)){
            yon_advanced_part_remove_for_part(name,widgets);
            gtk_list_store_remove(widgets->PartitionsList,&iter);
        }
    } 
    yon_advanced_part_remove_for_part(device_name,widgets);
}

void on_advanced_part_create(GtkWidget *, main_window *widgets){
    GtkTreeIter iter;
    GtkTreeModel *model;
    if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(widgets->AdvancedDeviceTree)),&model,&iter)){
        yon_advanced_part_create_for_device(&iter,widgets);
    }
}

int yon_advanced_part_select_for_data(advanced_part_data *data, main_window *widgets){
    GtkTreeIter device_iter;
    GtkTreeModel *device_model = GTK_TREE_MODEL(widgets->DevicesList);
    for_iter(device_model, &device_iter){
        char *device_name;
        int status;
        gtk_tree_model_get(device_model,&device_iter,0,&device_name,5,&status,-1);
        if ((!yon_char_is_empty(data->device)&&!strcmp(device_name,data->device))||(!yon_char_is_empty(data->partition)&&strstr(data->partition,device_name))){

            gtk_list_store_set(widgets->DevicesList,&device_iter, 5,1,-1);
            if (!status){
                yon_advanced_part_add_parts_for_device(device_name,widgets);
            }


            if (yon_char_is_empty(data->partition)){
                yon_advanced_part_create_for_device(&device_iter,widgets);
            }
        }
    }
    if (!yon_char_is_empty(data->partition)){
        GtkTreeIter part_iter;
        GtkTreeModel *part_model = GTK_TREE_MODEL(widgets->PartitionsList);
        for_iter(part_model,&part_iter){
            char *part_name;
            gtk_tree_model_get(part_model,&part_iter,0,&part_name,-1);
            if (!strcmp(part_name,data->partition)){
                char *path = gtk_tree_model_get_string_from_iter(GTK_TREE_MODEL(widgets->PartitionsList),&part_iter);
                g_signal_emit_by_name(widgets->AdvancedPartChosenCell,"toggled",path,widgets,NULL);
                
            }
        }
    }
    return 1;
}

void yon_advanced_init(main_window *widgets){
    GList *list = gtk_container_get_children(GTK_CONTAINER(widgets->AdvancedPartitionAddBox));
    GList *iter;
    for (iter=list;iter;iter=iter->next){
        advanced_part_widgets *part = g_object_get_data(G_OBJECT(iter->data),"advanced_part_widgets");
        // on_advanced_part_remove_part(part->RemoveButton,widgets);
        free(part);
        gtk_widget_destroy(iter->data);
    }
    gtk_list_store_clear(widgets->PartitionsList);
    yon_devices_setup(widgets);
    g_signal_handlers_block_by_func(G_OBJECT(widgets->AdvancedVirtualDeviceCombo),G_CALLBACK(on_advanced_virtual_device_changed),widgets);
    gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(widgets->AdvancedVirtualDeviceCombo));
    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widgets->AdvancedVirtualDeviceCombo),NO_LABEL);
    gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->AdvancedVirtualDeviceCombo),0);
    int size;
    config_str vmf_file = yon_resource_open_file(vfs_list_path,&size);
    for (int i=1;i<size;i++){
        int parsed_size;
        config_str parsed = yon_char_parse(vmf_file[i],&parsed_size,";");
        gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(widgets->AdvancedVirtualDeviceCombo),parsed[2],parsed[0]);
        yon_char_parsed_free(parsed,parsed_size);
    }
    yon_char_parsed_free(vmf_file,size);
    g_signal_handlers_unblock_by_func(G_OBJECT(widgets->AdvancedVirtualDeviceCombo),G_CALLBACK(on_advanced_virtual_device_changed),widgets);
    char *install_mode = config(AUTOINSTALL_TYPE_INSTALL);
    if (!yon_char_is_empty(install_mode)){ // &&!strcmp(install_mode,"custom")
        advanced_part_data *data1 = yon_advanced_get_config_data(0);
        advanced_part_data *data2 = yon_advanced_get_config_data(1);
        yon_advanced_part_select_for_data(data1,widgets);
        yon_advanced_part_select_for_data(data2,widgets);
    }
}

advanced_part_widgets *yon_advanced_part_create(advanced_part_data *part_data){
    advanced_part_widgets *part = new(advanced_part_widgets);
    GtkBuilder *builder = gtk_builder_new_from_resource(glade_path_advanced_part);
    yon_scroll_block_for_builder(builder);
    part->MainBox = yon_gtk_builder_get_widget(builder,"MainBox");
    part->SectionLabel = yon_gtk_builder_get_widget(builder,"SectionLabel");
    part->SystemSectionToggle = yon_gtk_builder_get_widget(builder,"SystemSectionToggle");
    part->UserDataSectionToggle = yon_gtk_builder_get_widget(builder,"UserDataSectionToggle");
    part->RemoveButton = yon_gtk_builder_get_widget(builder,"RemoveButton");
    part->FormatCombo = yon_gtk_builder_get_widget(builder,"FormatCombo");
    part->SizeSpin = yon_gtk_builder_get_widget(builder,"SizeSpin");
    part->SizeCombo = yon_gtk_builder_get_widget(builder,"SizeCombo");
    part->PartLabelEntry = yon_gtk_builder_get_widget(builder,"PartLabelEntry");
    part->FileSystemTypeCombo = yon_gtk_builder_get_widget(builder,"FileSystemTypeCombo");
    part->FileSystemLabelEntry = yon_gtk_builder_get_widget(builder,"FileSystemLabelEntry");
    part->EncryptionCombo = yon_gtk_builder_get_widget(builder,"EncryptionCombo");
    part->EncryptionEntry = yon_gtk_builder_get_widget(builder,"EncryptionEntry");
    part->EncryptionButton = yon_gtk_builder_get_widget(builder,"EncryptionButton");
    part->FormatRevealer = yon_gtk_builder_get_widget(builder,"FormatRevealer");

    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(part->SizeCombo),"K",KB_LABEL);
    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(part->SizeCombo),"M",MB_LABEL);
    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(part->SizeCombo),"G",GB_LABEL);
    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(part->SizeCombo),"T",TB_LABEL);
    gtk_combo_box_set_active(GTK_COMBO_BOX(part->SizeCombo),0);

    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(part->FormatCombo),NULL,DEFAULT_LABEL);
    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(part->FormatCombo),"no",DO_NOT_FORMAT_LABEL);
    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(part->FormatCombo),"yes",FORMAT_LABEL);
    gtk_combo_box_set_active(GTK_COMBO_BOX(part->FormatCombo),0);

    g_signal_connect(G_OBJECT(part->EncryptionButton),"clicked",G_CALLBACK(on_advanced_password_clicked),part);
    g_signal_connect(G_OBJECT(part->EncryptionCombo),"changed",G_CALLBACK(yon_gtk_widget_set_sensitive_from_combo_box),part->EncryptionButton);
    g_signal_connect(G_OBJECT(part->EncryptionCombo),"changed",G_CALLBACK(yon_gtk_widget_set_sensitive_from_combo_box),part->EncryptionEntry);
    g_signal_connect(G_OBJECT(part->FormatCombo),"changed",G_CALLBACK(on_format_changed),part);
    g_signal_connect(G_OBJECT(part->SystemSectionToggle),"toggled",G_CALLBACK(on_advanced_part_toggled),NULL);
    g_signal_connect(G_OBJECT(part->UserDataSectionToggle),"toggled",G_CALLBACK(on_advanced_part_toggled),NULL);
    
    yon_fs_type_setup(GTK_COMBO_BOX_TEXT(part->FileSystemTypeCombo));

    g_object_set_data(G_OBJECT(part->MainBox),"advanced_part_widgets",part);
    g_object_set_data(G_OBJECT(part->MainBox),"advanced_part_data",part_data);
    g_object_set_data(G_OBJECT(part->SizeCombo),"advanced_part_widgets",part);
    g_object_set_data(G_OBJECT(part->RemoveButton),"advanced_part_widgets",part);
    g_object_set_data(G_OBJECT(part->RemoveButton),"advanced_part_data",part_data);
    g_object_set_data(G_OBJECT(part->SystemSectionToggle),"advanced_part_widgets",part);
    g_object_set_data(G_OBJECT(part->UserDataSectionToggle),"advanced_part_widgets",part);

    int size;
    config_str encryptions = yon_char_parsed_new(&size,encryptions_list,NULL);
    for (int i=0;i<size;i++){
        gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(part->EncryptionCombo),encryptions[i],encryptions[i]);
    }
    yon_char_parsed_free(encryptions,size);
    return part;
}