#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 <libublsettings.h>
#include <libublsettings-gtk3.h>
#include <libublsettingsui-gtk3.h>
#ifdef WEBKIT_INCLUDE
    #include <webkit2/webkit2.h>
#endif 
#include "ubl-strings.h"

#define _(String) gettext(String)

#define glade_path "/com/ublinux/ui/ubl-settings-bootloader.glade"
#define glade_path_password "/com/ublinux/ui/ubl-settings-bootloader-password.glade"
#define glade_path_user "/com/ublinux/ui/ubl-settings-bootloader-user.glade"
#define glade_path_ringtone "/com/ublinux/ui/ubl-settings-bootloader-ringtone.glade"
#define glade_path_menu_window "/com/ublinux/ui/ubl-settings-bootloader-menu.glade"
#define glade_path_menu_item "/com/ublinux/ui/ubl-settings-bootloader-menu-item.glade"
#define banner_path "/com/ublinux/images/ubl-settings-bootloader-banner.png"
#define CssPath "/com/ublinux/css/ubl-settings-bootloader.css"
#define config_path yon_char_unite(yon_ubl_user_get_home_directory(),"/.config/",LocaleName,"/",LocaleName,".conf",NULL)
#define icon_path "com.ublinux.ubl-settings-bootloader"
#define kernel_options_path "resource:///com/ublinux/csv/grub-cmdline-linux.csv"
#define terminal_input_path "resource:///com/ublinux/csv/grub-terminal-input.csv"
#define terminal_output_path "resource:///com/ublinux/csv/grub-terminal-output.csv"
#define melody_path "resource:///com/ublinux/csv/grub-play.csv"

#define LocaleName "ubl-settings-bootloader"

#define get_menus_entry_command "/usr/lib/ublinux/scripts/grub-functions exec_get_all_menuentry2"

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

#define yon_config_get_custom_command(target) yon_char_unite("ubconfig --source ",target," get boot GRUB_SUPERUSERS GRUB_TIMEOUT GRUB_DEFAULT GRUB_BOOT_SILENT GRUB_PASSWORD[*] GRUB_CMDLINE_LINUX GRUB_TERMINAL_INPUT GRUB_TERMINAL_OUTPUT GRUB_PLAY",NULL)
#define config_get_local_command "ubconfig --source system get boot GRUB_SUPERUSERS GRUB_TIMEOUT GRUB_DEFAULT GRUB_BOOT_SILENT GRUB_PASSWORD[*] GRUB_CMDLINE_LINUX GRUB_TERMINAL_INPUT GRUB_TERMINAL_OUTPUT GRUB_PLAY"
#define config_get_global_command "ubconfig --source global get boot GRUB_SUPERUSERS GRUB_TIMEOUT GRUB_DEFAULT GRUB_BOOT_SILENT GRUB_PASSWORD[*] GRUB_CMDLINE_LINUX GRUB_TERMINAL_INPUT GRUB_TERMINAL_OUTPUT GRUB_PLAY"
#define config_get_default_command ""

#define config_get_global_only_parameters "ubconfig --source global get boot GRUB_USER"
#define config_get_local_only_parameters ""

#define GRUB_TIMEOUT_parameter "GRUB_TIMEOUT"
#define GRUB_TIMEOUT_command "ubconfig --source system get boot GRUB_TIMEOUT"

#define GRUB_DEFAULT_parameter "GRUB_DEFAULT"
#define GRUB_DEFAULT_command "ubconfig --source system get boot GRUB_DEFAULT"

#define GRUB_BOOT_SILENT_parameter "GRUB_BOOT_SILENT"
#define GRUB_BOOT_SILENT_command "ubconfig --source system get boot GRUB_BOOT_SILENT"

#define GRUB_PASSWORD_parameter "GRUB_PASSWORD"
#define GRUB_PASSWORD_search "GRUB_PASSWORD["
#define GRUB_PASSWORD(target) yon_char_unite("GRUB_PASSWORD[",target,"]",NULL)
#define GRUB_PASSWORD_command "ubconfig --source system get boot GRUB_PASSWORD[*]"

#define GRUB_CMDLINE_LINUX_parameter "GRUB_CMDLINE_LINUX"
#define GRUB_CMDLINE_LINUX_command "ubconfig --source system get boot GRUB_CMDLINE_LINUX"

#define GRUB_TERMINAL_INPUT_parameter "GRUB_TERMINAL_INPUT"
#define GRUB_TERMINAL_INPUT_command "ubconfig --source system get boot GRUB_TERMINAL_INPUT"

#define GRUB_TERMINAL_OUTPUT_parameter "GRUB_TERMINAL_OUTPUT"
#define GRUB_TERMINAL_OUTPUT_command "ubconfig --source system get boot GRUB_TERMINAL_OUTPUT"

#define GRUB_USER_parameter "GRUB_USER"
#define GRUB_USER_command "ubconfig --source system get boot GRUB_USER"

#define GRUB_SUPERUSERS_parameter "GRUB_SUPERUSERS"
#define GRUB_SUPERUSERS_command "ubconfig --source system get boot GRUB_SUPERUSERS"

#define GRUB_PLAY_parameter "GRUB_PLAY"
#define GRUB_PLAY_command "ubconfig --source system get boot GRUB_PLAY"

typedef char* string;

__attribute__((unused)) static \
string version_application;

typedef struct {
    template_config_fields
    int save_config;
    config_str launch_arguments;
    int launch_size;
    int password_min_length;

    int kernel_size;
    config_str kernel_parameters;

    int input_size;
    config_str input_parameters;

    int output_size;
    config_str output_parameters;

} config;
extern config main_config; 

typedef struct {
    template_window_fields
    GtkWidget *BootDisplayModeCombo;
    GtkWidget *BootRingtoneAddButton;
    GtkWidget *BootRingtoneEditButton;
    GtkWidget *BootRingtoneRemoveButton;
    GtkWidget *BootRingtoneTree;
    GtkWidget *BootSelectionTimerCheck;
    GtkWidget *BootSelectionTimerSpin;
    GtkWidget *BootUsersAddButton;
    GtkWidget *BootUsersEditButton;
    GtkWidget *BootUsersRemoveButton;
    GtkWidget *BootUsersTree;
    GtkWidget *CommandLineParametersEntry;
    GtkWidget *InputTerminalEntry;
    GtkWidget *InputTerminalTree;
    GtkWidget *KernelParametersTree;
    GtkWidget *MenuButton;
    GtkWidget *MenuOverlay;
    GtkWidget *OSDefaultEntry;
    GtkWidget *OutputTerminalEntry;
    GtkWidget *OutputTerminalTree;

    GtkCellRenderer *MelodyChosenCellRenderer;
    GtkCellRenderer *KernelChooseCell;
    GtkCellRenderer *OutputChosenCell;
    GtkCellRenderer *InputChosenCell;

    GtkListStore *BootUsersList;
    GtkListStore *BootRingtoneList;
    GtkListStore *KernelParametersList;
    GtkListStore *InputTerminalList;
    GtkListStore *OutputTerminalList;

} main_window;

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

	GtkWidget *UserCancelButton;
	GtkWidget *UserOkButton;
	GtkWidget *PasswordEntry;
	GtkWidget *RepeatPasswordEntry;
	GtkWidget *PasswordHashEntry;
	GtkWidget *HashBox;
	GtkWidget *PasswordBox;
	GtkWidget *NoEncriptionCheck;
} yon_bootloader_password_window;

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

	GtkWidget *AdminCheck;
	GtkWidget *UsernameEntry;
	GtkWidget *PasswordEntry;
    GtkWidget *PasswordButton;

	GtkWidget *CancelButton;
	GtkWidget *AcceptButton;

    char *prev_name;
} yon_user_window;

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

	GtkWidget *NameEntry;
	GtkWidget *CodeEntry;

	GtkWidget *CancelButton;
	GtkWidget *AcceptButton;

    char *prev_name;
} yon_ringtone_window;

typedef struct
{
	GtkWidget *MenuWindow;
	GtkWidget *BackButton;
	GtkWidget *ItemsRevealer;
	GtkWidget *ItemsListBox;
	GtkWidget *ChildrenRevealer;
	GtkWidget *ChildrenListBox;
	GtkWidget *target;

	int seat_grab;
	dictionary *menu_items;
	char *cur_selection;
	int button_pos_x;
	int button_pos_y;
} yon_menu_window;

typedef struct
{
	GtkWidget *MenuItemRow;
	GtkWidget *MenuTextLabel;
	GtkWidget *ArrowImage;

	yon_menu_window *window;
	
	char *name;
	char *id;
	int children;

} yon_menu_item;

//main
void on_save_done(main_window *, config_str output, int size);
void on_config_global_local_save(GtkWidget *, main_window *);
void on_config_local_save(GtkWidget *, main_window *);
void on_config_global_save(GtkWidget *, main_window *);
void on_config_custom_save(GtkWidget *, main_window *);
void on_config_local_load(GtkWidget *,main_window *);
void on_config_global_load(GtkWidget *,main_window *);
void on_config_custom_load(GtkWidget *,main_window *);

void yon_load_proceed(YON_CONFIG_TYPE type);

void yon_interface_update(main_window *);

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

void on_kernel_parameter_switch(GtkCellRenderer *, char *path, main_window *widgets);
void on_input_option_switch(GtkCellRenderer *,char *path, main_window *widgets);
void on_output_option_switch(GtkCellRenderer *,char *path, main_window *widgets);

void config_init();

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

void yon_main_window_complete(main_window *widgets);

//password
void yon_password_change(GtkWidget *, GtkEntry *entry);
void on_password_accept(GtkWidget *self, dictionary *dict);
yon_bootloader_password_window *yon_ubl_settings_usergroups_password_new();
int yon_check_password_blocked(char *password);

//user
void on_user_accept(GtkWidget *,dictionary *dict);
void on_user_add_clicked(GtkWidget *,main_window *widgets);
void on_user_edit_clicked(GtkWidget *,main_window *widgets);
void on_user_remove_clicked(GtkWidget *,main_window *widgets);
yon_user_window *yon_user_window_new();

//ringtone
void on_ringtone_accept(GtkWidget *,dictionary *dict);
void on_ringtone_add_clicked(GtkWidget *,main_window *widgets);
void on_ringtone_edit_clicked(GtkWidget *,main_window *widgets);
void on_ringtone_remove_clicked(GtkWidget *,main_window *widgets);
yon_ringtone_window *yon_ringtone_window_new();

//menu

yon_menu_item *yon_menu_item_new();
yon_menu_window *yon_menu_window_new();
void on_menu_window_size_reallocated(GtkWidget *self, GtkAllocation *, yon_menu_window *window);
void on_children_clean(GtkWidget *, yon_menu_window *window);
gboolean yon_on_revealer_switched(yon_menu_window *window);
gboolean on_menu_clicked(GtkWidget *, GdkEventButton *event, yon_menu_window *window);
yon_menu_window *yon_menu_window_open(GtkWidget *, main_window *widgets);
void yon_menu_open_submenu(yon_menu_window *window, yon_menu_item *item);
yon_menu_item *yon_menu_add_item(yon_menu_window *target_menu,const char *id, const char *name, int children);
void yon_menu_ungrab(yon_menu_window *window);
void on_menu_chosen(GtkWidget *, GtkListBoxRow* row, yon_menu_window *window);
void on_children_clean(GtkWidget*, yon_menu_window *window);
gboolean yon_on_revealer_switched (yon_menu_window *window);
void yon_save_window_hide_passwords(template_saving_window *window);
void on_tree_view_selection_changed(GtkWidget *self, main_window *widgets);
void on_melody_toggled(GtkCellRenderer *self, char *path, main_window *widgets);
char *yon_bootloader_get_os_name(char *parameter);