#include "ubinstall-gtk.h"

void on_source_changed(GtkComboBox *self){
    source_element *element = g_object_get_data(G_OBJECT(self),"source_element");
    switch (gtk_combo_box_get_active(self)){
        case 0:{
            gtk_widget_hide(element->PathButton);
                gtk_widget_hide(element->PathEntry);
                gtk_widget_show(element->DeviceCombo);
            } break;
            case 1:
            case 2:{
                gtk_widget_show(element->PathButton);
                gtk_widget_show(element->PathEntry);
                gtk_widget_hide(element->DeviceCombo);
                
            } break;
            case 3: {
                gtk_widget_hide(element->PathButton);
                gtk_widget_hide(element->PathEntry);
                gtk_widget_hide(element->DeviceCombo);
            }
        }
}

void yon_source_update(source_window *window){
    GList *list = gtk_container_get_children(GTK_CONTAINER(window->AddBox));
    GList *iter;
    for (iter = list; iter; iter = iter->next){
        source_element *element = (source_element*)g_object_get_data(G_OBJECT(iter->data),"source_element");
        if (!iter->next&&!element->AddButton){
            GtkWidget *button = gtk_button_new_from_icon_name(add_icon_path,GTK_ICON_SIZE_BUTTON);
            g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(on_source_add),window);
            gtk_box_pack_end(GTK_BOX(element->MainBox),button,0,0,0);
            element->AddButton = button;
            gtk_style_context_add_class(gtk_widget_get_style_context(button),"thin");
            gtk_style_context_add_class(gtk_widget_get_style_context(button),"instant");
            gtk_widget_show(button);
            gtk_box_reorder_child(GTK_BOX(element->MainBox),button,0);
        } else if (iter->next){
            if (element->AddButton) {
                gtk_widget_destroy(element->AddButton);
                element->AddButton = NULL;
            }
        }
        
        if (!iter->next&&!iter->prev){
            gtk_widget_hide(element->RemoveButton);
        } else {
            gtk_widget_show(element->RemoveButton);
        }
    }
}

source_element *yon_source_element_new(){
    source_element *element = new(source_element);
    GtkBuilder *builder = gtk_builder_new_from_resource(glade_path_source_element);

    element->MainBox = yon_gtk_builder_get_widget(builder,"MainBox");
    element->TypeCombo = yon_gtk_builder_get_widget(builder,"TypeCombo");
    element->PathEntry = yon_gtk_builder_get_widget(builder,"PathEntry");
    element->DeviceCombo = yon_gtk_builder_get_widget(builder,"DeviceCombo");
    element->PathButton = yon_gtk_builder_get_widget(builder,"PathButton");
    element->RemoveButton = yon_gtk_builder_get_widget(builder,"RemoveButton");
    element->AddButton = NULL;

    yon_gtk_combo_box_block_scroll(GTK_COMBO_BOX(element->DeviceCombo));
    yon_gtk_combo_box_block_scroll(GTK_COMBO_BOX(element->TypeCombo));

    g_signal_connect(G_OBJECT(element->RemoveButton),"clicked",G_CALLBACK(on_source_remove),element);
    g_signal_connect(G_OBJECT(element->PathButton),"clicked",G_CALLBACK(on_source_choose),element);
    g_signal_connect(G_OBJECT(element->TypeCombo),"changed",G_CALLBACK(on_source_changed),element);

    g_object_set_data(G_OBJECT(element->PathButton),"source_element",element);
    g_object_set_data(G_OBJECT(element->MainBox),"source_element",element);
    g_object_set_data(G_OBJECT(element->TypeCombo),"source_element",element);

    gtk_widget_hide(element->PathButton);

    int size;
    config_str parts = yon_config_load(get_parts_and_devices_command, &size);
    for (int i=0;i<size;i++){
        int parsed_size;
        config_str parsed = yon_char_parse(parts[i],&parsed_size,";");
        if (!strcmp(parsed[0],"part")){
            gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(element->DeviceCombo),parsed[1],parsed[1]);
        }
        yon_char_parsed_free(parsed,parsed_size);
    }
    gtk_combo_box_set_active(GTK_COMBO_BOX(element->DeviceCombo),0);
    yon_char_parsed_free(parts,size);

    return element;
}

void yon_source_element_add(char *key,void*,source_window *window){
    source_element *element = yon_source_element_new();
    gtk_box_pack_start(GTK_BOX(window->AddBox),element->MainBox,0,0,0);
    g_object_set_data(G_OBJECT(element->MainBox),"window",window);

    if (yon_char_is_empty(key)) return;

    if (yon_char_check_begins_with(key,"/dev/")){
        gtk_combo_box_set_active_id(GTK_COMBO_BOX(element->DeviceCombo),key);
        gtk_combo_box_set_active(GTK_COMBO_BOX(element->TypeCombo),0);
    } else if (g_regex_match_simple(".*\\.iso",key,G_REGEX_DEFAULT,G_REGEX_MATCH_DEFAULT)){
        gtk_entry_set_text(GTK_ENTRY(element->PathEntry),key);
        gtk_combo_box_set_active(GTK_COMBO_BOX(element->TypeCombo),2);
    } else if (!strcmp(key,"local")){
        gtk_combo_box_set_active(GTK_COMBO_BOX(element->TypeCombo),3);
    } else {
        gtk_entry_set_text(GTK_ENTRY(element->PathEntry),key);
        gtk_combo_box_set_active(GTK_COMBO_BOX(element->TypeCombo),1);
    }
}

void on_source_add(GtkWidget *,source_window *window){
    yon_source_element_add(NULL,NULL,window);
    yon_source_update(window);
}

void on_source_remove(GtkWidget *,source_element *element){
    source_window *window = g_object_get_data(G_OBJECT(element->MainBox),"window");
    gtk_widget_destroy(element->MainBox);    
    yon_source_update(window);
}

void on_source_choose(GtkWidget *self){
    source_element *element = g_object_get_data(G_OBJECT(self),"source_element");
    switch (gtk_combo_box_get_active(GTK_COMBO_BOX(element->TypeCombo))){
        case 1:{
            filechooser_window *dialog = yon_file_chooser_window_new(GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
            yon_gtk_window_setup(GTK_WINDOW(dialog->Window),GTK_WINDOW(dialog->Window),OPEN_LABEL,icon_path,"filechooser_window");
            if (yon_file_chooser_start(dialog)==GTK_RESPONSE_ACCEPT){
                gtk_entry_set_text(GTK_ENTRY(element->PathEntry),dialog->last_success_selection);
                free(dialog);
            }

        } break;
        case 2: {
            filechooser_window *dialog = yon_file_chooser_window_new(GTK_FILE_CHOOSER_ACTION_OPEN);
        yon_gtk_window_setup(GTK_WINDOW(dialog->Window),GTK_WINDOW(dialog->Window),OPEN_LABEL,icon_path,"filechooser_window");
            GtkFileFilter *filter = gtk_file_filter_new();
            gtk_file_filter_add_pattern(filter,"*.iso");
            gtk_file_filter_set_name(filter,".iso");
            gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog->MainFileChooser),filter);

            if (yon_file_chooser_start(dialog)==GTK_RESPONSE_ACCEPT){
                gtk_entry_set_text(GTK_ENTRY(element->PathEntry),dialog->last_success_selection);
                free(dialog);
            }

        } break;
    }
}

void on_source_accept(GtkWidget *,source_window *window){
    if (gtk_switch_get_active(GTK_SWITCH(window->AutoSwitch))){
        yon_config_register(source_parameter,source_parameter_command,"auto");
        on_subwindow_close(window->Window);
        return;
    }
    char *sources_list = NULL;
    GList *list = gtk_container_get_children(GTK_CONTAINER(window->AddBox));
    GList *iter;
    for (iter=list;iter;iter=iter->next){
        source_element *element = NULL;
        element = g_object_get_data(G_OBJECT(iter->data),"source_element");
        switch(gtk_combo_box_get_active(GTK_COMBO_BOX(element->TypeCombo))){
            case 0:{
                char *cur = (char*)gtk_combo_box_get_active_id(GTK_COMBO_BOX(element->DeviceCombo));
                if (yon_char_check_element(sources_list,cur,",")){
                    yon_ubl_status_box_spawn(GTK_CONTAINER(window->StatusBox),VALUE_REPEAT_LABEL,5,BACKGROUND_IMAGE_FAIL_TYPE);
                    yon_ubl_status_highlight_incorrect(element->DeviceCombo);
                    return;
                }
                if (strstr(cur,",")){
                    yon_ubl_status_box_spawn(GTK_CONTAINER(window->StatusBox),PATH_INVALID_LABEL,5,BACKGROUND_IMAGE_FAIL_TYPE);
                    yon_ubl_status_highlight_incorrect(element->DeviceCombo);
                    return;
                }
                char *temp = yon_char_append_element(sources_list,cur,",");
                if (!yon_char_is_empty(sources_list)) free(sources_list);
                sources_list = temp;
            } break;
            case 1:{
                char *cur = (char*)gtk_entry_get_text(GTK_ENTRY(element->PathEntry));
                if (yon_char_is_empty(cur)){
                    yon_ubl_status_box_spawn(GTK_CONTAINER(window->StatusBox),_EMPTY_IMPORTANT_LABEL,5,BACKGROUND_IMAGE_FAIL_TYPE);
                    yon_ubl_status_highlight_incorrect(element->PathEntry);
                    return;
                }
                if (yon_char_check_element(sources_list,cur,",")){
                    yon_ubl_status_box_spawn(GTK_CONTAINER(window->StatusBox),VALUE_REPEAT_LABEL,5,BACKGROUND_IMAGE_FAIL_TYPE);
                    yon_ubl_status_highlight_incorrect(element->PathEntry);
                    return;
                }
                if (strstr(cur,",")){
                    yon_ubl_status_box_spawn(GTK_CONTAINER(window->StatusBox),PATH_INVALID_LABEL,5,BACKGROUND_IMAGE_FAIL_TYPE);
                    yon_ubl_status_highlight_incorrect(element->PathEntry);
                    return;
                }
                char *temp = yon_char_append_element(sources_list,cur,",");
                if (!yon_char_is_empty(sources_list)) free(sources_list);
                sources_list = temp;
            } break;
            case 2:{
                char *cur = (char*)gtk_entry_get_text(GTK_ENTRY(element->PathEntry));
                if (yon_char_check_element(sources_list,cur,",")){
                    yon_ubl_status_box_spawn(GTK_CONTAINER(window->StatusBox),VALUE_REPEAT_LABEL,5,BACKGROUND_IMAGE_FAIL_TYPE);
                    yon_ubl_status_highlight_incorrect(element->PathEntry);
                    return;
                }
                if (strstr(cur,",")){
                    yon_ubl_status_box_spawn(GTK_CONTAINER(window->StatusBox),PATH_INVALID_LABEL,5,BACKGROUND_IMAGE_FAIL_TYPE);
                    yon_ubl_status_highlight_incorrect(element->PathEntry);
                    return;
                }
                char *temp = yon_char_append_element(sources_list,cur,",");
                if (!yon_char_is_empty(sources_list)) free(sources_list);
                sources_list = temp;
            } break;
            case 3: {
                if (yon_char_check_element(sources_list,"local",",")){
                    yon_ubl_status_box_spawn(GTK_CONTAINER(window->StatusBox),VALUE_REPEAT_LABEL,5,BACKGROUND_IMAGE_FAIL_TYPE);
                    yon_ubl_status_highlight_incorrect(element->TypeCombo);
                    return;
                }
                char *temp = yon_char_append_element(sources_list,"local",",");
                sources_list = temp;
            }
        }
    }
    if (!yon_char_is_empty(sources_list)){
        yon_config_register(source_parameter,source_parameter_command,sources_list);
    } else {
        yon_config_remove_by_key(source_parameter);
    }
    if (!main_config.configure_mode){
        yon_debug_output("%s\n",yon_config_save_args_simple(main_config.config_load_path,source_parameter,NULL));
    }
    on_subwindow_close(window->Window);
    free(window);
}

source_window *yon_source_window_new(){
    source_window *window = new(source_window);
    GtkBuilder *builder = gtk_builder_new_from_resource(glade_path_source);

    window->Window = yon_gtk_builder_get_widget(builder,"MainWindow");
    window->StatusBox = yon_gtk_builder_get_widget(builder,"StatusBox");
    window->CancelButton = yon_gtk_builder_get_widget(builder,"CancelButton");
    window->AcceptButton = yon_gtk_builder_get_widget(builder,"AcceptButton");
    window->AutoSwitch = yon_gtk_builder_get_widget(builder,"AutoSwitch");
    window->AddBox = yon_gtk_builder_get_widget(builder,"AddBox");

    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_source_accept),window);
    g_signal_connect(G_OBJECT(window->AutoSwitch),"state-set",G_CALLBACK(yon_gtk_widget_set_sensitive_from_switch_inversed),gtk_widget_get_parent(gtk_widget_get_parent(window->AddBox)));
    
    {
        char *config_parameter = config(source_parameter);
        if (!yon_char_is_empty(config_parameter)){
            gtk_switch_set_active(GTK_SWITCH(window->AutoSwitch),0);
            int size;
            config_str parsed = yon_char_parse(config_parameter,&size,",");
            for (int i=0;i<size;i++){
                yon_source_element_add(parsed[i],NULL,window);
            }
            yon_char_parsed_free(parsed,size);
        } else {
            yon_source_element_add(NULL,NULL,window);
        }

    }
    return window;
}

void on_source_clicked(GtkWidget *,main_window *widgets){
    source_window *window = yon_source_window_new();
    g_object_set_data(G_OBJECT(window->Window),"widgets",widgets);
    yon_source_update(window);
    gtk_widget_show(window->Window);
}
