#include "ubl-settings-keyboard.h"

void on_layouts_accept(GtkWidget *self, layouts_window *window){
    main_window *widgets = g_object_get_data(G_OBJECT(window->Window),"widgets");
    if (!yon_char_is_empty(window->parameters)){
        yon_config_register(keyboard_layout_parameter,keyboard_layout_parameter_command,window->parameters);
    } else {
        yon_config_remove_by_key(keyboard_layout_parameter);
    }
    on_subwindow_close(self);
    yon_interface_update(widgets);
}

void on_layouts_chosen(GtkCellRenderer *, gchar *path, layouts_window *window){
    GtkTreeIter iter;
    gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(window->list),&iter,path);
    int chosen;
    char *layout, *variant;
    gtk_tree_model_get(GTK_TREE_MODEL(window->list),&iter,0,&layout,1,&variant,3,&chosen,-1);
    gtk_tree_store_set(GTK_TREE_STORE(window->list),&iter,3,!chosen,-1);


    char *full_layout = NULL;
    if (!yon_char_is_empty(variant)){
        full_layout = yon_char_unite(layout,"_",variant,NULL);
    } else {
        full_layout = layout;
    }
    if (!chosen){
        char *temp = yon_char_append_element(window->parameters,full_layout,",");
        free(window->parameters);
        window->parameters = temp;
    } else {
        char *temp = yon_char_remove_element(window->parameters,full_layout,",");
        free(window->parameters);
        window->parameters = temp;
    }
    free(full_layout);
}

void on_system_layouts_add(GtkWidget *, main_window *widgets){
    yon_layouts_add(GTK_TREE_VIEW(widgets->LayoutTree),widgets->LayoutsList,widgets);
}

layouts_window *yon_layouts_window_new(){
    GtkBuilder *builder = gtk_builder_new_from_resource(glade_layouts_path);
    layouts_window *window = malloc(sizeof(layouts_window));
    memset(window,0,sizeof(layouts_window));
    window->Window = yon_gtk_builder_get_widget(builder,"Window");
    window->AcceptButton = yon_gtk_builder_get_widget(builder,"AcceptButton");
    window->CancelButton = yon_gtk_builder_get_widget(builder,"CancelButton");
    window->ChosenCell = GTK_CELL_RENDERER(gtk_builder_get_object(builder,"ChosenCell"));
    window->MainTree = yon_gtk_builder_get_widget(builder,"LayoutsTree");
    window->parameters = yon_char_new(config(keyboard_layout_parameter));

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

void yon_layouts_add(GtkTreeView *, GtkListStore *, main_window *widgets){
    layouts_window *window = yon_layouts_window_new();
    yon_gtk_window_setup(GTK_WINDOW(window->Window),GTK_WINDOW(widgets->Window),TITLE_LABEL,icon_path,"layout_window");

    window->list = main_config.layouts_store;

    gtk_tree_view_set_model(GTK_TREE_VIEW(window->MainTree), GTK_TREE_MODEL(main_config.layouts_store));
    gtk_tree_view_column_clicked(GTK_TREE_VIEW_COLUMN(gtk_tree_view_get_column(GTK_TREE_VIEW(window->MainTree),0)));
    yon_layout_build(window);
    g_object_set_data(G_OBJECT(window->Window),"widgets",widgets);
    g_signal_connect(G_OBJECT(window->AcceptButton),"clicked",G_CALLBACK(on_layouts_accept),window);

    char *languages = config(keyboard_layout_parameter);
    int size;
    config_str parsed = yon_char_parse(languages,&size,",");
    GtkTreeIter iter,itar;
    for_iter(window->list,&iter){
        int found = 0;
        char *id, *id_var;
        gtk_tree_model_get(GTK_TREE_MODEL(window->list),&iter,0,&id,-1);
        for (int i=0;i<size;i++){
            char *key = NULL;
                key = yon_char_new(parsed[i]);
            if (!strcmp(id,key)){
                gtk_tree_store_set(GTK_TREE_STORE(window->list),&iter,3,1,-1);
                found=1;
                break;
            }
        }
        if (!found) {
            gtk_tree_store_set(GTK_TREE_STORE(window->list),&iter,3,0,-1);
        }
        if (gtk_tree_model_iter_children(GTK_TREE_MODEL(window->list),&itar,&iter)){
            for (int valid2=1;valid2;valid2 = gtk_tree_model_iter_next(GTK_TREE_MODEL(window->list),&itar)){
                gtk_tree_model_get(GTK_TREE_MODEL(window->list),&itar,0,&id,1,&id_var,-1);
                for (int i=0;i<size;i++){
                    char *key, *variant = NULL;
                    variant = yon_char_new(parsed[i]);
                    key = yon_char_divide_search(variant,"_",-1);
                    if (!strcmp(key,id)&&!yon_char_is_empty(id_var)&&!strcmp(variant,id_var)){
                        gtk_tree_store_set(GTK_TREE_STORE(window->list),&itar,3,1,-1);
                        found=1;
                        break;
                    }
                }
            }
        }

    }
}

void yon_layouts_remove(GtkTreeView *tree, GtkListStore *cur_list, main_window *widgets){
    GtkTreeModel *model = GTK_TREE_MODEL(cur_list);
    GtkTreeIter iter;
    if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(tree),&model,&iter)){
        dialog_confirmation_data *data = yon_confirmation_dialog_data_new();
        data->action_text = LAYOUT_REMOVE_LABEL;
        data->title = LAYOUT_REMOVE_TITLE_LABEL;
        if (yon_confirmation_dialog_call(widgets->Window,data)!=GTK_RESPONSE_ACCEPT) return;
        char *layout, *variant;
        gtk_tree_model_get(model,&iter,0,&layout,1,&variant,-1);
        if (!yon_char_is_empty(variant)){
            char *temp = yon_char_unite(layout,"_",variant,NULL);
            free(layout);
            layout = temp;
        }
        yon_config_remove_element(keyboard_layout_parameter,layout,",");
    }
    yon_interface_update(widgets);
}

void on_system_layouts_remove(GtkWidget *, main_window *widgets){
    yon_layouts_remove(GTK_TREE_VIEW(widgets->LayoutTree),widgets->LayoutsList,widgets);
}

// standard functions

config_str yon_layout_get_children(char *layout_id, int *size){
    (*size)=0;
    config_str final = NULL;
    for (int i=0;i<main_config.variants_size;i++){
        int parsed_size;
        config_str parsed = yon_char_parse(main_config.variants_list[i],&parsed_size,"|");
        if (!strcmp(parsed[0],layout_id)){
            yon_char_parsed_add_or_create_if_exists(final,size,main_config.variants_list[i]);
        }
    }
    return final;
}

void yon_layout_load(char *layout,main_window *widgets){
    GtkTreeIter iter;
    if (strstr(layout,"_")){
        char *cur_variant = yon_char_new(layout);
        char *cur_layout = yon_char_divide_search(cur_variant,"_",-1);
        for (int i=0;i<main_config.variants_size;i++){
            int parsed_size;
            config_str parsed = yon_char_parse(main_config.variants_list[i],&parsed_size,"|");
            if (!strcmp(parsed[0],cur_layout)&&!strcmp(parsed[1],cur_variant)){
                gtk_list_store_append(widgets->LayoutsList,&iter);
                gtk_list_store_set(widgets->LayoutsList,&iter,0,parsed[0],1,parsed[1],2,_(parsed[2]),-1);
            }
        }

    } else {
        for (int i=0;i<main_config.layouts_size;i++){
            int parsed_size;
            config_str parsed = yon_char_parse(main_config.layouts_list[i],&parsed_size,"|");
            if (!strcmp(parsed[0],layout)){
                gtk_list_store_append(widgets->LayoutsList,&iter);
                gtk_list_store_set(widgets->LayoutsList,&iter,0,parsed[0],2,_(parsed[1]),-1);
            }
        }
    }
}

void yon_layout_build(layouts_window *window){
    gtk_tree_store_clear(window->list);
    GtkTreeIter parent;
    GtkTreeIter iter;
    int size;
    config_str layouts = yon_config_load(layouts_command,&size);
    for (int i=0;i<size;i++){
        yon_char_remove_last_symbol(layouts[i],'\n');
        int parsed_size;
        config_str parsed = yon_char_parse(layouts[i],&parsed_size,"|");
        gtk_tree_store_append(window->list,&parent,NULL);
        gtk_tree_store_set(window->list,&parent,0,parsed[0],2,_(parsed[1]),-1);
        int variants_size;
        config_str variants = yon_layout_get_children(parsed[0],&variants_size);
        yon_char_parsed_free(parsed,parsed_size);
        for (int k=0;k<variants_size;k++){
            parsed = yon_char_parse(variants[k],&parsed_size,"|");
            gtk_tree_store_append(window->list,&iter,&parent);
            gtk_tree_store_set(window->list,&iter,0,parsed[0],1,parsed[1],2,_(parsed[2]),-1);
            yon_char_parsed_free(parsed,parsed_size);
        }
        yon_char_parsed_free(variants,variants_size);
        
    }
    yon_char_parsed_free(layouts,size);
    
}

void on_layout_move_up(GtkWidget *, main_window *widgets){
    GtkTreeModel *model;
    GtkTreeIter iter,*previter;
    if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(widgets->LayoutTree)),&model,&iter)){
        previter = gtk_tree_iter_copy(&iter);
        if (!gtk_tree_model_iter_previous(model,previter)) return;
        char *a, *b;
        gtk_tree_model_get(model,&iter,0,&a,-1);
        gtk_tree_model_get(model,previter,0,&b,-1);
        char *layouts = config(keyboard_layout_parameter);
        char *temp = yon_char_swap_element(layouts,a,b,",");
        yon_config_register(keyboard_layout_parameter,keyboard_layout_parameter_command,temp);
        free(temp);
        gtk_list_store_swap(widgets->LayoutsList,&iter,previter);
        gtk_tree_iter_free(previter);
    }
}

void on_layout_move_down(GtkWidget *, main_window *widgets){
    GtkTreeModel *model;
    GtkTreeIter iter,*nextiter;
    if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(widgets->LayoutTree)),&model,&iter)){
        nextiter = gtk_tree_iter_copy(&iter);
        if (!gtk_tree_model_iter_next(model,nextiter)) return;
        char *a, *b;
        gtk_tree_model_get(model,&iter,0,&a,-1);
        gtk_tree_model_get(model,nextiter,0,&b,-1);
        char *layouts = config(keyboard_layout_parameter);
        char *temp = yon_char_swap_element(layouts,a,b,",");
        yon_config_register(keyboard_layout_parameter,keyboard_layout_parameter_command,temp);
        free(temp);
        gtk_list_store_swap(widgets->LayoutsList,&iter,nextiter);
        gtk_tree_iter_free(nextiter);
    }
}

// void on_layout_dnd_inserted(GtkTreeModel *,  GtkTreePath* ,  GtkTreeIter* iter, main_window *widgets){
//     char *target;
//     gtk_tree_model_get(GTK_TREE_MODEL(widgets->LayoutsList),iter,0,&target,-1);
// }

// void on_layout_dnd_deleted(GtkTreeModel *,  GtkTreePath* ,  GtkTreeIter* iter, main_window *widgets){

//     char *target;
//     gtk_tree_model_get(GTK_TREE_MODEL(widgets->LayoutsList),iter,0,&target,-1);
//     printf("%s\n",target);
// }