#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);

void yon_entry_set_pattern(GtkEntry *target, 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);

// Packages section

enum YON_PACKAGES_DB_TYPE {
    YON_PACKAGES_LOCAL,
    YON_PACKAGES_SYNC,
    YON_PACKAGES_ALL,
};

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

/*Проверить существовует ли пакет в репозиториях*/
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();
int yon_packages_install(char *package);
int yon_packages_remove(char *package);

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 bytes to convert
/// @return A newly allocated string with converted representation of bytes
char *yon_size_long_convert_automatic_to_string(unsigned 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);

#endif