#ifndef UBL_SETTINGS_UPDATE_INIT
#define UBL_SETTINGS_UPDATE_INIT
#include <gtk/gtk.h>
#include <gtk/gtkx.h>
#include <locale.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <libintl.h>
#include <getopt.h>
#include <libintl.h>
#include <time.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 _(String) gettext(String)

#define check_is_password_hash(password) system(yon_char_unite("/lib/ublinux/functions is_hash_password '", password,"'",NULL))

#define glade_path "/com/ublinux/ui/ubl-settings-update.glade"
#define glade_repo_add_path "/com/ublinux/ui/ubl-settings-update-repo-add.glade"
#define glade_web_publish_add_path "/com/ublinux/ui/ubl-settings-update-web-publication-add.glade"
#define glade_mirror_configure_path "/com/ublinux/ui/ubl-settings-update-mirror-configure.glade"
#define glade_mirror_add_path "/com/ublinux/ui/ubl-settings-update-mirror-add.glade"
#define glade_mirror_path_add_path "/com/ublinux/ui/ubl-settings-update-mirror-path-add.glade"
#define glade_repo_path_add_path "/com/ublinux/ui/ubl-settings-update-repo-path-add.glade"
#define glade_password_path "/com/ublinux/ui/ubl-settings-update-password.glade"
#define glade_path_ftp "/com/ublinux/ui/ubl-settings-update-ftp-publication.glade"
#define CssPath "/com/ublinux/css/ubl-settings-update.css"
#define config_path yon_char_unite(yon_ubl_user_get_home_directory(),"/.config/",LocaleName,"/",LocaleName,".conf",NULL)

#define accept_icon_name "com.ublinux.libublsettingsui-gtk3.accept-symbolic"
#define edit_icon_name "document-edit-symbolic"

#define LocalePath "/usr/share/locale" 
#define LocaleName "ubl-settings-update"
#define icon_path "com.ublinux.ubl-settings-update"

#define sha256_encrypt_command(target) yon_char_unite("echo -n \"",target,"\" | sha256sum | cut -f 1 -d ' '",NULL)
#define sha512_encrypt_command(target) yon_char_unite("echo -n \"",target,"\" | sha512sum | cut -f 1 -d ' '",NULL)

#define config_get_command(target) yon_char_unite("ubconfig --default --source ",target," -ea get [update] REPOPUBLIC_NET REPOPUBLIC_WEB REPOSITORY REPOSITORY[*] REPOPUBLIC_WEB REPOPUBLIC_WEB[*] REPOPUBLIC_CACHE REPOPUBLIC_CACHE[*] AUTOUPDATE AUTOUPDATE[mode] AUTOUPDATE[interval] AUTOUPDATE[repos] AUTOUPDATE[timestamp] REPOPUBLIC_FTP[*]",NULL)
#define config_get_default_command "ubconfig --source default get [update] AUTOUPDATE[repos] AUTOUPDATE[interval] AUTOUPDATE[mode] AUTOUPDATE REPOSITORY REPOSITORY[*] REPOPUBLIC_FTP[*]"
#define config_get_repos_command(target) yon_char_unite("ubconfig --default --source ",target," get [update]  REPOSITORY[*] ",NULL)

#define config_get_global_only_parameters ""
#define config_get_local_only_parameters ""

#define get_all_standard_repos "ubconfig --source default get [update] REPOSITORY[*]"
#define get_publication_list_command "sed -rn \"/^[[:blank:]]*\\[options\\][[:blank:]]*$/d;s/^\\[(.*)\\]$/\\1/p\" /etc/pacman.conf"

#define REPOSITORY(target) yon_char_unite("REPOSITORY[",target,"]",NULL)
#define REPOSITORY_parameter "REPOSITORY"
#define REOSITORY_command(target) yon_char_unite("ubconfig --source global get [update] REPOSITORY[",target,"]",NULL)
#define REPOSITORY_parameter_command yon_char_unite("ubconfig --source global get [update] REPOSITORY",NULL)
#define REPOSITORY_search "REPOSITORY["
#define REPOSITORY_parameter_all "REPOSITORY[*]"

#define REPOPUBLIC_FTP(target) yon_char_unite("REPOPUBLIC_FTP[",target,"]",NULL)
#define REPOPUBLIC_FTP_parameter "REPOPUBLIC_FTP[*]"
#define REPOPUBLIC_FTP_search "REPOPUBLIC_FTP["
#define REPOPUBLIC_FTP_command(target) yon_char_unite("ubconfig --source global get [update] REPOPUBLIC_FTP[",target,"]",NULL)
#define REPOPUBLIC_FTP_command_all "ubconfig --source global get [update] REPOPUBLIC_FTP[*]"

#define REPOPUBLIC_NET_parameter "REPOPUBLIC_NET"
#define REPOPUBLIC_NET_parameter_command "ubconfig --source global get [update] REPOPUBLIC_NET"
#define REPOPUBLIC_WEB "REPOPUBLIC_WEB"
#define REPOPUBLIC_WEB_search "REPOPUBLIC_WEB["
#define REPOPUBLIC_WEB_full(target) yon_char_unite("REPOPUBLIC_WEB[",target,"]",NULL)
#define REPOPUBLIC_WEB_command(target) yon_char_unite("ubconfig --source global get [update] REPOPUBLIC_WEB[",target,"]",NULL)
#define REPOPUBLIC_CACHE "REPOPUBLIC_CACHE"
#define REPOPUBLIC_CACHE_command "ubconfig --source global get [update] REPOPUBLIC_CACHE"
#define REPOPUBLIC_CACHE_search "REPOPUBLIC_CACHE["
#define REPOPUBLIC_CACHE_full(target) yon_char_unite("REPOPUBLIC_CACHE[",target,"]",NULL)
#define REPOPUBLIC_CACHE_full_command(target) yon_char_unite("ubconfig --source global get [update] REPOPUBLIC_CACHE[",target,"]",NULL)
#define REPOPUBLIC_CACHE_port "REPOPUBLIC_CACHE[port]"
#define REPOPUBLIC_CACHE_cache_dir "REPOPUBLIC_CACHE[cache_dir]"
#define REPOPUBLIC_CACHE_purge_files_after "REPOPUBLIC_CACHE[purge_files_after]"
#define REPOPUBLIC_CACHE_download_timeout "REPOPUBLIC_CACHE[download_timeout]"
#define REPOPUBLIC_CACHE_http_proxy "REPOPUBLIC_CACHE[http_proxy]"
#define REPOPUBLIC_CACHE_user_agent "REPOPUBLIC_CACHE[user_agent]"
#define REPOPUBLIC_CACHE_cron "REPOPUBLIC_CACHE[prefetch.cron]"
#define REPOPUBLIC_CACHE_ttl_unaccessed_in_days "REPOPUBLIC_CACHE[prefetch.ttl_unaccessed_in_days]"
#define REPOPUBLIC_CACHE_ttl_unupdated_in_days "REPOPUBLIC_CACHE[prefetch.ttl_unupdated_in_days]"

#define AUTOUPDATE "AUTOUPDATE"
#define AUTOUPDATE_command "ubconfig --source global get [update] AUTOUPDATE"
#define AUTOUPDATE_mode "AUTOUPDATE[mode]"
#define AUTOUPDATE_mode_command "ubconfig --source global get [update] AUTOUPDATE[mode]"
#define AUTOUPDATE_interval "AUTOUPDATE[interval]"
#define AUTOUPDATE_interval_command "ubconfig --source global get [update] AUTOUPDATE[interval]"
#define AUTOUPDATE_repos "AUTOUPDATE[repos]"
#define AUTOUPDATE_repos_command "ubconfig --source global get [update] AUTOUPDATE[repos]"
#define AUTOUPDATE_timestamp "AUTOUPDATE[timestamp]"
#define AUTOUPDATE_timestamp_command "ubconfig --source global get [update] AUTOUPDATE[timestamp]"

#define config_presave_clean_command(target_config) yon_char_unite("ubconfig ",!yon_char_is_empty(target_config)?"--target ":"",!yon_char_is_empty(target_config)?target_config:""," remove [update] REPOSITORY[*]",NULL)

typedef char* string;

__attribute__((unused)) static \
string version_application;

typedef struct {
    template_config_fields
    int save_config;
    char *date_format;
    config_str launch_arguments;
    int launch_size;

    gboolean remove_repos;
} config;

extern config main_config;

typedef struct {
    template_window_fields
    GtkWidget *AutoUpdateCheck;
    GtkWidget *UpdateModeCombo;
    GtkWidget *UpdateIntervalDefaultCheck;
    GtkWidget *UpdateIntervalSpin;
    GtkWidget *UpdateIntervalCombo;
    GtkWidget *UpdateRepoListCheck;
    GtkWidget *UpdateRepoTree;
    GtkWidget *BootCheck;
    GtkWidget *DateEntry;
    GtkCellRenderer *UpdateToggleCell;

    GtkWidget *RepositoriesRepoListConfigurationCheck;
    GtkWidget *RepositoriesDisableSystemReposCheck;
    GtkWidget *RepositoriesTree;
    GtkWidget *RepositoriesUpdateButton;
    GtkWidget *RepositoriesMoveUpButton;
    GtkWidget *RepositoriesMoveDownButton;
    GtkWidget *RepositoriesCreateButton;
    GtkWidget *RepositoriesEditButton;
    GtkWidget *RepositoriesDeleteButton;
    GtkListStore *ReposList;

    GtkWidget *PublicationConnectPublicCheck;
    GtkWidget *RecieveDBFromNetCheck;
    GtkWidget *PublicationTree;
    GtkCellRenderer *PublicationToggleCell;
    GtkWidget *PublicationUpdateButton;
    GtkWidget *PublicationCheck;
    GtkListStore *PublicationList;

    GtkWidget *WebPublicationUpdateButton;
    GtkWidget *WebPublicationAddButton;
    GtkWidget *WebPublicationEditButton;
    GtkWidget *WebPublicationRemoveButton;
    GtkWidget *WebPublicationTree;
    GtkWidget *WebPublicationUpperTree;
    GtkListStore *WebPublicationList;

    GtkWidget *FtpUpdateButton;
    GtkWidget *FtpAddButton;
    GtkWidget *FtpEditButton;
    GtkWidget *FtpRemoveButton;
    GtkWidget *FtpTree;
    GtkListStore *FtpList;

    GtkWidget *MirrorPublicCheck;
    GtkWidget *MirrorTree;
    GtkWidget *MirrorUpdateButton;
    GtkWidget *MirrorAddButton;
    GtkWidget *MirrorEditButton;
    GtkWidget *MirrorRemoveButton;
    GtkWidget *MirrorConfigureButton;
    GtkListStore *MirrorList;
} main_window;

typedef struct {
    dictionary *sections;
    GtkWidget *RepoSourceCombo;
    GtkWidget *RepoSourceEntry;
    GtkWidget *Window;
    GtkWidget *HeadLabel;
    GtkWidget *StatusBox;
    GtkWidget *UsageSysupgradeCheck;
    GtkWidget *UsageEnableInsallCheck;
    GtkWidget *UsageEnableSearchCheck;
    GtkWidget *UsageEnableUpdateCheck;
    GtkWidget *UsageDefaultCheck;
    GtkWidget *SourceListBox;
    GtkWidget *RepoSignConditionCombo;
    GtkWidget *RepoSignCheckCombo;
    GtkWidget *RepoSourceButton;
    GtkWidget *SourceBox;
    GtkWidget *RepoSourceAddButton;
    GtkWidget *RepoNameEntry;
    GtkWidget *EnabledCheck;
    GtkWidget *AcceptButton;
    GtkWidget *CancelButton;
    GtkWidget *SignLevelLabel;

    GtkWidget *SignDefaultCheck;
    GtkWidget *SignTree;
    GtkWidget *SignLevelCheckEntry;
    GtkCellRenderer *SignCell;
    
    GtkListStore *SignList;

    char *name;
} repo_add_window;

typedef struct {
    GtkListStore *list;
    GtkWidget *PathEntry;

    GtkWidget *Window;
    GtkWidget *HeadLabel;
    GtkWidget *StatusBox;
    GtkWidget *EnablePublishCheck;
    GtkWidget *PathButton;
    GtkWidget *RepositoriesTree;
    GtkWidget *PortCheck;
    GtkWidget *PortEntry;
    GtkWidget *EnableWebFileBrowserCheck;
    GtkWidget *UsernameCheck;
    GtkWidget *UsernameEntry;
    GtkWidget *UserPasswordCheck;
    GtkWidget *UserPasswordCombo;
    GtkWidget *UserPasswordEntry;
    GtkWidget *PasswordButton;
    GtkWidget *AcceptButton;
    GtkWidget *CancelButton;
    GtkCellRenderer *SelectionCellRenderer;

    char *name;
} web_publication_add_window;

typedef struct {
    dictionary *sections;
    GtkWidget *TypeCombo;
    GtkWidget *TypeEntry;
    GtkWidget *Window;
    GtkWidget *HeadLabel;
    GtkWidget *StatusBox;
    GtkWidget *AddButton;
    GtkWidget *AcceptButton;
    GtkWidget *CancelButton;
    GtkWidget *NameEntry;
    GtkWidget *TypeButton;
    GtkWidget *PathBox;

    char *name;
} mirror_add_window;

typedef struct {
    GtkWidget *Window;
    GtkWidget *HeadLabel;
    GtkWidget *StatusBox;
    GtkWidget *AcceptButton;
    GtkWidget *CancelButton;

    GtkWidget *PortDefaultCheck;
    GtkWidget *PortSpin;
    GtkWidget *CacheDefaultCheck;
    GtkWidget *CacheEntry;
    GtkWidget *CacheButton;
    GtkWidget *InactivityDurationDefaultCheck;
    GtkWidget *InactivityDurationSpin;
    GtkWidget *CacheTimeoutDefaultCheck;
    GtkWidget *CacheTimeoutSpin;
    GtkWidget *ProxyCheck;
    GtkWidget *ProxyEntry;
    GtkWidget *AgentDefaultCheck;
    GtkWidget *AgentEntry;
    GtkWidget *CronEntry;
    GtkWidget *UpdatesDelayDefaultCheck;
    GtkWidget *UpdatesDelaySpin;
    GtkWidget *UpdatesRequestDelayDefaultCheck;
    GtkWidget *UpdatesRequestDelaySpin;
} mirror_configure_window;

typedef struct {
    GtkWidget *Window;
    GtkWidget *HeadLabel;
    GtkWidget *StatusBox;

    GtkWidget *PasswordEntry;
    GtkWidget *RepeatPasswordEntry;
    GtkWidget *EncryptionCombo;
    GtkWidget *NoEncriptionCheck;
    GtkWidget *PasswordHashEntry;
    GtkWidget *UserCancelButton;
    GtkWidget *AcceptButton;

    GtkWidget *PasswordBox;
    GtkWidget *HashBox;

    const char *old_password;
    
} password_window;

typedef struct {
    GtkWidget *Window;
    GtkWidget *HeaderLabel;

    GtkWidget *AlwaysOpenCheck;

    GtkWidget *CloseButton;
    GtkWidget *AcceptButton;
} documentation_confirmation_window;

typedef struct {
    GtkWidget *PathRemovalBox;
    GtkWidget *PathEntry;
    GtkWidget *PathEditButton;
    GtkWidget *PathRemoveButton;
    GtkWidget *TypeCombo;
    int edits;
} path_section;

typedef struct {
    GtkListStore *ReposList;
    GtkWidget *StorageEntry;

    GtkWidget *Window;
    GtkWidget *StatusBox;
    GtkWidget *EnableCheck;
    GtkWidget *StorageButton;
    GtkWidget *ReposTree;
    GtkWidget *PortCheck;
    GtkWidget *PortSpin;
    GtkWidget *AnonUserCheck;
    GtkWidget *AnonUserEntry;
    GtkWidget *AnonUserButton;
    GtkWidget *CancelButton;
    GtkWidget *AcceptButton;

    GtkCellRenderer *SelectionCell;

    char *prev_key;
    
} ftp_window;

void on_save_done(main_window *, config_str output, int size);

void on_toggle_button_toggled(GtkWidget *self, main_window *widgets);
void on_config_save(GtkWidget *self, main_window *widgets);
void on_config_global_save(GtkWidget *self, main_window *widgets);
void on_config_local_save(GtkWidget *self, main_window *widgets);
void on_config_custom_save(GtkWidget *self, main_window *widgets);

void yon_load_proceed(YON_CONFIG_TYPE type);

void on_config_local_load(GtkWidget *, main_window *widgets);
void on_config_global_load(GtkWidget *, main_window *widgets);
void on_config_custom_load(GtkWidget *,main_window *widgets);

void on_toggle_cell_toggled(GtkCellRenderer *,char *path, main_window *widgets);

char *on_save_repos(main_window *widgets);

void on_web_user_check(GtkToggleButton *self, web_publication_add_window *window);

void config_init();

void yon_main_window_complete(main_window *widgets);

void on_repo_accept_clicked(GtkWidget *, dictionary *dict);
void on_web_publish_accept(GtkWidget *, dictionary *dict);
void on_mirror_accept(GtkWidget *,dictionary *dict);
void on_repo_remove(GtkWidget *self, main_window *widgets);
void on_web_publish_remove_accept(GtkWidget *, main_window *widgets);
void on_mirror_remove_accept(GtkWidget *, main_window *widgets);
void on_repositories_remove_accept(GtkWidget *, main_window *widgets);
void on_password_accept();

void on_password_open(GtkWidget *, web_publication_add_window *window);

void on_scrolled_window_size_allocate(GtkWidget *, GdkRectangle *allocation, repo_add_window *window);

void on_sign_cell_toggled(GtkWidget *, char *path, repo_add_window *window);

void on_sign_check_toggled(GtkToggleButton *self, repo_add_window *window);

void on_password_encryption_changed(GtkComboBox *self, password_window *dialog);

void on_mirror_type_changed(GtkComboBox *self, mirror_add_window *window);
void on_repo_source_changed(GtkComboBox *self, repo_add_window *window);
password_window *yon_password_window_new();
repo_add_window *yon_repo_add_window_new();
web_publication_add_window *yon_web_publication_add_window_new();
mirror_add_window *yon_mirror_add_window_new();
mirror_configure_window *yon_mirror_configure_window_new();

void on_file_chooser_open(GtkWidget *self, GtkEntry *target);
void on_column_resize(GtkTreeViewColumn *,GParamSpec *,main_window *widgets);

void on_web_publish_path_changed(GtkWidget *, web_publication_add_window *window);

void on_repo_add(GtkWidget *, main_window *widgets);
void on_mirror_add(GtkWidget *,main_window *widgets);
void on_web_publish_add(GtkWidget *,main_window *widgets);

void on_web_publish_remove(GtkWidget *self,main_window *widgets);
void on_mirror_remove(GtkWidget *,main_window *widgets);

void on_repo_edit(GtkWidget *,main_window *widgets);
void on_web_publish_edit(GtkWidget *,main_window *widgets);
void on_mirror_edit(GtkWidget *,main_window *widgets);

void on_mirror_configure(GtkWidget *,main_window *widgets);

void on_selection_changed(GtkWidget *self, main_window *widgets);

void yon_interface_update(main_window *widgets);

void on_mirror_path_add(GtkWidget *, mirror_add_window *window);
void on_mirror_path_removed(GtkWidget *, mirror_add_window *);
void on_mirror_path_edit(GtkWidget*,mirror_add_window *);
void on_repo_source_add(GtkWidget *, repo_add_window *window);

void on_cell_renderer_toggle_toggled(GtkWidget *self, gchar* path, GtkWidget *table);
void on_mirror_configure_accept(GtkWidget *, dictionary *dict);
char *yon_password_unencrypted_password_get(password_window *window);
char *yon_password_hash_get(password_window *window);
void yon_hash_entry_sensitiveness_update(GtkWidget *, password_window *dialog);
void on_password_hash_sensitiveness(GtkWidget *,password_window *window);
void on_update_clicked(GtkWidget *, main_window *widgets);
void on_repo_move_up(GtkWidget *,main_window *widgets);
void on_repo_move_down(GtkWidget *,main_window *widgets);
void on_save_start(main_window *widgets, char* path);
void on_repo_file_chooser_open(GtkWidget *, repo_add_window *window);
void on_ftp_accept(GtkWidget *, ftp_window *);
ftp_window *yon_ftp_window_new();
void yon_ftp_window_add(GtkWidget *, main_window *widgets);
void on_anon_user_select(GtkWidget *, ftp_window *window);
void yon_ftp_window_edit(GtkWidget *, main_window *widgets);
void on_ftp_remove(GtkWidget *,main_window *widgets);
void yon_update_toggled(GtkWidget *self, main_window *widgets);
void on_update_mode_changed(GtkWidget *, main_window *widgets);
void yon_check_repositories_order(const char *path);
#endif