#ifndef UBL_UTILS_GTK3
#define UBL_UTILS_GTK3
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gtk/gtkx.h>
#include <libintl.h>
#include <libublsettings.h>

#define _(String) gettext(String)

#ifdef __GTK_H__
#ifdef VTE_INCLUDE
#include <vte/vte.h>
/**
 * void yon_terminal_integrated_launch(GtkWidget *place_to_show, void *endwork_function, void* endwork_function_argument)
 * [EN]
 * launches terminal with specific [command],
 * terminal is shown in [place_to_show] container,
 * after terminal done its work [endwork_function] is called with [endwork_function_argument] argument.
 * [RU]
 * Запускает терминал с командой [command],
 * терминал добавляется в контейнер [place_to_show] виджета,
 * после завершения работы терминала вызывается функция [endwork_function] с аргументом [endwork_function_argument].
*/
void yon_terminal_integrated_launch(GtkWidget *place_to_show, char* command, void *endwork_function, void* endwork_function_argument);

/**yon_terminal_integrated_start(GtkWidget *terminal, char* command)
 * [EN]
 * launches terminal with specific [command],
 * terminal is shown in [place_to_show] container.
 * [RU]
 * Запускает терминал с командой [command].
*/
void yon_terminal_integrated_start(GtkWidget *terminal, char* command);

/**yon_terminal_integrated_start_shell(GtkWidget *terminal, char* command, void *endwork_function, void* endwork_function_argument)
 * [EN]
 * launches terminal with shell and executes specific [command],
 * terminal is shown in [place_to_show] container,
 * after terminal done its work [endwork_function] is called with [endwork_function_argument] argument.
 * [RU]
 * Запускает терминал оболочкой для выполнения команды [command],
 * после завершения работы терминала вызывается функция [endwork_function] с аргументом [endwork_function_argument].
*/
void yon_terminal_integrated_start_shell(GtkWidget *terminal, char* command, void *endwork_function, void* endwork_function_argument);

    typedef struct{
        GtkWidget *window;
        GtkWidget *header;
        GtkWidget *terminal;
        GtkWidget *StatusBox;
        GtkWidget *box;
        GtkWidget *terminal_box;
        GtkWidget *scroll;
        char *success_label;
        char *fail_label;
    } terminal_window_struct;

terminal_window_struct *yon_terminal_window_launch(GtkWindow *parent_window, char *command, char *success_label,char *fail_label);
void yon_terminal_window_launch_shell(GtkWindow *parent_window, char *command, char *success_label,char *fail_label);

void yon_terminal_window_update_button_launch(GtkWindow *parent_window, char *command, char *success_label,char *fail_label);

#endif

#define for_iter(model,iter) for(int valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model),iter);valid;valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model),iter))

/**yon_gtk_widget_set_scroll_window_for_scroll(GtkWidget *target, GtkScrollbar *scroll)
 * [EN]
 * 
 * [RU]
 * Устанавливает для виджета [target] прокрутку скролла [scroll]
*/
void yon_gtk_widget_set_scroll_window_for_scroll(GtkWidget *target, GtkScrollbar *scroll);

/**YON_TYPE
 * [EN]
 * 
 * [RU]
 * Типы, поддерживаемые функциями сохранения/загрузки конфигурации утилиты
*/
enum YON_TYPE{
    YON_TYPE_STRING,
    YON_TYPE_STRING_LIST,
    YON_TYPE_INT,
    YON_TYPE_BOOLEAN,
    YON_TYPE_OTHER};

/**yon_gtk_builder_get_widget(builder, widget_name)
 * [EN]
 * Returns GtkWidget from GtkBuilder *[builder].
 * [builder] is GtkBuilder*;
 * [widget_name] is id of widget;
 * [RU]
 * Возвращает виджет GtkWidget c id [widget_name] из [builder]
*/
#define yon_gtk_builder_get_widget(builder, widget_name) GTK_WIDGET(gtk_builder_get_object(builder, widget_name))

void yon_window_config_save_instant();

int yon_window_config_check_init();

/**yon_window_config_setup(GtkWindow *window)
 * [EN]
 * 
 * [RU]
 * Устанавливает указатель на окно для отслеживания его положения и размера
*/
void yon_window_config_setup(GtkWindow *window);

/**yon_window_config_load(char *path)
 * [EN]
 * 
 * [RU]
 * Загружает конфиг окна и инициализирует отслеживание его параметров
*/
int yon_window_config_load(char *path);

/**yon_window_config_get_section(char *section, gsize *size)
 * [EN]
 * 
 * [RU]
 * Возвращает все параметры раздела [section] конфига утилиты и записывает в [size] количество считанных параметров.
*/
config_str yon_window_config_get_section(char *section, gsize *size);

/**yon_window_config_add_custom_parameter(GtkWidget *widget, char *param_name, char *widget_property)
 * [EN]
 * 
 * [RU]
 * Добавляет параметр виджета [widget] по названию [widget_property] для отслеживания и сохраняет его в конфиг под ключом [param_name].
*/
void yon_window_config_add_listener(GtkWidget *widget, char *param_name, char *widget_property, enum YON_TYPE val_type);

/**yon_window_config_add_custom_parameter(char *param_name, char *section, void *tracked_value, enum YON_TYPE val_type)
 * [EN]
 * 
 * [RU]
 * Добавить параметр в конфиг утилиты.
 * Параметр [param_name] добавляется в раздел [section] конфига утилиты со значением [tracked value].
 * Тип указывается в [type]
*/
__attribute__((__deprecated__)) void yon_window_config_add_custom_parameter(char *param_name, char *section, void *tracked_value, enum YON_TYPE val_type);

void yon_window_config_add_instant_parameter(char *param_name, char *section, void *tracked_value, enum YON_TYPE val_type);

/**yon_window_config_erase_custom_parameter(char *param_name, char *section)
 * [EN]
 * 
 * [RU]
 * Удаляет параметр из конфига утилиты.
 * Удаляет параметр [param_name] из раздела [section] конфига утилиты.
*/
void yon_window_config_erase_custom_parameter(char *param_name, char *section);

void yon_window_config_erase_instant_parameter(char *param_name, char *section);

/**yon_window_config_get_parameter(char *section, char *config_parameter, void *return_value, enum YON_TYPE type)
 * [EN]
 * 
 * [RU]
 * Возвращает параметр из конфига утилиты.
 * Параметр [config_parameter] из раздела [section] возвращается в [return_value]
 * Возвращаемый тип указывается в [type]
*/
int yon_window_config_get_parameter(char *section, char *config_parameter, void *return_value, enum YON_TYPE type);

/**yon_window_config_custom_window_setup(GtkWindow *window, char *window_name)
 * [EN]
 * 
 * [RU]
 * Зарегистрировать окно [window] в конфиге утилиты под именем [window_name]
*/
void yon_window_config_custom_window_setup(GtkWindow *window, char *window_name);

/**yon_window_config_custom_window_set(GtkWindow *window, char *window_name)
 * [EN]
 * 
 * [RU]
 * Загрузить и применить параметры окна [window], сохранёнными в конфигурации утилиты под именем [window_name]
*/
void yon_window_config_custom_window_get(GtkWindow *window, char *window_name);

/**yon_window_config_custom_window_set(GtkWindow *window, char *window_name)
 * [EN]
 * 
 * [RU]
 * Сохранить параметры окна [window] в конфигурацию утилиты под именем [window_name]
*/
void yon_window_config_custom_window_set(GtkWindow *window, char *window_name);

int yon_window_config_check_exist(char *section, char *parameter);

int yon_gtk_icon_view_hide_empty(dictionary *icon_view_segment);

/**on_subwindow_close(GtkWidget *self)
 * [EN]
 * Closes window in which [self] is contained.
 * [RU]
 * Закрывает окно, в котором расположен виджет [self].
*/
void on_subwindow_close(GtkWidget *self);

int yon_gtk_window_setup(GtkWindow *window, GtkWindow *transistent_window, char *title, char *icon_name, char *window_id);

/**yon_ubl_menu_item_documentation_new(char *buttonname)
 * [EN]
 * 
 * [RU]
 * Создаёт  элемент меню GtkMenu с текстом [buttonname]. Кнопка настроена для отображения диалогового окна информации об утилите
*/
GtkWidget *yon_ubl_menu_item_about_new(char *buttonname);

/**yon_ubl_menu_item_documentation_new(char *buttonname)
 * [EN]
 * 
 * [RU]
 * Создаёт  элемент меню GtkMenu с текстом [buttonname]. Кнопка настроена для отображения диалогового окна подтверждения перехода на страницу wiki
*/
GtkWidget *yon_ubl_menu_item_documentation_new(char *buttonname);

// other Gtk functions

/**yon_gtk_combo_box_fill(GtkWidget *combo, config_str parameters,int size)
 * [EN]
 * 
 * [RU]
 * Добавляет в Комбобокс [combo] все строки из массива строк [parameters] размера [size]
*/
int yon_gtk_combo_box_fill(GtkWidget *combo, char **parameters,int size);

/**yon_gtk_combo_box_text_find(GtkWidget *combo_box, char *text_to_find)
 * [EN]
 * 
 * [RU]
 * Проивзодит поиск по GtkComboBoxText [combo_box]
 * возвращает 1 если элемент [text_to_find] найден, иначе возвращает 0 
*/
int yon_gtk_combo_box_text_find(GtkWidget *combo_box, char *text_to_find);

void yon_gtk_tree_view_column_minimal_fixed_size_set(GtkTreeViewColumn *column);

/**yon_gtk_tree_view_minimal_fixed_size_set_full(GtkTreeView *tree)
 * [EN]
 * 
 * [RU]
 * Установить минимальный размер таблицы [tree] равным размеру заголовка.
*/
void yon_gtk_tree_view_minimal_fixed_size_set_full(GtkTreeView *tree);

void yon_gtk_tree_view_set_(GtkTreeView *top,GtkTreeView *resizing, ...);

/**yon_dictionary_gtk_pack_start_multiple_widgets(GtkBox *destination, gboolean expand, gboolean fill, int padding, ...)
 * [EN]
 * 
 * [RU]
 * Добвляет [destination] все виджеты, прописанные после [padding]. Добавление происходит с начала контейнера.
 * [expand] - расширяемость выделенного для виджетов места
 * [fill] - заполнять ли виджетом всё ему выделенное место 
 * [padding] - отступ од других элементов
*/
int yon_dictionary_gtk_pack_start_multiple_widgets(GtkBox *destination, gboolean expand, gboolean fill, int padding, ...);

/**yon_dictionary_gtk_pack_end_multiple_widgets(GtkBox *destination, gboolean expand, gboolean fill, int padding, ...)
 * [EN]
 * 
 * [RU]
 * Добвляет в [destination] все виджеты, прописанные после [padding]. Добавление происходит с конца контейнера.
 * [expand] - расширяемость выделенного для виджетов места
 * [fill] - заполнять ли виджетом всё ему выделенное место 
 * [padding] - отступ од других элементов
*/
int yon_dictionary_gtk_pack_end_multiple_widgets(GtkBox *destination, gboolean expand, gboolean fill, int padding, ...);

int yon_gtk_list_store_find_text(GtkListStore *list, GtkTreeIter *iter, int seek_column, char *value);

void yon_cell_renderer_toggle_set_toggle(GtkCellRendererToggle *target,GtkWidget *tree);

void yon_gtk_toggle_button_set_inactive_from_toggle(GtkToggleButton *self, GtkToggleButton *target);

void yon_gtk_toggle_button_set_inactive_from_entry(GtkEntry *self, GtkToggleButton *target);

void yon_gtk_toggle_button_set_inactive_from_combo_box(GtkComboBox *self, GtkToggleButton *target);

/**yon_gtk_widget_set_sensitive_from_toggle_button(GtkToggleButton *toggle, GtkWidget *target)
 * [EN]
 * 
 * [RU]
 * Выставляет чуствительность виджета [target] в зависимости от состояния комбобокса [toggle].
 * Чувствительность виджета [target] повторяет статус чекбоска.
*/
void yon_gtk_widget_set_sensitive_from_toggle_button(GtkToggleButton *toggle, GtkWidget *target);

/**yon_gtk_widget_set_sensitive_from_toggle_button_inversed(GtkToggleButton *toggle, GtkWidget *target)
 * [EN]
 * 
 * [RU]
 * Выставляет чуствительность виджета [target] в зависимости от состояния чекбоска [toggle].
 * Если чекбокс вктивен, [target] становится нечувствительным и наоборот.
*/
void yon_gtk_widget_set_sensitive_from_toggle_button_inversed(GtkToggleButton *toggle, GtkWidget *target);

void yon_gtk_widget_set_sensitive_from_switch(GtkSwitch *toggle, int status, GtkWidget *target);
void yon_gtk_widget_set_sensitive_from_switch_inversed(GtkSwitch *toggle, int status, GtkWidget *target);

/**yon_gtk_widget_set_sensitive_from_combo_box(GtkComboBox *toggle, GtkWidget *target);
 * [EN]
 * 
 * [RU]
 * Выставляет чуствительность виджета [target] в зависимости от состояния комбобокса [toggle].
 * Если выбран первый элемент списка, [target] становится чувствительным, любое другое значение сделает его нечувствительным.
*/
void yon_gtk_widget_set_sensitive_from_combo_box(GtkComboBox *toggle, GtkWidget *target);

/**yon_gtk_widget_set_sensitive_from_combo_box_inversed(GtkComboBox *toggle, GtkWidget *target);
 * [EN]
 * 
 * [RU]
 * Выставляет чуствительность виджета [target] в зависимости от состояния комбобокса [toggle].
 * Если выбран первый элемент списка, [target] становится нечувствительным, любое другое значение сделает его чувствительным.
*/
void yon_gtk_widget_set_sensitive_from_combo_box_inversed(GtkComboBox *toggle, GtkWidget *target);

/**yon_gtk_toggle_button_set_inactive_from_toggle_button_inversed(GtkToggleButton *self, GtkToggleButton *target)
 * [EN]
 * 
 * [RU]
 * Выставляет активность переключателя [target] на 0 когда переключатель [self] не равен 0.
*/
void yon_gtk_toggle_button_set_inactive_from_toggle_button_inversed(GtkToggleButton *self, GtkToggleButton *target);


/**yon_gtk_toggle_button_set_inactive_from_toggle_button(GtkToggleButton *self, GtkToggleButton *target)
 * [EN]
 * 
 * [RU]
 * Выставляет активность переключателя [target] на 0 когда переключатель [self] сам равен 0.
*/
void yon_gtk_toggle_button_set_inactive_from_toggle_button(GtkToggleButton *self, GtkToggleButton *target);


int yon_gtk_tree_view_set_fixed_size(GtkTreeView *target, ...);

void yon_tree_model_sort_filter_get_child_iter(GtkTreeModelSort *target, GtkTreeIter *iter, GtkTreeIter *converted_iter);

void yon_tree_model_sort_filter_get_model_iter(GtkTreeModelSort *target, GtkTreeIter *iter, GtkTreeIter *converted_iter);

//status section
typedef enum
{
    BACKGROUND_IMAGE_INFO_TYPE,
    BACKGROUND_IMAGE_SUCCESS_TYPE,
    BACKGROUND_IMAGE_FAIL_TYPE
} BACKGROUND_IMAGE_TYPE;

typedef struct {
    BACKGROUND_IMAGE_TYPE type;
    GtkWidget *icon;
    GtkWidget *box;
    GtkWidget *label;
    char* text_to_render;
} render_data;


/**yon_ubl_status_box_setup(render,icon,box,label)
 * [EN]
 * Sets up [render] structure of type render_data.
 * [icon] is GtkImage widget of status box for showing status icons;
 * [box] is GtkBox widget of status box for showing status color;
 * [label] is GtkLabel widget of status box for showing status text;
 * [RU]
 * Настраивает структуру [render] типа render_data.
 * [icon] - виджет типа GtkIcon в котором будут отображаться статусные иконки;
 * [box] - виджет типа GtkBox в котором будет отображаться цвет статуса;
 * [label] - виджет типа GtkLabel в котором будет отображаться текст статусного сообщения;
*/
int yon_ubl_status_box_setup(GtkWidget *icon, GtkWidget *box, GtkWidget *label);

int yon_status_box_is_set();

/**yon_ubl_status_box_render(render,text,type)
 * [EN]
 * Renders message in status box;
 * [render] is render_data structure of status box;
 * [text] is text to be shown in status box;
 * [type] if type of message. Can be BACKGROUND_IMAGE_FAIL_TYPE or BACKGROUND_IMAGE_SUCCESS_TYPE
 * [RU]
 * Отображает сообщение в статусном окне.
 * [render] - структура типа render_data для нужного статусного окна;
 * [text] - текст, отображаемый в статусном окне;
 * [type] - тип сообщения. Может быть:
 * BACKGROUND_IMAGE_FAIL_TYPE (красный фон,иконка - восклицательный знак)
 * или
 * BACKGROUND_IMAGE_SUCCESS_TYPE (Жёлтный фон, иконка - галка)
*/
void yon_ubl_status_box_render(char *text, BACKGROUND_IMAGE_TYPE type);

void yon_ubl_status_box_block_input(int seconds);

/**yon_ubl_status_box_render_thread(render,text,type)
 * [EN]
 * Renders message in status box. It is safe to use outside of interface thread.
 * [render] is render_data structure of status box;
 * [text] is text to be shown in status box;
 * [type] if type of message. Can be BACKGROUND_IMAGE_FAIL_TYPE or BACKGROUND_IMAGE_SUCCESS_TYPE
 * [RU]
 * Отображает сообщение в статусном окне. Безопасна для вызова не из потока интерфейса.
 * [render] - структура типа render_data для нужного статусного окна;
 * [text] - текст, отображаемый в статусном окне;
 * [type] - тип сообщения. Может быть:
 * BACKGROUND_IMAGE_FAIL_TYPE (красный фон,иконка - восклицательный знак)
 * или
 * BACKGROUND_IMAGE_SUCCESS_TYPE (Жёлтный фон, иконка - галка)
*/
void yon_ubl_status_box_render_thread(char *text, BACKGROUND_IMAGE_TYPE type);

/**yon_ubl_status_list_store_highlight_incorrect(GtkListStore *list, GtkTreeIter *iter)
 * [EN]
 * 
 * [RU]
 * Подсвечивает красным цветом [widget] на 5 секунд
*/
void yon_ubl_status_highlight_incorrect(GtkWidget *widget);

/**yon_ubl_status_list_store_highlight_incorrect(GtkListStore *list, GtkTreeIter *iter)
 * [EN]
 * 
 * [RU]
 * Подсвечивает красным цветом [iter] элемент списка [list] на 5 секунд
*/
void yon_ubl_status_list_store_highlight_incorrect(GtkListStore *list, GtkTreeIter *iter);

static int status_thread_busy;

/**yon_ubl_status_box_spawn(GtkContainer *container,char *display_text, int timeout,BACKGROUND_IMAGE_TYPE type);
 * [EN]
 * 
 * [RU]
 * Создаёт статусную строку в контейнере [container], отображая текст [display_text].
 * Строка удаляется через [timeout] секунд.
 * [type] - тип сообщения. Может быть:
 * BACKGROUND_IMAGE_FAIL_TYPE (красный фон,иконка - восклицательный знак)
 * или
 * BACKGROUND_IMAGE_SUCCESS_TYPE (Жёлтный фон, иконка - галка)
*/
void yon_ubl_status_box_spawn(GtkContainer *container,char *display_text, int timeout,BACKGROUND_IMAGE_TYPE type);
void yon_ubl_status_box_despawn(GtkContainer *status_container);

//socket section
/**yon_ubl_setup_sockets(GtkWidget *main_window, GtkWidget *left_window, GtkWidget *right_window, int socket_main_id, int socket_left_id, int socket_right_id)
 * [EN]
 * Set up plugs for using with GtkSockets insine ubl-settings-manager.
 * [main_window] is container widget, which holds main application functionality.
 * [left_window] is container widget, which holds widgets, have to be shown at left part of ubl-settings-manager header.
 * [right_window] is container widget, which holds widgets, have to be shown at right part of ubl-settings-manager header.
 * [socket_main_id] is id of socket for [main_window].
 * [socket_left_id] is id of socket for [left_window].
 * [socket_right_id] is id of socket for [right_window].
 * [RU]
 * Настраивает плаги для работы с сокетами в утилите ubl-settings-manager.
 * [main_window] - контейнер основного интерфейса приложения.
 * [left_window] - контейнер для виджетов которые должны отображаться в левой части шапки ubl-settings-manager.
 * [right_window] - контейнер для виджетов которые должны отображаться в правой части шапки ubl-settings-manager.
 * [socket_main_id] - id сокета для [main_window].
 * [socket_left_id] - id сокета для [left_window].
 * [socket_right_id] - id сокета для [right_window].
*/
void yon_ubl_setup_sockets(GtkWidget *main_window, GtkWidget *left_window, GtkWidget *right_window, int socket_main_id, int socket_left_id, int socket_right_id);

//webkit section
#ifdef WEBKIT_FOUND
    #ifndef WEBKIT_INCLUDE
        #define WEBKIT_INCLUDE 
    #endif
#endif
#ifdef WEBKIT_INCLUDE
#include <webkit2/webkit2.h> 

/**yon_ubl_browser_window_open(char *link, char *browser_window_name)
 * [EN]
 * Launches integrated browser window, named [browser_window_name] at header with [link].
 * [RU]
 * Открывает встроенный браузер с именем [browser_window_name] и показываемой страницей по ссылке [link]
*/
GtkWidget *yon_ubl_browser_window_open(char *link, char *browser_window_name);
#else

/**yon_ubl_browser_window_open(char *link, char *browser_window_name)
 * [EN]
 * Launches browser with [link].
 * [browser_window_name] is't used. It's needed for compatibility with webkit version of that function.
 * [RU]
 * Открывает браузер со страницей по ссылке [link]
 * [browser_window_name] не используется. Нужна для совместимости с webkit версией этой функции.
*/
GtkWidget *yon_ubl_browser_window_open(char *link, char *browser_window_name);
#endif

// rmb menu section
typedef struct {
    GtkWidget *menu;
    dictionary *buttons;
    GCallback show_function;
    void *show_data;
} rmb_menu_window;

rmb_menu_window *yon_rmb_menu_setup(GtkWidget *target_widget, int (*show_function)(void*), void *show_data, const char *button_label, const char *icon_name, GCallback function, gpointer data,...);
#endif

void yon_gtk_entry_set_password_visibility_icon(GtkEntry *target);

void yon_on_text_insert_only_digits(GtkEditable *editable, const gchar *text, gint length, gint *position, gpointer user_data);

void yon_gtk_entry_block_restricted_symbols(GtkEntry *target);

void yon_gtk_entry_allow_password_symbols(GtkEntry *target);

void yon_gtk_entry_block_languages(GtkEntry *target);

void yon_gtk_entry_block_symbols(GtkEntry *target, char *symbols);

void yon_gtk_entry_block_lowercase(GtkEntry *target);


/// @brief Set regex input pattern for GtkEntry.
/// @param target Target entry widget. 
/// @param pattern Valid regex string.
/// @example yon_entry_set_pattern(GTK_ENTRY(entry_widget),"^\\d\\dx\\d\\d$") // pattern will allow to input two numbers from line start, then one 'x', and then two more numbers. After that, inserting new symbols will block, as patern was successfully filled. 
void yon_entry_set_pattern(GtkEntry *target, char *pattern);

/// @brief Get string from GtkEntry by regex string
/// @param target Target entry widget.
/// @param pattern Valid regex string.
/// @return A newly allocated matched substring, or NULL if nothing were found 
char *yon_gtk_entry_get_by_pattern(GtkEntry *target, const char *pattern);

void yon_on_entry_set_allowed_symbols(GtkEntry *target, char *symbols);

// GtkTreeView section

dictionary *yon_gtk_tree_store_get_children(GtkTreeStore *tree, GtkTreeIter *parent,int column);

void yon_gtk_tree_store_fill_children(GtkTreeStore *tree, GtkTreeIter *parent, dictionary *data, int column);

void yon_gtk_tree_store_copy_full(GtkTreeStore *source, GtkTreeStore *destination);

gboolean yon_gtk_tree_store_find_full(GtkTreeModel *model, GtkTreeIter *iter, gint column, const gchar *target);

gboolean yon_gtk_tree_iter_get_from_combo_box_id(GtkComboBox *combo, GtkTreeModel *model, GtkTreeIter *iter);

gboolean yon_gtk_tree_model_check_exist(GtkTreeModel *model, GtkTreeIter *iter, char *id, int column);

gboolean yon_gtk_list_store_copy_full(GtkListStore *target, GtkListStore *source);

void yon_calendar_set_date_orientation(int orientation);

void yon_calendar_popover_open(GtkEntry *TargetEntry,GtkWidget *PopupTarget);

int yon_calendar_get_last_date();

config_str yon_resource_open_file(const char *path, int *size);

void yon_gtk_revealer_set_from_switch(GtkRevealer *revealer, GtkSwitch *target);
void yon_gtk_revealer_set_from_switch_inversed(GtkRevealer *revealer, GtkSwitch *target);
void yon_gtk_revealer_set_from_expander(GtkRevealer *revealer, GtkExpander *target);

void yon_gtk_window_set_shrinking_from_revealer_resizing(GtkWindow *window, GtkRevealer *revealer);

/// @brief Check if specific TreeModel's boolean column has at least one matching value
/// @param model Model to check
/// @param column Searching column
/// @param check_value Compared value
/// @return 1 if value exists, 0 otherwise
int yon_tree_model_check_boolean(GtkTreeModel *model, int column, int check_value);

void yon_gtk_tree_view_set_click_callback(GtkTreeView *target, GtkCellRenderer *cell, void(*func)(GtkTreeView*, GtkTreePath*,gpointer *data), gpointer data);

// Packages section

enum YON_PACKAGES_DB_TYPE {
    YON_PACKAGES_LOCAL,
    YON_PACKAGES_SYNC,
    YON_PACKAGES_ALL,
};

/**yon_packages_init()
 * Инициализация системы пакетов. Инициализация происходит долго,
 * рекомендуется вызывать как можно ближе к началу работы кода.
 */
int yon_packages_init();

/// @brief Separate package name from DB name
/// @param package_name A string of "DB_name/package_name" format 
/// @return A newly allocated sting with DB name. package name returns to packagename variable
char *yon_packages_parse_path(char *package_name);

/// @brief Toggle an option to use full package path (db_name/package_name)
/// @param enable 1 to enable, 0 to disable
void yon_packages_option_use_full_path_set(gboolean enable);

/*Проверить существовует ли пакет в репозиториях*/
int yon_packages_check_exist(const char *package);

/*Проверить установлен ли пакет*/
int yon_packages_check_installed(char *package);
int yon_packages_check_updates(char *package);
void yon_packages_finish();
GList *yon_packages_get_all();
GList *yon_packages_search_all(char *pkgname_regex);
void yon_packages_update();

#ifdef VTE_INCLUDE

int yon_packages_install(char *package,VteTerminal *terminal);
int yon_packages_remove(char *package,VteTerminal *terminal);

#endif

config_str yon_packages_find(enum YON_PACKAGES_DB_TYPE type, const char *search_string, gsize *size);

/// @brief Get groups string for package
/// @param type Source database for package
/// @param package Package name
/// @return A newly allocated string of groups for requested package in bytes
char *yon_packages_get_version(enum YON_PACKAGES_DB_TYPE type, const char *package);

/// @brief Get description for package
/// @param type Source database for package
/// @param package Package name
/// @return A newly allocated description string for requested package in bytes
char *yon_packages_get_description(enum YON_PACKAGES_DB_TYPE type, const char *package);

/// @brief Get groups string for package
/// @param type Source database for package
/// @param package Package name
/// @return A newly allocated string of groups for requested package in bytes
char *yon_packages_get_groups(enum YON_PACKAGES_DB_TYPE type, const char *package);

/// @brief Get installed size for package
/// @param type Source database for package
/// @param package Package name
/// @return The installed size of requested package in bytes
long yon_packages_get_installed_size(enum YON_PACKAGES_DB_TYPE type, const char *package);

/// @brief Get installed size for package
/// @param type Source database for package
/// @param package Package name
/// @return The download size of requested package in bytes
long yon_packages_get_size(enum YON_PACKAGES_DB_TYPE type, const char *package);

/// @brief Get dependences for package
/// @param type Source database for package
/// @param package Package name
/// @return A newly allocated char* array
config_str yon_packages_get_depends(enum YON_PACKAGES_DB_TYPE type, const char *package, int *size);

typedef struct {
    char *repo_name;
    char *package_name;
    char *version;
    char *description;
    char *architecture;
    char *url;
    char *licence;
    char *groups;
    char *provides;
    char *depends;
    char *optional_depends;
    char *conflicts;
    char *replaces;
    char *download_size;
    char *install_size;
    char *packager;
    char *build_date;
    int validate_by;
} yon_packages_info;

yon_packages_info *yon_packages_get_info_struct(enum YON_PACKAGES_DB_TYPE type, const char *package);

void yon_packages_info_struct_free(yon_packages_info *info);
char *yon_packages_get_info_string(yon_packages_info *info);

void yon_combo_box_set_default(GtkComboBoxText *target, char *command, char*(result_callback)(char*));

int yon_ip_mask_get_bits(char *mask);
int yon_ip_check(char *ip);

void yon_gtk_widget_register_parameter(GtkWidget *target, char *config_parameter, char *get_command, char *object_property);
void yon_gtk_widget_register_parameter_manual(GtkWidget *target, char *config_parameter, char *get_command, char *object_property);
void yon_gtk_widget_register_parameter_activate();

typedef struct apps
{
    char *Name;
    char *Desktop_path;
    int Type;
    char *Comment;
    int categories_size;
    config_str Categories;
    char *Exec;
    char *Icon;
    int Pluggable;
    int DualPluggable;
    char *keywords;
    char *NameRaw;
} apps;

/// @brief Initiallize applications system
void yon_apps_init();

/// @brief Uninitiallize applications system
void yon_apps_uninit();

/// @brief Check the initialization of the applications system 
/// @return true if initialised, false otherwise
gboolean yon_apps_check_init();

/// @brief Get a structure with information about the application
/// @param name Application name
/// @return Structure with information about the application from the system
apps *yon_apps_get(char *name);

apps *yon_apps_find(char *name);

/// @brief Get all apps from the category list
/// @param categories List of categories for which applications are searched
/// @param categories_size The length of the category list
/// @param final_size The size of the final array with application names
/// @return An array of strings containing the names of all applications in the given categories.
config_str yon_apps_get_by_categories(config_str categories, int categories_size, int *final_size);


/// @brief Block scroll element changing for GtkComboBox
/// @param target - GtkComboBox to block
void yon_gtk_combo_box_block_scroll(GtkComboBox *target);

//timezone section

#define timezone_locale_name "libublsettings-gtk3"

/// @brief Init timezone system
/// @return 1 if timezone system has been successfully initialised, 0 if failed
int yon_timezone_init();


/// @brief Finalize timezone system and free all memory;
void yon_timezone_unref();

/// @brief Get all timezones list
/// @param size pointer for list size;
/// @return A newly allocated char* array with timezones
config_str yon_timezone_get_all(size_t *size);

/// @brief Get list of zones for specific region
/// @param region The region for which the zone search will take place;
/// @param size size pointer of zones list;
/// @return New allocated char* array with zones
config_str yon_timezone_get_zones_from_region(char *region, size_t *size);

/// @brief Get a country code for timezone
/// @param timezone Requested timezone;
/// @return A newly allocated char string with country code or NULL
char *yon_timezone_get_country_code(const char *timezone);

/// @brief Get a comments for timezone
/// @param timezone Requested timezone;
/// @return A newly allocated char string with comments or NULL
char *yon_timezone_get_comments(const char *timezone);

/// @brief Get a city for timezone
/// @param timezone Requested timezone;
/// @return A newly allocated char string with city or NULL
char *yon_timezone_get_city(const char *timezone);

/// @brief Get a country for timezone
/// @param timezone Requested timezone;
/// @return A newly allocated char string with country or NULL
char *yon_timezone_get_country(const char *timezone);

/// @brief Get a zone for timezone
/// @param timezone Requested timezone;
/// @return A newly allocated char string with zone or NULL
char *yon_timezone_get_zone(const char *timezone);

/// @brief Get UTC modifier for timezone
/// @param timezone Requested timezone;
/// @return A newly allocated char string with UTC modifier or NULL
char *yon_timezone_get_utc(const char *timezone);

    #define KB_LABEL _("Kb")
    #define MB_LABEL _("Mb")
    #define GB_LABEL _("Gb")
    #define TB_LABEL _("Tb")

/// @brief Get a string of bytes, converted to kilobytes, megabytes gigabytes or terabytes (K, M, G, T) 
/// @param bytes size value of bytes to convert
/// @return A newly allocated string with converted representation of bytes
char *yon_size_long_convert_automatic_to_string(unsigned long bytes);

/// @brief Get a string of bytes, converted to kilobytes, megabytes gigabytes or terabytes (K, M, G, T). Works with negative sizes.
/// @param bytes size value of bytes to convert
/// @return A newly allocated string with converted representation of bytes
char *yon_size_long_convert_automatic_to_string_preserve_negative(long bytes);

char *yon_size_get_name_from_letter(char letter);

/// @brief Block widget from destruction;
void yon_gtk_widget_block_destruction(GtkWidget *target);

// translation

/// @brief Initiate application runtime translation
/// @param update_widgets SList of widgets to translate
void yon_translation_init(GSList *update_widgets);

/// @brief Add a certain widget for translation
/// @param target Widget to translate
void yon_gtk_widget_set_translation(GtkWidget *target);

/// @brief Set a certain widget to be translated with custom function. Prevents using yon_gtk_widget_set_translation() function.
/// @param target Target widget for translation
/// @param translation_func Function to be executed instead of original function
/// @return TRUE if function was set successfully, FALSE otherwise.
int yon_translation_set_translation_func(GtkWidget *target, void (*translation_func)(GtkWidget *));

/// @brief Start process of translation for chosen language
void yon_update_translation();

/// @brief Set language for translation
/// @param lang Locale code (ex. "en_US.UTF-8")
/// @param locale_name translation domain name
void yon_translation_set_language(const char *lang, const char *locale_name);

/// @brief Check environment for wayland sesstion type and change it to x11 if found
/// @return 1 if wayland was found, 0 otherwise
int yon_environment_check_wayland();

/// @brief Get environment variables for launch command.
/// @param env pointer to char string, where environment string should be returned
/// @return 1 if it is possible to launch applications via GtkSocket, 0 if it shall not be used
gboolean yon_environment_get_env_for_launch(char **env);

#endif