#include "ubl-settings-datetime.h"

config main_config;

// functions

config_str yon_char_parsed_localize(config_str parsed, int size){
    config_str new_parsed = yon_char_parsed_copy(parsed,size);
    for (int i=0;i<size;i++){
        char *temp = yon_char_new(_(new_parsed[i]));
        free(new_parsed[i]);
        new_parsed[i]=temp;
    }
    return new_parsed;
}

config_str yon_char_parsed_sort(config_str parsed, int size){
    config_str new_parsed = yon_char_parsed_copy(parsed,size);
    qsort(new_parsed,size,sizeof(char*),(__compar_fn_t)yon_char_parsed_compare);
    return new_parsed;
}

//Config functions
void yon_save_parameters(GtkWidget *self, main_window *widgets){
    if (self == widgets->DHCPCombo||self == widgets->NTPEntry){
        int mode = gtk_combo_box_get_active(GTK_COMBO_BOX(widgets->DHCPCombo));
        switch(mode){
            case 0:yon_config_remove_by_key(NTPSERVERS_parameter);
                break;
            case 1:yon_config_register(NTPSERVERS_parameter,NTPSERVERS_parameter_command,"dhcp");
                break;
            case 2:yon_config_register(NTPSERVERS_parameter,NTPSERVERS_parameter_command,"default");
                break;
            case 3:yon_config_register(NTPSERVERS_parameter,NTPSERVERS_parameter_command,"ntp-ru");
                break;
            case 5:yon_config_register(NTPSERVERS_parameter,NTPSERVERS_parameter_command,"disable");
                break;
            case 6:yon_config_register(NTPSERVERS_parameter,NTPSERVERS_parameter_command,"stop");
                break;
            case 4:
                char *value = (char*)gtk_entry_get_text(GTK_ENTRY(widgets->NTPEntry));
                if (yon_char_is_empty(value)&&self == widgets->NTPEntry) {
                    yon_ubl_status_box_render(EMPTY_IMPORTANT_LABEL,BACKGROUND_IMAGE_FAIL_TYPE);
                    yon_ubl_status_highlight_incorrect(widgets->NTPEntry);
                    return;
                }
                yon_config_register(NTPSERVERS_parameter,NTPSERVERS_parameter_command,value);
                break;
        }
    } else if (self == widgets->TimeSyncTypeCombo){
        int hwclock_sync = gtk_combo_box_get_active(GTK_COMBO_BOX(widgets->TimeSyncTypeCombo));
        if (hwclock_sync==1){
            yon_config_register(HWCLOCK_SYNC_parameter,HWCLOCK_SYNC_parameter_command,"localtime");
        } else if (hwclock_sync == 2) {
            yon_config_register(HWCLOCK_SYNC_parameter,HWCLOCK_SYNC_parameter_command,"utc");
        } else {
            yon_config_remove_by_key(HWCLOCK_SYNC_parameter);
        }

    } else if (self == widgets->RegionCombo||self == widgets->ZoneCombo){
        const char *region = gtk_combo_box_get_active_id(GTK_COMBO_BOX(widgets->RegionCombo));
        const char *zone = gtk_combo_box_get_active_id(GTK_COMBO_BOX(widgets->ZoneCombo));

        if (!yon_char_is_empty(region)&&!yon_char_is_empty(zone)){
            char *zone_parameter = yon_char_unite((char*)region,"/",(char*)zone,NULL);
            yon_config_register(ZONE_parameter,ZONE_parameter_command,zone_parameter);

            if (!yon_window_config_check_init()) return;
            
            char *parameter = config(ZONE_parameter);
            GTimeZone *tz = g_time_zone_new_identifier(parameter);
            if (!tz) return;
            GDateTime *datetime = g_date_time_new_now(tz);
            long hours = atol(g_date_time_format(datetime,"%H"));
            long minutes = atol(g_date_time_format(datetime,"%M"));
            char *format = yon_settings_configuration_get(date_format_parameter);
            char *date = g_date_time_format(datetime,format?format:"%d.%m.%Y");
            g_date_time_unref(datetime);
            g_time_zone_unref(tz);
            gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->HourSpin),hours);
            gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->MinuteSpin),minutes);
            gtk_entry_set_text(GTK_ENTRY(widgets->DateEntry),date);

        }
    } 

}

int check_input(main_window *widgets){
    int ntp_active = gtk_combo_box_get_active(GTK_COMBO_BOX(widgets->DHCPCombo));
    if (ntp_active == 4){
        const char *ntp = gtk_entry_get_text(GTK_ENTRY(widgets->NTPEntry));
        if (yon_char_is_empty(ntp)){
            yon_ubl_status_box_render(EMPTY_IMPORTANT_LABEL,BACKGROUND_IMAGE_FAIL_TYPE);
            yon_ubl_status_highlight_incorrect(widgets->NTPEntry);
            return 0;
        }
    }
    return 1;
}

void yon_load_proceed(YON_CONFIG_TYPE type){ 
	if (type!=YON_CONFIG_CUSTOM){
		yon_config_clean();
        if (!yon_char_is_empty(config_get_default_command))
            yon_config_load_config(YON_CONFIG_DEFAULT,config_get_default_command,NULL);
	}
    if (type==YON_CONFIG_GLOBAL){
		yon_config_load_config(type,config_get_command("global"),NULL);
	} else if (type==YON_CONFIG_LOCAL){
		yon_config_load_config(type,config_get_command("system"),NULL);
    } else if (type==YON_CONFIG_CUSTOM){
		char *path="";
        textdomain(template_ui_LocaleName);
		GtkWidget *dialog = gtk_file_chooser_dialog_new(template_app_information.app_title,NULL,GTK_FILE_CHOOSER_ACTION_SAVE,CANCEL_LABEL,GTK_RESPONSE_CANCEL,OPEN_LABEL,GTK_RESPONSE_ACCEPT,NULL);
        textdomain(LocaleName);
        gtk_window_set_icon_name(GTK_WINDOW(dialog),"com.ublinux.ubl-settings-services");
        gtk_window_set_title(GTK_WINDOW(dialog),TITLE_LABEL);
        GtkFileFilter *filter = gtk_file_filter_new();
		gtk_file_filter_add_pattern(filter,"*.ini");
        gtk_file_filter_set_name(filter, "*.ini");
		gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog),filter);
		gtk_widget_show(dialog);
		int response = gtk_dialog_run(GTK_DIALOG(dialog));
		if (response == GTK_RESPONSE_ACCEPT){
			char *file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
			if (!yon_char_is_empty(file)){
				path=file;
			}
            yon_config_clean();
            if (!yon_char_is_empty(config_get_default_command))
                yon_config_load_config(YON_CONFIG_DEFAULT,config_get_default_command,NULL);
            char *command = config_get_command(path);
            yon_config_load_config(type,command,NULL);
			gtk_widget_destroy(dialog);
		} else {
			gtk_widget_destroy(dialog);
		}
	}
}

void on_config_local_load(GtkWidget *self,main_window *widgets){
    if (self){};
        yon_load_proceed(YON_CONFIG_LOCAL);
        main_config.load_mode=1;
        yon_interface_update(widgets);
}

void on_config_global_load(GtkWidget *self,main_window *widgets){
    if (self){}
        yon_load_proceed(YON_CONFIG_GLOBAL);
        main_config.load_mode=0;
        yon_interface_update(widgets);
}

void on_config_custom_load(GtkWidget *self,main_window *widgets){
    if (self){}
	yon_load_proceed(YON_CONFIG_CUSTOM);
	main_config.load_mode=3;
        yon_interface_update(widgets);
}

void on_config_global_local_save(){
    main_config.save_config=YON_CONFIG_BOTH;
    yon_save_proceed(NULL,YON_CONFIG_BOTH,config_get_command("global"),NULL);
}

void on_config_local_save(){
    main_config.save_config=YON_CONFIG_LOCAL;
    yon_save_proceed("system",YON_CONFIG_LOCAL,config_get_command("system"),NULL);
}

void on_config_global_save(){
    main_config.save_config=YON_CONFIG_GLOBAL;
    yon_save_proceed("global",YON_CONFIG_GLOBAL,config_get_command("global"),NULL);
}

void on_config_custom_save(GtkWidget *self, main_window *widgets){
    if (self&&widgets){}
    main_config.save_config=YON_CONFIG_CUSTOM;
	template_saving_window *window = yon_save_proceed(NULL,YON_CONFIG_CUSTOM,config_get_command("system"),NULL);
	if (window){};
}

void on_save_done(main_window *widgets, config_str output, int size){
	char *final_output = yon_char_parsed_to_string(output,size,"");
	if (final_output){
		printf("%s\n",final_output);
		free(final_output);
	}
	yon_char_parsed_free(output,size);
	yon_interface_update(widgets);
	textdomain(template_ui_LocaleName);
	switch (main_config.save_config){
		case 0:
			yon_ubl_status_box_render(GLOBAL_SAVE_SUCCESS_LABEL,BACKGROUND_IMAGE_SUCCESS_TYPE);
			break;
		case 1:
			yon_ubl_status_box_render(LOCAL_SAVE_SUCCESS_LABEL,BACKGROUND_IMAGE_SUCCESS_TYPE);
			break;
		case 2:
			yon_ubl_status_box_render(GLOBAL_LOCAL_SAVE_SUCCESS_LABEL,BACKGROUND_IMAGE_SUCCESS_TYPE);
            break;
        case 3:
			yon_ubl_status_box_render(SAVE_SUCCESS_LABEL,BACKGROUND_IMAGE_SUCCESS_TYPE);
			break;
	}
	textdomain(LocaleName);
	
}

void yon_interface_update(main_window *widgets){
    g_signal_handlers_block_by_func(G_OBJECT(widgets->NTPEntry),G_CALLBACK(yon_save_parameters),widgets);
    g_signal_handlers_block_by_func(G_OBJECT(widgets->DHCPCombo),G_CALLBACK(yon_save_parameters),widgets);
    g_signal_handlers_block_by_func(G_OBJECT(widgets->TimeSyncTypeCombo),G_CALLBACK(yon_save_parameters),widgets);
    g_signal_handlers_block_by_func(G_OBJECT(widgets->RegionCombo),G_CALLBACK(yon_save_parameters),widgets);
    g_signal_handlers_block_by_func(G_OBJECT(widgets->ZoneCombo),G_CALLBACK(yon_save_parameters),widgets);
    char *zone = config(ZONE_parameter);
    zone = yon_char_new(zone);
    if (!yon_char_is_empty(zone)&&strstr(zone,"/")){
        char *region = yon_char_divide_search(zone,"/",-1);
        g_signal_handlers_block_by_func(G_OBJECT(widgets->RegionCombo),on_region_changed,widgets);
        gtk_combo_box_set_active_id(GTK_COMBO_BOX(widgets->RegionCombo),region);
        on_region_changed(GTK_COMBO_BOX(widgets->RegionCombo),widgets);
        gtk_combo_box_set_active_id(GTK_COMBO_BOX(widgets->ZoneCombo),zone);
        g_signal_handlers_unblock_by_func(G_OBJECT(widgets->RegionCombo),on_region_changed,widgets);
        free(zone);
        free(region);
    }
    char *ntp = config(NTPSERVERS_parameter);
    if (!yon_char_is_empty(ntp)){
            gtk_widget_set_sensitive(widgets->NTPEntry,0);
        if (!strcmp(ntp,"dhcp")){
            gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->DHCPCombo),1);
        } else if (!strcmp(ntp,"default")){
            gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->DHCPCombo),2);
        } else if (!strcmp(ntp,"ntp-ru")){
            gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->DHCPCombo),3);
        } else if (!strcmp(ntp,"no")||!strcmp(ntp,"disable")){
            gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->DHCPCombo),5);
        } else if (!strcmp(ntp,"stop")){
            gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->DHCPCombo),6);
        } else {
            gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->DHCPCombo),4);
            gtk_widget_set_sensitive(widgets->NTPEntry,1);
            gtk_entry_set_text(GTK_ENTRY(widgets->NTPEntry),ntp);
        }
    } else {
        gtk_widget_set_sensitive(widgets->NTPEntry,0);
        gtk_entry_set_text(GTK_ENTRY(widgets->NTPEntry),"");
        gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->DHCPCombo),0);
    }

    char *hwclock_sync = config(HWCLOCK_SYNC_parameter);
    if (!yon_char_is_empty(hwclock_sync)){
        if (!strcmp(hwclock_sync,"utc")){
            gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->TimeSyncTypeCombo),2);
        } else if (!strcmp(hwclock_sync,"localtime")){
            gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->TimeSyncTypeCombo),1);
        } else {
            gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->TimeSyncTypeCombo),0);

        }
    } else {
        gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->TimeSyncTypeCombo),0);
    }

    GTimeZone *tz = g_time_zone_new_identifier(config(ZONE_parameter));
    if (tz){
        GDateTime *datetime = g_date_time_new_now(tz);
        char *time = g_date_time_format(datetime,"%H %M");
        char *format = yon_settings_configuration_get(date_format_parameter);
        char *date = g_date_time_format(datetime,format?format:"%d.%m.%Y");
        gtk_calendar_select_month(GTK_CALENDAR(widgets->DateCalendar),g_date_time_get_month(datetime)-1,g_date_time_get_year(datetime));
        gtk_calendar_select_day(GTK_CALENDAR(widgets->DateCalendar),g_date_time_get_day_of_month(datetime));
        g_date_time_unref(datetime);

        if (!yon_char_is_empty(time)){
            char *hour = yon_char_divide_search(time," ",-1);
            double hours = atof(hour);
            double minutes = atof(time);
            gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->HourSpin),hours);
            gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->MinuteSpin),minutes);
            free(hour);
            free(time);
        } else {
            gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->HourSpin),0.0f);
            gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->MinuteSpin),0.0f);
        }

        if (!yon_char_is_empty(date)){
            gtk_entry_set_text(GTK_ENTRY(widgets->DateEntry),date);
        } else {
            gtk_entry_set_text(GTK_ENTRY(widgets->DateEntry),"");
        }

        g_signal_handlers_unblock_by_func(G_OBJECT(widgets->NTPEntry),G_CALLBACK(yon_save_parameters),widgets);
        g_signal_handlers_unblock_by_func(G_OBJECT(widgets->DHCPCombo),G_CALLBACK(yon_save_parameters),widgets);
        g_signal_handlers_unblock_by_func(G_OBJECT(widgets->TimeSyncTypeCombo),G_CALLBACK(yon_save_parameters),widgets);
        g_signal_handlers_unblock_by_func(G_OBJECT(widgets->RegionCombo),G_CALLBACK(yon_save_parameters),widgets);
        g_signal_handlers_unblock_by_func(G_OBJECT(widgets->ZoneCombo),G_CALLBACK(yon_save_parameters),widgets);
        g_time_zone_unref(tz);
    }
}

void on_date_clicked(GtkWidget *,main_window *widgets){
    gtk_popover_popup(GTK_POPOVER(widgets->DatePopover));
}

void on_region_changed(GtkComboBox *self, main_window *widgets){
    char *active_name = (char*)gtk_combo_box_get_active_id(self);
    char *active = yon_char_append("/usr/share/zoneinfo/",active_name);
    int size;
    gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(widgets->ZoneCombo));
    if (yon_file_is_directory(active)){
        config_str parsed = yon_file_ls(active,&size);
        config_str parsed_sorted = yon_char_parsed_sort(parsed,size);
        yon_char_parsed_free(parsed,size);
        for (int i=0;i<size;i++){
            char *tzone = yon_char_unite(active_name,"/",parsed_sorted[i],NULL);
            GTimeZone *tz = g_time_zone_new_identifier(tzone);
            if (!tz)
                continue;
            g_time_zone_unref(tz);
            char *name_string = NULL;
            char *utc_string = parsed_sorted[i];
            if (strstr(parsed_sorted[i],"GMT")){
                utc_string = yon_char_unite("UTC",parsed_sorted[i]+3," (",parsed_sorted[i],")",NULL);
            } else if (strcmp(active_name,"Etc")){
                char *zonereg = yon_char_unite(active,"/",utc_string,NULL);
                if (g_setenv("TZ",zonereg,1)){
                    time_t curtime = time(NULL);
                    struct tm *local = localtime(&curtime);
                    char *hour_str = yon_char_from_long(local->tm_gmtoff/3600);
                    name_string = yon_char_unite("(UTC ",local->tm_gmtoff>0?"+":"",strlen(hour_str)<2&&local->tm_gmtoff!=0?"0":"",hour_str,") ",_(parsed_sorted[i]),NULL);
                    free(hour_str);
                    free(zonereg);
                }
            }
            gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(widgets->ZoneCombo),parsed_sorted[i],name_string?name_string:_(utc_string));
        }
        if (size) yon_char_parsed_free(parsed_sorted,size);
        gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->ZoneCombo),0);
    }
    free(active);
}

struct datetime_arg {
    char *time;
    const char *date;
};

gboolean on_sync_error(void*){
    yon_ubl_status_box_render(SYNC_ERROR_LABEL,BACKGROUND_IMAGE_FAIL_TYPE);
    return G_SOURCE_REMOVE;
}

void yon_date_tooltip_update(main_window *widgets){
    char *format = yon_settings_configuration_get(date_format_parameter);
    format = format?format:"%d.%m.%Y";
    char *temp = yon_char_replace(format,"%Y",YEAR_FORMAT_LABEL);
    char *month_temp = yon_char_replace(temp,"%m",MONTH_FORMAT_LABEL);
    char *day_temp = yon_char_replace(month_temp,"%d",DAY_FORMAT_LABEL);
    char *tooltip = yon_char_unite(DATE_DORMAT_TOOLTIP_LABEL,": ",day_temp,NULL);
    gtk_widget_set_tooltip_text(widgets->DateEntry,tooltip);
    free(tooltip);
    free(temp);
    free(month_temp);
    free(day_temp);
}

void on_date_format_changed(GtkWidget *, main_window *widgets){
    char *format = yon_settings_configuration_get(date_format_parameter);
    char *format_converted = yon_date_convert_to_pattern(format);
    yon_entry_set_pattern(GTK_ENTRY(widgets->DateEntry),format_converted);
    yon_interface_update(widgets);
    yon_date_tooltip_update(widgets);
}

gboolean on_operation_success(void*){
    yon_ubl_status_box_render(SYNC_SUCCESS_LABEL,BACKGROUND_IMAGE_SUCCESS_TYPE);
    return G_SOURCE_REMOVE;
}

void *yon_sync_thread_start(void *arg){
    struct datetime_arg *data = (struct datetime_arg*)arg;
    char *command_time = time_sync_command(data->time);
    char *command_date = date_sync_command(data->date);
    char *command = yon_char_unite(command_date,"; ",command_time,NULL);
    free(command_time);
    free(command_date);
    if (system(yon_debug_output("%s\n",command))){
        gdk_threads_add_idle((GSourceFunc)on_sync_error,NULL);
    } else {
        gdk_threads_add_idle((GSourceFunc)on_operation_success,NULL);
    }
    pthread_exit(NULL);
}

void on_sync_clicked(GtkWidget *, main_window *widgets){
    char *hour = yon_char_from_long((long)gtk_spin_button_get_value(GTK_SPIN_BUTTON(widgets->HourSpin)));
    char *minute = yon_char_from_long((long)gtk_spin_button_get_value(GTK_SPIN_BUTTON(widgets->MinuteSpin)));
    GTimeZone *tz = g_time_zone_new_identifier(config(ZONE_parameter));
    GDateTime *datetime = g_date_time_new_now(tz);
    char *second = g_date_time_format(datetime, "%S");
    char *time = yon_char_unite(hour,":",minute,":",second,NULL);
    g_date_time_unref(datetime);
    g_time_zone_unref(tz);

    const char *date = gtk_entry_get_text(GTK_ENTRY(widgets->DateEntry));

    struct datetime_arg *data = malloc(sizeof(struct datetime_arg));
    data->date=NULL;
    data->time=time;
    if (!yon_char_is_empty(date)){
        int size;
        char *format = yon_settings_configuration_get(date_format_parameter);
        format = format?format:"%d.%m.%Y";
        config_str parsed = yon_char_parse((char*)date,&size,!strcmp(format,"%d.%m.%Y")?".":!strcmp(format,"%d/%m/%Y")?"/":"-");
        if (!strcmp(format,"%m-%d-%Y")){
            char *year = parsed[2];
            char *month = parsed[0];
            char *day = parsed[1];
            parsed[0]=year;
            parsed[1]=month;
            parsed[2]=day;
        } else {
            char *year = parsed[2];
            char *month = parsed[1];
            char *day = parsed[0];
            parsed[0]=year;
            parsed[1]=month;
            parsed[2]=day;
        }
        data->date=yon_char_parsed_to_string(parsed,size,"");
        yon_char_parsed_free(parsed,size);
    }
    free(hour);
    free(minute);
    free(second);

    pthread_t tid;
    pthread_attr_t attr;
    pthread_attr_init(&attr); 
    pthread_create(&tid,&attr,yon_sync_thread_start,data);

}

void on_ntp_sync(GtkWidget *, main_window *widgets){
    int mode = gtk_combo_box_get_active(GTK_COMBO_BOX(widgets->DHCPCombo));
            gtk_widget_set_sensitive(widgets->NTPEntry,0);
    switch(mode){
        case 0:
            if (main_config.ntp_default){
                // gtk_entry_set_text(GTK_ENTRY(widgets->NTPEntry),"");
                gtk_entry_set_placeholder_text(GTK_ENTRY(widgets->NTPEntry),main_config.ntp_default);
            }
            break;
        case 2:{
            if (!getuid()){
                int size;
                config_str parsed = yon_config_load(get_ntp_default_command,&size);
                if (size&&!yon_char_is_empty(parsed[0])&&strcmp(parsed[0],"(null)\n")){
                    free(yon_char_divide_search(parsed[0],"=",-1));
                    yon_char_remove_last_symbol(parsed[0],'\n');
                    yon_char_remove_brackets(parsed[0]);
                    gtk_entry_set_placeholder_text(GTK_ENTRY(widgets->NTPEntry),parsed[0]);
                    yon_char_parsed_free(parsed,size);
                    // gtk_entry_set_text(GTK_ENTRY(widgets->NTPEntry),"");
                }
            }
        }
            break;
        case 3:{
            if (!getuid()){
                int size;
                config_str parsed = yon_config_load(get_ntp_ru_command,&size);
                if (size&&!yon_char_is_empty(parsed[0])&&strcmp(parsed[0],"(null)\n")){
                    free(yon_char_divide_search(parsed[0],"=",-1));
                    yon_char_remove_last_symbol(parsed[0],'\n');
                    yon_char_remove_brackets(parsed[0]);
                    gtk_entry_set_placeholder_text(GTK_ENTRY(widgets->NTPEntry),parsed[0]);
                    yon_char_parsed_free(parsed,size);
                    // gtk_entry_set_text(GTK_ENTRY(widgets->NTPEntry),"");
                }
            }
        }
            break;
        case 1:
                gtk_entry_set_placeholder_text(GTK_ENTRY(widgets->NTPEntry),"DHCP");
                gtk_entry_set_text(GTK_ENTRY(widgets->NTPEntry),"");
            break;
        case 5:
                gtk_entry_set_placeholder_text(GTK_ENTRY(widgets->NTPEntry),"");
                // gtk_entry_set_text(GTK_ENTRY(widgets->NTPEntry),"");
            break;
        case 4:
            gtk_widget_set_sensitive(widgets->NTPEntry,1);
                gtk_entry_set_placeholder_text(GTK_ENTRY(widgets->NTPEntry),"");
                // gtk_entry_set_text(GTK_ENTRY(widgets->NTPEntry),"");
            break;
    }
}

gboolean on_hardware_operation_success(void*){
    yon_ubl_status_box_render(SYNC_HARDWARE_SUCCESS_LABEL,BACKGROUND_IMAGE_SUCCESS_TYPE);
    return G_SOURCE_REMOVE;
}

void *yon_sync_hardware_thread_start(void*){
    if (system(hardware_datetime_sync_command)){
        g_idle_add((GSourceFunc)on_sync_error,NULL);
    } else {
        g_idle_add((GSourceFunc)on_hardware_operation_success,NULL);
    }
    pthread_exit(NULL);
}

void on_sync_hardware_clicked(){
    pthread_t tid;
    pthread_attr_t attr;
    pthread_attr_init(&attr); 
    pthread_create(&tid,&attr,yon_sync_hardware_thread_start,NULL);
}

// standard functions

void on_date_accept(GtkWidget *,main_window *widgets){
    guint year=0, month=0, day=0;
    gtk_calendar_get_date(GTK_CALENDAR(widgets->DateCalendar),&year,&month,&day);
    GTimeZone *tz = g_time_zone_new_identifier(config(ZONE_parameter));
    GDateTime *datetime = g_date_time_new(tz,year,++month,day,0,0,0);
    char *format = yon_settings_configuration_get(date_format_parameter);
    char *date = g_date_time_format(datetime,format?format:"%d.%m.%Y");
    gtk_entry_set_text(GTK_ENTRY(widgets->DateEntry),date);
    gtk_popover_popdown(GTK_POPOVER(widgets->DatePopover));
    free(date);
    g_date_time_unref(datetime);
    g_time_zone_unref(tz);
}

void on_date_cancel(GtkWidget *, main_window *widgets){
    gtk_popover_popdown(GTK_POPOVER(widgets->DatePopover));
}

/**config_init() 
 * [EN] 
 *  
 * [RU] 
 * Функция инициализации всех параметров конфигурации 
*/ 
void config_init(){ 
    main_config.always_open_documentation=0; 
    main_config.socket_id=-1; 
    main_config.save_socket_id=-1; 
    main_config.load_socket_id=-1; 
    main_config.lock_help=0; 
    main_config.lock_help=0; 
    main_config.lock_load_global=0; 
    main_config.lock_save_global=0; 
    main_config.lock_save_local=0; 
    main_config.load_mode=1;
    main_config.ntp_default = NULL;

    char *ntp_command = yon_config_parameter_prepare_command(NTPSERVERS_parameter_raw_command,"default",NULL,NULL);
    if (!getuid()){
        int size;
        config_str parsed = yon_config_load(ntp_command,&size);
        if (size>0){
            if (strcmp(parsed[0],"(null)\n")){
                yon_char_remove_last_symbol(parsed[0],'\n');
                if (strstr(parsed[0],"[")&&strstr(parsed[0],"]"))
                    main_config.ntp_default = strstr(parsed[0],"] ")+2;
                else 
                    main_config.ntp_default = parsed[0];
            }
        }
    }
}

void yon_date_chooser_save_accept(GtkWidget *root){
    struct yon_date_chooser_option *parameter = g_object_get_data(G_OBJECT(root),"data_struct");
    char *path = (char*)gtk_combo_box_get_active_id(GTK_COMBO_BOX(parameter->DateCombo));
    if (!yon_char_is_empty(path)){
        yon_window_config_add_instant_parameter(date_format_parameter,yon_configuration_window_section,path,YON_TYPE_STRING);
    } else {
        yon_window_config_erase_instant_parameter(date_format_parameter,yon_configuration_window_section);
    }
    on_date_format_changed(NULL,main_config.widgets);
}

char *yon_date_convert_to_pattern(const char *date_string){
    if (yon_char_is_empty(date_string)) date_string = "%d.%m.%Y";
    char *temp = yon_char_replace_valist(date_string,"%d","\\d\\d","%m","\\d\\d","%Y","\\d{1,4}",".","\\.",NULL);
    char *date_copy = yon_char_unite("^",temp,NULL);
    free(temp);
    return date_copy;
}

/**yon_main_window_complete(main_window *widgets) 
 * [EN] 
 *  
 * [RU] 
 * Функция настройки основного окна приложения. [widgets] - структура со стандартным интерфейсом. 
*/ 
void yon_main_window_complete(main_window **window){ 
    
    main_window *widgets = yon_remalloc(*window,sizeof(main_window)); 
    (*window) = widgets;
    GtkBuilder *builder = gtk_builder_new_from_resource(glade_path); 
    gtk_box_pack_start(GTK_BOX(widgets->InterfaceBox),yon_gtk_builder_get_widget(builder,"BoxMain"),1,1,0); 

    // Custom widgets configuration 
    {
        widgets->HourSpin = yon_gtk_builder_get_widget(builder,"HourSpin");
        widgets->MinuteSpin = yon_gtk_builder_get_widget(builder,"MinuteSpin");
        widgets->DateEntry = yon_gtk_builder_get_widget(builder,"DateEntry");
        widgets->DateButton = yon_gtk_builder_get_widget(builder,"DateButton");
        widgets->SyncButton = yon_gtk_builder_get_widget(builder,"SyncButton");
        widgets->SyncHardwareButton = yon_gtk_builder_get_widget(builder,"SyncHardwareButton");
        widgets->DHCPCombo = yon_gtk_builder_get_widget(builder,"DHCPCombo");
        widgets->NTPEntry = yon_gtk_builder_get_widget(builder,"NTPEntry");
        widgets->TimeSyncTypeCombo = yon_gtk_builder_get_widget(builder,"TimeSyncTypeCombo");
        widgets->RegionCombo = yon_gtk_builder_get_widget(builder,"RegionCombo");
        widgets->ZoneCombo = yon_gtk_builder_get_widget(builder,"ZoneCombo");
        widgets->DatePopover = yon_gtk_builder_get_widget(builder,"DatePopover");
        widgets->DateCalendar = yon_gtk_builder_get_widget(builder,"DateCalendar");
        widgets->DateCancelButton = yon_gtk_builder_get_widget(builder,"DateCancelButton");
        widgets->DateAcceptButton = yon_gtk_builder_get_widget(builder,"DateAcceptButton");
        widgets->zone_list = GTK_LIST_STORE(gtk_builder_get_object(builder,"liststore1"));
    }
    main_config.widgets=widgets;
    // Signal configuration
    {
        g_signal_connect(G_OBJECT(widgets->SaveMenuItem),"activate",G_CALLBACK(on_config_global_local_save),widgets);
        g_signal_connect(G_OBJECT(widgets->SaveGlobalMenuItem),"activate",G_CALLBACK(on_config_global_save),widgets);
        g_signal_connect(G_OBJECT(widgets->SaveLocalMenuItem),"activate",G_CALLBACK(on_config_local_save),widgets);
        g_signal_connect(G_OBJECT(widgets->SaveCustomMenuItem),"activate",G_CALLBACK(on_config_custom_save),widgets);

        g_signal_connect(G_OBJECT(widgets->LoadGlobalMenuItem),"activate",G_CALLBACK(on_config_global_load),widgets);
        g_signal_connect(G_OBJECT(widgets->LoadLocalMenuItem),"activate",G_CALLBACK(on_config_local_load),widgets);
        g_signal_connect(G_OBJECT(widgets->LoadCustomMenuItem),"activate",G_CALLBACK(on_config_custom_load),widgets);
        
        g_signal_connect(G_OBJECT(widgets->DHCPCombo),"changed",G_CALLBACK(on_ntp_sync),widgets);
        g_signal_connect(G_OBJECT(widgets->SyncButton),"clicked",G_CALLBACK(on_sync_clicked),widgets);
        g_signal_connect(G_OBJECT(widgets->SyncHardwareButton),"clicked",G_CALLBACK(on_sync_hardware_clicked),widgets);
        g_signal_connect(G_OBJECT(widgets->RegionCombo),"changed",G_CALLBACK(on_region_changed),widgets);

        g_signal_connect(G_OBJECT(widgets->DateButton),"clicked",G_CALLBACK(on_date_clicked),widgets);
        g_signal_connect(G_OBJECT(widgets->DateCancelButton),"clicked",G_CALLBACK(on_date_cancel),widgets);
        g_signal_connect(G_OBJECT(widgets->DateAcceptButton),"clicked",G_CALLBACK(on_date_accept),widgets);
        g_signal_connect(G_OBJECT(widgets->DHCPCombo),"changed",G_CALLBACK(yon_save_parameters),widgets);
        g_signal_connect(G_OBJECT(widgets->NTPEntry),"changed",G_CALLBACK(yon_save_parameters),widgets);
        g_signal_connect(G_OBJECT(widgets->TimeSyncTypeCombo),"changed",G_CALLBACK(yon_save_parameters),widgets);
        g_signal_connect(G_OBJECT(widgets->RegionCombo),"changed",G_CALLBACK(yon_save_parameters),widgets);
        g_signal_connect(G_OBJECT(widgets->ZoneCombo),"changed",G_CALLBACK(yon_save_parameters),widgets);
    }
    // Initial data loading
    char *ntp_default = NULL;
    char *time_sync_default = NULL;
    {
        {
            
            if (!yon_char_is_empty(main_config.ntp_default)){
                if (!strcmp(main_config.ntp_default,"dhcp")){
                    ntp_default = DHCP_LABEL;
                } else if (!strcmp(main_config.ntp_default,"default")){
                    ntp_default = NTP_LABEL;

                } else if (!strcmp(main_config.ntp_default,"ntp-ru")){
                    ntp_default = NTp_RU_LABEL;

                } else if (!strcmp(main_config.ntp_default,"disable")){
                    ntp_default = STOPPED_LABEL;
                } else if(!strcmp(main_config.ntp_default,"stop")) {
                    ntp_default = DISABLED_LABEL;
                } else {
                    ntp_default = yon_char_new(main_config.ntp_default);
                }
            }
        }
        if (!getuid()){
            int size;
            config_str parsed = yon_config_load(HWCLOCK_SYNC_parameter_command,&size);
            if (size&&!yon_char_is_empty(parsed[0])&&strcmp(parsed[0],"(null)\n")){
                yon_char_remove_last_symbol(parsed[0],'\n');
                free(yon_char_divide_search(parsed[0],"=",-1));
                if (!strcmp(parsed[0],"utc")){
                    time_sync_default = UTC_LABEL;
                } else if (!strcmp(parsed[0],"localtime")){
                    time_sync_default = LOCAL_TIME_LABEL;
                } else {
                    

                }
            }
        }
        gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(widgets->DHCPCombo),DEFAULT_CUSTOM_LABEL(ntp_default));
        gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(widgets->TimeSyncTypeCombo),DEFAULT_CUSTOM_LABEL(time_sync_default));

        int size;
        config_str parsed = yon_file_ls(zone_path,&size);
        config_str sorted = yon_char_parsed_sort(parsed,size);
        config_str localized = yon_char_parsed_localize(sorted,size);
        for (int i=0;i<size;i++){
            if (!strstr(sorted[i],".")&&strcmp(sorted[i],"posix")&&strcmp(sorted[i],"right")){
                char *path = yon_char_append(zone_path,sorted[i]);
                if (yon_file_is_directory(path)){
                    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(widgets->RegionCombo),sorted[i],(localized[i]));
                }
                free(path);
            }
        }
        if (size) yon_char_parsed_free(parsed,size);
        gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->RegionCombo),0);
    }

    gtk_window_resize(GTK_WINDOW(widgets->Window),100,150);
    while(gtk_events_pending()) gtk_main_iteration();
    yon_window_config_setup(GTK_WINDOW(widgets->Window));
    char *path = yon_char_unite(yon_ubl_user_get_home_directory(),"/.config/",LocaleName,"/",LocaleName,".conf",NULL);
    yon_window_config_load(path);

        yon_ubl_settings_window_init(GTK_MENU(gtk_widget_get_parent(widgets->DocumentationMenuItem)));
        GList *menu_items = gtk_container_get_children(GTK_CONTAINER(gtk_widget_get_parent(widgets->DocumentationMenuItem)));
        for (guint i=0;i<g_list_length(menu_items);i++){
            if (i==0){
                gtk_style_context_remove_class(gtk_widget_get_style_context((GtkWidget*)g_list_nth_data(menu_items,i)),"menuitembottom");
                gtk_style_context_remove_class(gtk_widget_get_style_context((GtkWidget*)g_list_nth_data(menu_items,i)),"menuitemmiddle");
                gtk_style_context_add_class(gtk_widget_get_style_context((GtkWidget*)g_list_nth_data(menu_items,i)),"menuitemtop");
            } else if (i==g_list_length(menu_items)-1){
                gtk_style_context_remove_class(gtk_widget_get_style_context((GtkWidget*)g_list_nth_data(menu_items,i)),"menuitemmiddle");
                gtk_style_context_remove_class(gtk_widget_get_style_context((GtkWidget*)g_list_nth_data(menu_items,i)),"menuitemtop");
                gtk_style_context_add_class(gtk_widget_get_style_context((GtkWidget*)g_list_nth_data(menu_items,i)),"menuitembottom");
            } else {
                gtk_style_context_remove_class(gtk_widget_get_style_context((GtkWidget*)g_list_nth_data(menu_items,i)),"menuitembottom");
                gtk_style_context_remove_class(gtk_widget_get_style_context((GtkWidget*)g_list_nth_data(menu_items,i)),"menuitemtop");
                gtk_style_context_add_class(gtk_widget_get_style_context((GtkWidget*)g_list_nth_data(menu_items,i)),"menuitemmiddle");
            }
        }
        g_list_free(menu_items);
		struct yon_configuration_window_custom_parameter *parameter = malloc(sizeof(struct yon_configuration_window_custom_parameter));
		parameter->custom_parameter_create_func = yon_date_chooser_new;
		parameter->custom_parameter_save_value_func = yon_date_chooser_save_accept;
		parameter->custom_parameter_update_func = yon_date_chooser_update;
		yon_configuration_window_add_custom_parameter(date_format_parameter,parameter);
        char *format = yon_settings_configuration_get(date_format_parameter);
        char *format_converted = yon_date_convert_to_pattern(format);
        yon_entry_set_pattern(GTK_ENTRY(widgets->DateEntry),format_converted);
        // yon_configuration_window_add_combo_box_parameter(CONFIGURATION_PARAMETER_BOOL,date_format_parameter,DATE_FORMAT_SETTINGS_LABEL,G_CALLBACK(on_date_format_changed),widgets,"%d.%m.%Y",DMY_FORMAT_LABEL,"%d-%m-%Y",DMY_MINUS_FORMAT_LABEL,"%d/%m/%Y",DMY_SLASH_FORMAT_LABEL,"%m-%d-%Y",MDY_FORMAT_LABEL,NULL);

    yon_load_proceed(YON_CONFIG_LOCAL);
    yon_interface_update(widgets);
	yon_save_window_set_postsave_function(on_save_done,widgets);
    yon_date_tooltip_update(widgets);
}

int main(int argc, char *argv[]){
    setlocale(LC_ALL, "");
    textdomain (LocaleName);
    config_init();
    
    yon_ubl_connect_config((_template_config*)&main_config); 
    yon_ubl_window_init(TITLE_LABEL,TITLE_INFO_LABEL,LocaleName,CssPath,LocaleName,version_application,WIKI_LINK);
	config_str unfound = NULL;
	int size=0;
	yon_ubl_setup_arguments(argc,argv,&unfound,&size,NULL);
    gtk_init(&argc,&argv);
    template_main_window *widgets = yon_ubl_window_setup(); 
    yon_root_button_setup((template_main_window*)widgets,argv,argc);
    yon_main_window_complete((main_window**)&widgets);
    if (getuid()!=0){
        yon_ubl_status_box_render(yon_char_get_localised_from_lib(ROOT_WARNING_LABEL),BACKGROUND_IMAGE_FAIL_TYPE);
    }
    gtk_main();
    return 0;
}