#include "libublsettings-gtk3.h"

GSList *translate_widgets = NULL;
GList *translation_funcs = NULL;

struct translation_func_struct{
    GtkWidget *target;
    void *func;
};


void on_translation_widget_deleted(GtkWidget *self){
    // GList *delete_target = g_list_find(translate_widgets,self);
    translate_widgets = g_slist_remove(translate_widgets,self);
}

void on_translation_func_widget_deleted(GtkWidget *self){
    GList *iter = NULL;
    for(iter=translation_funcs;iter;iter=iter->next){
        struct translation_func_struct *cur = (struct translation_func_struct *)iter->data;
        if (self == cur->target){
            translation_funcs = g_list_remove(translation_funcs,cur);
            free(cur);
        }
    }
}

void yon_gtk_widget_set_translation(GtkWidget *target){
    GObject *cur_widget = NULL;
    char *widget_text = NULL;
    if (GTK_IS_BUTTON(target)){
        cur_widget = G_OBJECT(target);
        widget_text = yon_char_new(gtk_button_get_label(GTK_BUTTON(cur_widget)));
    } else if (GTK_IS_LABEL(target)){
        cur_widget = G_OBJECT(target);
        widget_text = yon_char_new(gtk_label_get_label(GTK_LABEL(cur_widget)));
    } else if (GTK_IS_TREE_VIEW_COLUMN(target)){
        cur_widget = G_OBJECT(target);
        widget_text = yon_char_new(gtk_tree_view_column_get_title(GTK_TREE_VIEW_COLUMN(cur_widget)));
    } else if (GTK_IS_MENU_ITEM(target)){
        cur_widget = G_OBJECT(target);
        GList *list = gtk_container_get_children(GTK_CONTAINER(cur_widget));
        if (list) {
            GtkWidget *widget = target;
            g_list_free(list);
            if (GTK_IS_BOX(widget)){
                return;
            }
        }
        widget_text = yon_char_new(gtk_menu_item_get_label(GTK_MENU_ITEM(cur_widget)));
    } else return;
    translate_widgets = g_slist_append(translate_widgets,target);
    g_object_set_data(G_OBJECT(cur_widget),"original_label",(void*)widget_text);
    g_signal_connect(G_OBJECT(target),"delete-event",G_CALLBACK(on_translation_widget_deleted),NULL);
}

int yon_translation_set_translation_func(GtkWidget *target, void (*translation_func)(GtkWidget *)){
    if (!translation_func) return 0;
    yon_gtk_widget_set_translation(target);
    struct translation_func_struct *cur = malloc(sizeof(struct translation_func_struct));
    cur->target = target;
    cur->func = (void*)translation_func;
    translate_widgets = g_slist_append(translate_widgets,target);
    translation_funcs = g_list_append(translation_funcs,cur);
    
}

void yon_translation_init(GSList *update_widgets){
    // translation_funcs=g_list_alloc();
    translate_widgets = update_widgets;
    GSList *list = translate_widgets;
    GSList *iter;
    for (iter = list; iter; iter = iter->next){
        if (GTK_IS_WIDGET(iter->data)){
            const char *tooltip = gtk_widget_get_tooltip_text(GTK_WIDGET(iter->data));
            if (!yon_char_is_empty(tooltip)){
                g_object_set_data(G_OBJECT(iter->data),"original_tooltip",(void*)yon_char_new(tooltip));
            }
        }
        GObject *cur_widget = NULL;
        const char *widget_text = NULL;
        if (GTK_IS_BUTTON(iter->data)){
            cur_widget = G_OBJECT(iter->data);
            widget_text = yon_char_new(gtk_button_get_label(GTK_BUTTON(cur_widget)));
        } else if (GTK_IS_LABEL(iter->data)){
            cur_widget = G_OBJECT(iter->data);
            widget_text = yon_char_new(gtk_label_get_label(GTK_LABEL(cur_widget)));
        } else if (GTK_IS_TREE_VIEW_COLUMN(iter->data)){
            cur_widget = G_OBJECT(iter->data);
            widget_text = yon_char_new(gtk_tree_view_column_get_title(GTK_TREE_VIEW_COLUMN(cur_widget)));
        } else if (GTK_IS_MENU_ITEM(iter->data)){
            cur_widget = G_OBJECT(iter->data);
            GList *itlist = gtk_container_get_children(GTK_CONTAINER(cur_widget));
            if (itlist) {
                GtkWidget *widget = itlist->data;
                g_list_free(itlist);
                if (GTK_IS_BOX(widget)){
                    continue;
                }
            }
            widget_text = yon_char_new(gtk_menu_item_get_label(GTK_MENU_ITEM(cur_widget)));
        } else continue;
            g_object_set_data(G_OBJECT(cur_widget),"original_label",(void*)widget_text);

    }
}

void yon_update_translation(){
    GSList *list = translate_widgets;
    dictionary *diter = NULL;
    GSList *iter;
    guint custom_size = g_list_length(translation_funcs);
    for (iter = list; iter; iter = iter->next){
        if (custom_size){
            GList *custom_iter = NULL; 
            int found = 0;
            for (custom_iter = translation_funcs;custom_iter;custom_iter=custom_iter->next){
                struct translation_func_struct *cur = ((struct translation_func_struct *)custom_iter->data);
                if (iter->data==cur->target){
                    found=1;
                    ((void(*)(GtkWidget*))cur->func)(cur->target);
                    break;
                }
            }
            if (found) continue;
        }
        if (GTK_IS_BUTTON(iter->data)){
            GtkWidget *cur_button = GTK_WIDGET(iter->data);
            char *source_label = g_object_get_data(G_OBJECT(cur_button),"original_label");
            if (!yon_char_is_empty(source_label)){
                gtk_button_set_label(GTK_BUTTON(cur_button),_(source_label));
            }

        } else if (GTK_IS_LABEL(iter->data)){
            GtkWidget *cur_label = GTK_WIDGET(iter->data);
            char *source_label = g_object_get_data(G_OBJECT(cur_label),"original_label");
            if (!yon_char_is_empty(source_label)){
                if (gtk_label_get_use_markup(GTK_LABEL(cur_label))){
                    gtk_label_set_markup(GTK_LABEL(cur_label),_(source_label));
                } else {
                    gtk_label_set_text(GTK_LABEL(cur_label),_(source_label));
                }
            }

        } else if (GTK_IS_MENU_ITEM(iter->data)){
            GtkWidget *cur_menu_item = GTK_WIDGET(iter->data);
            char *source_label = g_object_get_data(G_OBJECT(cur_menu_item),"original_label");
            if (!yon_char_is_empty(source_label)){
                gtk_menu_item_set_label(GTK_MENU_ITEM(cur_menu_item),_(source_label));
            }

        } else if (GTK_IS_TREE_VIEW_COLUMN(iter->data)){
            GObject *cur_column = G_OBJECT(iter->data);
            char *source_label = g_object_get_data(G_OBJECT(cur_column),"original_label");
            if (!yon_char_is_empty(source_label)){
                gtk_tree_view_column_set_title(GTK_TREE_VIEW_COLUMN(cur_column),_(source_label));
            }
        }
        if (GTK_IS_WIDGET(iter->data)){
            const char *tooltip_text = g_object_get_data(G_OBJECT(iter->data),"original_tooltip");
            if (!yon_char_is_empty(tooltip_text)){
                gtk_widget_set_tooltip_text(GTK_WIDGET(iter->data),_(tooltip_text));
            }
        }
    }
    
}

void yon_translation_set_language(const char *lang, const char *locale_name){
    setlocale(LC_ALL,(char *)lang);
    g_setenv("LANGUAGE",(char *)lang,1);
    textdomain(locale_name);

}