#include "ubinstall-gtk.h"

int yon_keyboard_save(main_window *widgets){
        GtkTreeIter iter,iter_child;
        if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(widgets->LayoutList),&iter)){
            yon_ubl_status_box_spawn(GTK_CONTAINER(widgets->StatusBox),LAYOUTS_CHOSEN_BUT_EMPTY_LABEL,5,BACKGROUND_IMAGE_FAIL_TYPE);
            yon_ubl_status_highlight_incorrect(gtk_widget_get_parent(widgets->LayoutTree));
            return 0;
        }
    char *layouts_list="";
        GtkTreeModel *layouts_model=GTK_TREE_MODEL(widgets->LayoutList);
        char *cur_layout=NULL;
        for_iter(layouts_model,&iter){
            int chosen=0;
            int primary=0;
            gtk_tree_model_get(layouts_model,&iter,0,&cur_layout,3,&chosen,4,&primary,-1);
            if (chosen)
                layouts_list = yon_char_unite(layouts_list,yon_char_is_empty(layouts_list)?"":",",cur_layout,NULL);
            if (primary){
                yon_config_register(xkbvariant_parameter,xkbvariant_parameter_command,cur_layout);
            }
            if (gtk_tree_model_iter_children(layouts_model,&iter_child,&iter)){
                for(int valid2=1;valid2;valid2 = gtk_tree_model_iter_next(GTK_TREE_MODEL(widgets->LayoutList),&iter_child)){
                    gtk_tree_model_get(layouts_model,&iter_child,0,&cur_layout,3,&chosen,4,&primary,-1);
                    if (chosen)
                        layouts_list = yon_char_unite(layouts_list,yon_char_is_empty(layouts_list)?"":",",cur_layout,NULL);
                    if (primary){
                        yon_config_register(xkbvariant_parameter,xkbvariant_parameter_command,cur_layout);
                    }
                }
            }
        }

    if (!yon_char_is_empty(layouts_list))
        yon_config_register(xkblayout_parameter,xkblayout_parameter_command,layouts_list);
    else
        yon_config_remove_by_key(xkblayout_parameter);

    if (gtk_combo_box_get_active(GTK_COMBO_BOX(widgets->KeyboardModelCombo))){
        char *model = (char*)gtk_combo_box_get_active_id(GTK_COMBO_BOX(widgets->KeyboardModelCombo));
        if (!yon_char_is_empty(model))
            yon_config_register(xkbmodel_parameter,xkbmodel_parameter_command,model);
    } else{
        yon_config_remove_by_key(xkbmodel_parameter);
    }
    
    if (gtk_combo_box_get_active(GTK_COMBO_BOX(widgets->LayoutBindingCombo))){
        char *options = (char*)gtk_combo_box_get_active_id(GTK_COMBO_BOX(widgets->LayoutBindingCombo));
        if (options){};
        yon_config_register(xkboptions_parameter,xkboptions_parameter_command,options);
    } else {
        yon_config_remove_by_key(xkboptions_parameter);
    }
    
    if (!main_config.configure_mode){
        int size;
        config_str parameters = yon_config_get_save_parameters_by_key(&size,xkbvariant_parameter,xkblayout_parameter,xkbmodel_parameter,xkboptions_parameter,NULL);
        if (parameters){
            char *command_parameters = yon_char_parsed_to_string(parameters,size," -- ");
            char *command = yon_char_unite(ubconfig_dull_command,"--target system ",command_parameters,NULL);
            if (!system(command)){}
            free(command);
            yon_char_parsed_free(parameters,size);
        }
    }
    return 1;
}

ubinstall_keyboard_window *yon_ubinstall_keyboard_new(){
void on_additional_software_toggled();
	ubinstall_keyboard_window *window = malloc(sizeof(ubinstall_keyboard_window));
	GtkBuilder *builder = gtk_builder_new_from_resource(glade_path_ubinstall_keyboard);
	window->MainWindow=yon_gtk_builder_get_widget(builder,"MainWindow");
	window->StatusBox=yon_gtk_builder_get_widget(builder,"StatusBox");
	window->headerBar=yon_gtk_builder_get_widget(builder,"headerBar");
	window->CancelButton=yon_gtk_builder_get_widget(builder,"CancelButton");
	window->SaveButton=yon_gtk_builder_get_widget(builder,"SaveButton");
	window->LayoutsTree=yon_gtk_builder_get_widget(builder,"LayoutsTree");
    window->ActiveToggle = GTK_CELL_RENDERER(gtk_builder_get_object(builder,"ActiveToggle"));

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

return window;
}

void on_keyboard_removed(GtkWidget *, main_window *widgets){
    GtkTreeModel *model;
    GtkTreeIter iter, childiter;
    if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(widgets->LayoutTree)),&model,&iter)){
        gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(widgets->LayoutsFilter),&childiter,&iter);
        gtk_tree_store_set(widgets->LayoutList,&childiter,3,0,-1);
    }
}

void yon_language_selection_changed(GtkCellRenderer *, char *path, ubinstall_language_window *window){
    GtkTreeIter iter;
    int state;

    if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(window->liststore1),&iter,path)){
        gtk_tree_model_get(GTK_TREE_MODEL(window->liststore1),&iter,0,&state,-1);
        gtk_list_store_set(window->liststore1,&iter,0,!state,-1);
    }
}

void on_language_window_accept(GtkWidget *,dictionary *dict){
    main_window *widgets= yon_dictionary_get_data(dict->first,main_window*);
    ubinstall_language_window *window = yon_dictionary_get_data(dict->first->next,ubinstall_language_window*);
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(window->DefaultCheck))){
        gtk_entry_set_text(GTK_ENTRY(widgets->AvailableLanguagesEntry),"");
        GtkTreeIter iter;
        int size;
        config_str lang_parsed = default_langs(&size);

        char *final = "";
        for_iter(widgets->LanguagesList,&iter){
            char *code, *labl;
            gtk_tree_model_get(GTK_TREE_MODEL(widgets->LanguagesList),&iter,1,&labl,2,&code,-1);
            if (yon_char_parsed_check_exist(lang_parsed,size,code)!=-1){
                gtk_list_store_set(widgets->LanguagesList,&iter,0,1,-1);
                char *tmp = yon_char_unite(final,!yon_char_is_empty(final)?";":"",labl,NULL);
                if (!yon_char_is_empty(final)) free(final);
                final = tmp;
            } else
                gtk_list_store_set(widgets->LanguagesList,&iter,0,0,-1);
        }
        if (!yon_char_is_empty(final)){
            gtk_entry_set_text(GTK_ENTRY(widgets->AvailableLanguagesEntry),final);
        }
        gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->LanguagesCombo),-1);
        gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(widgets->LanguagesFilter));
    } else {
        yon_gtk_list_store_copy_full(widgets->LanguagesList,window->liststore1);
        gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(widgets->LanguagesFilter));
        config_str parsed = NULL;
        int size;
        GtkTreeIter iter;
        for_iter(GTK_TREE_MODEL(window->liststore1),&iter){
            char *current;
            int status;
            gtk_tree_model_get(GTK_TREE_MODEL(window->liststore1),&iter,0,&status,1,&current,-1);
            if (status)
                yon_char_parsed_add_or_create_if_exists(parsed,&size,current);
        }
        if (parsed){
            char *final = yon_char_parsed_to_string(parsed,size,"; ");
            gtk_entry_set_text(GTK_ENTRY(widgets->AvailableLanguagesEntry),!yon_char_is_empty(final)?final:"");
            if (yon_char_is_empty(final)) {
                gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->LanguagesCombo),-1);
            }
            if (final) free(final);
            yon_char_parsed_free(parsed,size);
        } else 
            gtk_entry_set_text(GTK_ENTRY(widgets->AvailableLanguagesEntry),"");

    }
    on_subwindow_close(window->MainWindow);
    free(window);
}

ubinstall_language_window *yon_ubinstall_language_new(){
	ubinstall_language_window *window = malloc(sizeof(ubinstall_language_window));
	GtkBuilder *builder = gtk_builder_new_from_resource(glade_path_ubinstall_language);
	window->liststore1=GTK_LIST_STORE(gtk_builder_get_object(builder,"liststore1"));
	window->MainWindow=yon_gtk_builder_get_widget(builder,"MainWindow");
	window->StatusBox=yon_gtk_builder_get_widget(builder,"StatusBox");
	window->DefaultCheck=yon_gtk_builder_get_widget(builder,"DefaultCheck");
	window->LanguagesTree=yon_gtk_builder_get_widget(builder,"LanguagesTree");
	window->headerBar=yon_gtk_builder_get_widget(builder,"headerBar");
	window->CancelButton=yon_gtk_builder_get_widget(builder,"CancelButton");
	window->SaveButton=yon_gtk_builder_get_widget(builder,"SaveButton");
	window->ToggleRenderer=GTK_CELL_RENDERER(gtk_builder_get_object(builder,"ToggleRenderer"));

    g_signal_connect(G_OBJECT(window->DefaultCheck),"toggled",G_CALLBACK(yon_gtk_widget_set_sensitive_from_toggle_button_inversed),window->LanguagesTree);
    g_signal_connect(G_OBJECT(window->ToggleRenderer),"toggled",G_CALLBACK(yon_language_selection_changed),window);
    g_signal_connect(G_OBJECT(window->CancelButton),"clicked",G_CALLBACK(on_subwindow_close),NULL);
return window;
}

void on_language_clicked(GtkWidget *, main_window *widgets){
    ubinstall_language_window *window = yon_ubinstall_language_new();
    g_object_ref(G_OBJECT(window->liststore1));
    gtk_tree_view_set_model(GTK_TREE_VIEW(window->LanguagesTree),NULL);
    yon_gtk_list_store_copy_full(window->liststore1,widgets->LanguagesList);
    gtk_tree_view_set_model(GTK_TREE_VIEW(window->LanguagesTree),GTK_TREE_MODEL(window->liststore1));
    yon_gtk_window_setup(GTK_WINDOW(window->MainWindow),GTK_WINDOW(widgets->MainWindow),TITLE_LABEL,icon_path,"language-chooser-window");

    if (yon_char_is_empty(gtk_entry_get_text(GTK_ENTRY(widgets->AvailableLanguagesEntry)))){
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(window->DefaultCheck),1);
    }

    int size;
    int found=0;
    int statusfound=0;
    config_str langs = default_langs(&size);
    GtkTreeIter iter;
    for_iter(widgets->LanguagesList,&iter){
        char *cur;
        int status;
        gtk_tree_model_get(GTK_TREE_MODEL(widgets->LanguagesList),&iter,0,&status,2,&cur,-1);
        if (status){
            statusfound++;
            if (yon_char_parsed_check_exist(langs,size,cur)>-1) 
                found++;
        }
    }
    if ((found==size)&&statusfound==size){
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(window->DefaultCheck),1);
    }

    dictionary *dict=NULL;
    yon_dictionary_add_or_create_if_exists_with_data(dict,"widgets",widgets);
    yon_dictionary_add_or_create_if_exists_with_data(dict,"window",window);
    g_signal_connect(G_OBJECT(window->SaveButton),"clicked",G_CALLBACK(on_language_window_accept),dict);
    gtk_widget_show(window->MainWindow);
    
}
 
 
void on_layout_toggle(GtkCellRendererToggle*,  gchar* path, ubinstall_keyboard_window *window){
    GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(window->LayoutsTree));
    GtkTreeIter iter;
    if (gtk_tree_model_get_iter_from_string(model,&iter,path)){
        int status=0;
        gtk_tree_model_get(model,&iter,3,&status,-1);
        gtk_tree_store_set(GTK_TREE_STORE(model),&iter,3,!status,-1);
    }
}


void on_keyboard_accept(GtkWidget *self,main_window *widgets){
    gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(widgets->LayoutsFilter));
    on_subwindow_close(self);
}


void on_keyboard_clicked (GtkWidget *, main_window *widgets){
    ubinstall_keyboard_window *window = yon_ubinstall_keyboard_new();
    yon_gtk_window_setup(GTK_WINDOW(window->MainWindow),GTK_WINDOW(widgets->MainWindow),KEYBOARD_TITLE_LABEL,icon_path,"keyboard-window");
    gtk_tree_view_set_model(GTK_TREE_VIEW(window->LayoutsTree),GTK_TREE_MODEL(widgets->LayoutList));
    gtk_tree_view_column_clicked(gtk_tree_view_get_column(GTK_TREE_VIEW(window->LayoutsTree),1));

    g_signal_connect(G_OBJECT(window->ActiveToggle),"toggled",G_CALLBACK(on_layout_toggle),window);
    g_signal_connect(G_OBJECT(window->SaveButton),"clicked",G_CALLBACK(on_keyboard_accept),widgets);
    gtk_widget_show(window->MainWindow);
}

void yon_layout_build(char *key, GHashTable *value, main_window *widgets){
    GtkTreeIter parent;
    GtkTreeIter iter;
    gtk_tree_store_append(widgets->LayoutList,&parent,NULL);
    gtk_tree_store_set(widgets->LayoutList,&parent,0,key,1,_((char*)g_hash_table_lookup(value,"")),2,1,3,0,-1);

    GList *list = g_hash_table_get_keys(value);
    GList *iterator = NULL;
    for (iterator=list;iterator;iterator=iterator->next){
        if (!yon_char_is_empty((char*)iterator->data)){
            gtk_tree_store_append(widgets->LayoutList,&iter,&parent);
            gtk_tree_store_set(widgets->LayoutList,&iter,0,(char*)iterator->data,1,_((char*)g_hash_table_lookup(value,iterator->data)),2,1,3,0,4,0,-1);
        }
    }
}

void yon_keyboard_init(main_window *widgets){
    int size;
    config_str parsed = NULL;
    parsed = yon_config_load(yon_debug_output("%s\n",get_layouts_command),&size);
    GHashTable *table = g_hash_table_new(g_str_hash,g_str_equal);
    for (int i=0;i<size;i++){
        yon_char_remove_last_symbol(parsed[i],'\n');
        int layout_size;
        config_str layout = yon_char_parse(parsed[i],&layout_size,"|");
        if (layout_size){
            
            if (g_hash_table_contains(table,layout[0])){
                GHashTable *child_table = g_hash_table_lookup(table,layout[0]);
                g_hash_table_insert(child_table,yon_char_new(layout[1]),yon_char_new(layout[2]));
            }else {
                GHashTable *child_table = g_hash_table_new(g_str_hash,g_str_equal);
                g_hash_table_insert(table,yon_char_new(layout[0]),child_table);
                g_hash_table_insert(child_table,yon_char_new(layout[1]),yon_char_new(layout[2]));
            }
        }
    }

    g_hash_table_foreach(table,(GHFunc)yon_layout_build,widgets);
    yon_char_parsed_free(parsed,size);
    config_str models = yon_config_load(yon_debug_output("%s\n",get_models_command),&size);
    for (int i=0;i<size;i+=2){
        models[i] = yon_char_divide_search(models[i],"\n",-1);
        models[i+1] = yon_char_divide_search(models[i+1],"\n",-1);
        gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(widgets->KeyboardModelCombo),models[i],_(models[i+1]));
    }
    if (size) yon_char_parsed_free(models,size);

    char *keyboard = config(xkbmodel_parameter);
    char *option_parameter = config(xkboptions_parameter);
    char *layouts = config(xkblayout_parameter);
    char *variant = config(xkbvariant_parameter);

    if (!yon_char_is_empty(keyboard)){
        gtk_combo_box_set_active_id(GTK_COMBO_BOX(widgets->KeyboardModelCombo),keyboard);
    } else {
        gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->KeyboardModelCombo),0);
    }

    if (!yon_char_is_empty(option_parameter)){
        gtk_combo_box_set_active_id(GTK_COMBO_BOX(widgets->LayoutBindingCombo),option_parameter);
    } else{
        gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->LayoutBindingCombo),0);
    }

    if (!yon_char_is_empty(layouts)){
        int parsed_size;
        config_str parsed = yon_char_parse(layouts,&parsed_size,",");

        GtkTreeIter iter, chiter;
        GtkTreeModel *model = GTK_TREE_MODEL(widgets->LayoutList);
        for_iter(model,&iter){
            char *target;
            gtk_tree_model_get(model,&iter,0,&target,-1);
            if (yon_char_parsed_check_exist(parsed,parsed_size,target)>-1){
                gtk_tree_store_set(widgets->LayoutList,&iter,2,1,3,1,-1);
                if (!strcmp(variant,target)){
                    gtk_tree_store_set(widgets->LayoutList,&iter,4,1,-1);
                } else {
                    gtk_tree_store_set(widgets->LayoutList,&iter,4,0,-1);

                }
                for (int valid2 = gtk_tree_model_iter_children(model,&chiter,&iter);valid2;valid2 = gtk_tree_model_iter_next(model,&chiter)){
                    gtk_tree_model_get(model,&chiter,0,&target,-1);
                    if (yon_char_parsed_check_exist(parsed,parsed_size,target)>-1){
                        gtk_tree_store_set(widgets->LayoutList,&chiter,2,1,3,1,-1);
                        if (!strcmp(variant,target)){
                            gtk_tree_store_set(widgets->LayoutList,&chiter,4,1,-1);

                        }
                    } else {
                    gtk_tree_store_set(widgets->LayoutList,&chiter,3,0,4,0,-1);
                    }
                }
            } else {
                gtk_tree_store_set(widgets->LayoutList,&iter,3,0,4,0,-1);
            }

        }
    } else {

    }
}

void on_keyboard_layout_chosen(GtkCellRenderer *, gchar *path, main_window *widgets){
    GtkTreeIter iter, itar, itor, itur;
    gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(widgets->LayoutsFilter),&iter,path);
    int status;
    char *target;
        gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(widgets->LayoutsFilter),&itur,&iter);
    gtk_tree_model_get(GTK_TREE_MODEL(widgets->LayoutList),&itur,4,&status,1,&target,-1);
    // g_signal_handlers_block_by_func(self,G_CALLBACK(on_keyboard_layout_chosen),widgets);
    for_iter(GTK_TREE_MODEL(widgets->LayoutsFilter),&itar){
        gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(widgets->LayoutsFilter),&itor,&itar);
        // gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(widgets->LayoutList),&itar,&itor);
            gtk_tree_store_set(widgets->LayoutList,&itor,4,0,-1);
            GtkTreeIter itor_child;
        if (gtk_tree_model_iter_children(GTK_TREE_MODEL(widgets->LayoutList),&itor_child,&itor)){
            for(int valid2=1;valid2;valid2 = gtk_tree_model_iter_next(GTK_TREE_MODEL(widgets->LayoutList),&itor_child)){
                gtk_tree_store_set(widgets->LayoutList,&itor_child,4,0,-1);
            }
        }

    }
            gtk_tree_store_set(widgets->LayoutList,&itur,4,!status,-1);
    // g_signal_handlers_unblock_by_func(self,G_CALLBACK(on_keyboard_layout_chosen),widgets);
    if (!status){
        yon_config_register(xkbvariant_parameter,xkbvariant_parameter_command,target);
    } else {
        yon_config_remove_by_key(xkbvariant_parameter);
    }
}