#ifndef UBL_SETTINGS_MANAGER
#define UBL_SETTINGS_MANAGER

#include <gtk/gtk.h>
#include <time.h>
#include <getopt.h>
#include <dlfcn.h>
#include <gtk/gtkx.h>
#include <stdbool.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <libintl.h>
#include <unistd.h>
#include <pthread.h>
#include<sys/utsname.h>
#include<sys/sysinfo.h>
#include <math.h>
#include <wctype.h> 
#include <sys/stat.h>
#include <libublsettings.h>
#include <libublsettings-gtk3.h>
#include <libublsettingsui-gtk3.h>
#ifdef WEBKIT_FOUND
#include <webkit2/webkit2.h>
#endif
#include "ubl-strings.h"


#define check_web2kit_command "ldconfig -p |grep webkit2"

#define glade_path "/com/ublinux/ui/ubl-settings-manager.glade"
#define glade_path_gnome_theme "/com/ublinux/ui/ubl-settings-manager-theme-gnome.glade"
#define glade_path_gnome_section "/com/ublinux/ui/ubl-settings-manager-theme-gnome-section.glade"
#define glade_path_main_section "/com/ublinux/ui/ubl-settings-manager-theme-main-section.glade"
#define glade_path_main_theme "/com/ublinux/ui/ubl-settings-manager-theme-main.glade"
#define glade_path_settings "/com/ublinux/ui/ubl-settings-manager-settings.glade"
#define glade_path_settings_section "/com/ublinux/ui/ubl-settings-manager-settings-sections.glade"
#define glade_path_section_element "/com/ublinux/ui/ubl-settings-manager-section-element.glade"
#define glade_path_config "/com/ublinux/ui/ubl-settings-manager-config.glade"
#define CssPath "/com/ublinux/css/ubl-settings-manager.css"
#define GlobalConfigPath "/etc/xdg/ubl-settings-manager/ubl-settings-manager.conf"
#define UserConfigPath "/.config/ubl-settings-manager/ubl-settings-manager.conf"
#define arrow_right_icon_path "com.ublinux.libublsettingsui-gtk3.pan-right-symbolic"
#define arrow_left_icon_path "com.ublinux.libublsettingsui-gtk3.pan-left-symbolic"
#define icon_path "com.ublinux.ubl-settings-manager"
#define AppBannerPath "/com/ublinux/images/ubl-settings-manager-banner.png"
#define DesktopPath "/usr/share/applications/"
#define IconPicturesPath "/usr/share/icons/hicolor/scalable/apps/"
#define LocalePath "/usr/share/locale" 
#define LocaleName "ubl-settings-manager"

#define launch_command(target) yon_char_unite("xdg-open ",target,NULL)
#define launch_args_command(main_socket,load_socket,save_socket) yon_char_unite("--socket-id=",main_socket," --socket-ext-id=",save_socket," --socket-trd-id=",load_socket,NULL)

#define settings_section "Settings"
#define sections_section "Sections"

#define double_click_parameter "double_click"
#define icon_size_parameter "icon_size"
#define theme_parameter "theme"
#define hide_banner_parameter "hide_banner"

typedef char* string;
__attribute__((unused)) static \
string version_application;

#define _(String) gettext(String)

typedef struct {
    char *command;
    int *exitcode;
} thread_output;

typedef struct IVGrapgicals{
    char *sectionName;
    char *categories;
    GtkListStore *LV;
    GtkWidget *Box;
    GtkWidget *IV;
    GtkWidget *label;
    GtkWidget *sep;
    GtkCellRendererPixbuf *iconRender;
} IVGraphicals;

typedef struct IconSection{
    char *section;
    char *categories;
} IconSection;

typedef struct {
    GtkWidget *MainFrame;
    GtkWidget *MainBox;
    GtkWidget *ElemBox;
    GtkWidget *DragButtonBox;
    GtkWidget *DragUpButton;
    GtkWidget *DragDownButton;
    GtkWidget *NameBox;
    GtkWidget *CategoriesBox;
    GtkWidget *OptionBox;
    GtkWidget *NameEntry;
    GtkWidget *NameLabel;
    GtkWidget *CategoriesEntry;
    GtkWidget *CategoriesLabel;
    GtkWidget *EditButtonBox;
    GtkWidget *EditButtonAccept;
    GtkWidget *EditButtonCancel;
    GtkWidget *ButtonEdit;
    GtkWidget *ButtonDelete;
    GtkWidget *DeleditBox;
} SectionSettingSegment;

/// @brief Public fields of theme structs
typedef struct theme_struct { 
    char *theme_name;
    GtkWidget *MainBox; //theme main box, which connects to window
    GtkWidget *SocketBox; //main socket box, where socket is being parented to
    GtkWidget *HideBox; //box to hide when socket has been connected
    int (*list_update_func)(struct theme_struct*); //function to update theme's lits of application
} theme_struct;

typedef struct gnome_theme_struct {
    char *theme_name;
    GtkWidget *MainBox;
    GtkWidget *SocketBox;
    GtkWidget *HideBox;
    int (*list_update_func)(struct gnome_theme_struct*);
    GtkWidget *SearchEntry;
    GtkWidget *AppsTree;
    GtkWidget *Socket;
    GtkWidget *GnomePaned;
    GtkWidget *GnomeInfoLogoImage;
    GtkCellRenderer *IconCell;
} gnome_theme_struct;

typedef struct main_theme_struct {
    char *theme_name;
    GtkWidget *MainBox;
    GtkWidget *SocketBox;
    GtkWidget *HideBox;
    int (*list_update_func)(struct main_theme_struct*);
    GtkWidget *AppsTree;
    GtkWidget *Socket;
    GtkListStore *AppsList;
} main_theme_struct;

typedef struct {
    GtkWidget *Window;
    GtkWidget *StatusBox;
    GtkWidget *TitleLabel;
    GtkWidget *ThemeBox;
    GtkWidget *SocketBox;
    GtkWidget *BackButton;
    GtkWidget *SettingsButton;
    GtkWidget *BannerImage;
    GtkWidget *BannerArrow;
    GtkWidget *BannerButton;
    GtkWidget *BannerRevealer;

    GtkWidget *LoadSocket;
    GtkWidget *LoadSocketBox;
    GtkWidget *SaveSocket;
    GtkWidget *SaveSocketBox;
    GtkWidget *OptionsSocket;
    GtkWidget *OptionsSocketBox;

    GtkWidget *MainMenuItemSettings;
    GtkWidget *MainMenuItemAbout;
    GtkWidget *MainMenuItemDocumentation;
    
    theme_struct *current_theme;
    
} main_window;

typedef struct {
	template_config_fields;
    int apps_icon_size;
    dictionary *sections; 
    int labelDensity;
    int lock_settings;
    int double_click;
    dictionary *SettingsSections;
    int banner_hidden;

    main_window *widgets;

    GHashTable *themes;
} config;

extern config main_config;

typedef struct {
    char *name;
    int categories_size;
    config_str categories;
} app_section;

typedef struct {
    GtkWidget *Window;
    GtkWidget *SizeSlider;
    GtkWidget *SizeLabel;
    GtkWidget *SizeIcon;
    GtkWidget *ThemeCombo;
    GtkWidget *DoubleClickSwitch;
    GtkWidget *SectionsConfigurationButton;
    GtkWidget *CancelButton;
    GtkWidget *AcceptButton;

    int doubleclick;
    int icon_size;
} settings_window;

void yon_open_browser(GtkWidget *self, char *link);
void on_open_documentation_confirmation(GtkWidget *self, char *link);
void on_link(GtkWidget *self, char* uri, gpointer user_data);
void on_about(GtkWidget *self, char *version_application);

void on_settings_accept(GtkWidget *, settings_window *window);
void yon_theme_init();
theme_struct *yon_theme_update(main_window *widgets);
gnome_theme_struct *yon_gnome_theme_new();
main_theme_struct *yon_main_theme_new();
app_section *yon_app_section_new();
gnome_theme_struct *yon_gnome_theme_new();
char *yon_get_save_socket();
char *yon_get_load_socket();
GtkSocket *yon_sockets_init(GtkBox *socketBox);
void on_plug_disconnected(GtkSocket *self, main_window *widgets);

void yon_interface_update(main_window *widgets);

void on_settings_open(GtkWidget *, main_window *widgets);
void yon_section_window_open(GtkWidget *, settings_window *settings);
void on_reveal_banner(GtkWidget *, main_window *widgets);
void config_init();
void yon_config_update();
void on_back_clicked(GtkWidget *, GtkWidget *socket);
void on_plug_connected(GtkSocket *self, main_window *widgets);
main_window *yon_main_window_setup();
gboolean on_settings_size_changed(GtkRange* , GtkScrollType* , gdouble value, settings_window *window);
settings_window *yon_settings_window_new();
void on_gnome_plug_connected(GtkWidget *,gnome_theme_struct *theme);
void on_gnome_plug_disconnected(GtkWidget *,gnome_theme_struct *theme);
void yon_gnome_section_setup(gnome_theme_struct *theme,app_section *section);
int yon_gnome_update(gnome_theme_struct *theme);
void on_gnome_search(GtkWidget *, gnome_theme_struct *theme);
void on_main_plug_connected(GtkWidget *,main_theme_struct *theme);
void on_main_plug_disconnected(GtkWidget *,main_theme_struct *theme);
void on_main_activate(GtkFlowBox* , GtkFlowBoxChild* child, main_theme_struct *theme);
void yon_main_section_setup(main_theme_struct *theme, app_section *section);
void yon_main_theme_resize(main_theme_struct *theme);
int yon_main_update(main_theme_struct *theme);
GtkWidget *yon_config_chooser_new( char*);
void yon_config_chooser_update(GtkWidget *root);
void yon_config_chooser_save(GtkWidget *root);
void on_main_exit(GtkWidget *, GdkEvent *, main_window *widgets);
gboolean on_settings_doubleckick_switched(GtkWidget *, int state,settings_window *window);
#endif