#ifndef UI_INCLUDED
#define UI_INCLUDED

#include <osi/gui.hpp>

#include <edit/editor.hpp>
#include <osi/keyboard.hpp>
#include <osi/window.hpp>
#include <rofi/voxel_graph.hpp>
#include <rofi/connector.hpp>
#include <rofi/voxel.hpp>

#include <string.h>

/* UI Constants */ // TO DO: adjust for font size
static const float mode_toolbar_width = 275.0f;
static const float mode_toolbar_height = 40.0f;
static const float build_toolbar_width = 400.0f;
static const float build_toolbar_button_width = 90.0f;
static const float build_toolbar_height = 40.0f;

void show_ui(const osi::Window &window, edit::UIData &data, const double &current_second);
void show_edit_error_msg(const osi::Window &window, edit::UIData &data, const double current_second);

/* MAIN MENU BAR */
void menu_bar_ui(const osi::Window &window, edit::UIData &data);
void phase_menu_ui(const osi::Window &window, edit::UIData &data);
void mode_menu_ui(const osi::Window &window, edit::UIData &data);
void mode_I_menu_ui(const osi::Window &window, edit::UIData &data);
void mode_II_menu_ui(const osi::Window &window, edit::UIData &data);
void module_menu_ui(const osi::Window &window, edit::UIData &data);
void rofiworld_menu_ui(const osi::Window &window, edit::UIData &data);
void rofiworld_selection_menu_ui(const osi::Window &window, edit::UIData &data);
void file_menu_ui(const osi::Window &window, edit::UIData &data);
void help_menu_ui(const osi::Window &window, edit::UIData &data);

/* BUILD UI */
void phase_one_ui(const osi::Window &window, edit::UIData &data);
void phase_two_ui(const osi::Window &window, edit::UIData &data);
void mode_I_build_ui(const osi::Window &window, edit::UIData &data);
void mode_II_build_ui(const osi::Window &window, edit::UIData &data);
void mode_I_build_selection_ui(const osi::Window &window, edit::UIData &data);
void mode_II_build_selection_ui(const osi::Window &window, edit::UIData &data);
void build_toolbar_ui(const osi::Window &window, edit::UIData &data);
void build_toolbar_buttons(edit::UIData &data);
void set_build_toolbar_button_colors(edit::UIData &data);
void create_pad_ui(const osi::Window &window, edit::UIData &data);
void module_id_ui(const osi::Window &window, edit::UIData &data);
void module_change_id_ui(const osi::Window &window, edit::UIData &data);
void module_selection_ui(const osi::Window &window, edit::UIData &data);
void module_connection_ui(const osi::Window &window, edit::UIData &data);
void module_movement_ui(const osi::Window &window, edit::UIData &data);
void module_rotation_ui(const osi::Window &window, edit::UIData &data);
void module_rotation_drag(edit::UIData &data, glm::vec3 &euler_angles);
void module_rotation_manual(edit::UIData &data, glm::vec3 &euler_angles);
void component_rotation_ui(const osi::Window &window, edit::UIData &data);
void save_module_ui(const osi::Window &window, edit::UIData &data);
void save_rofiworld_ui(const osi::Window &window, edit::UIData &data);
void export_file_ui(const osi::Window &window, edit::UIData &data);
void export_module_file_ui(const osi::Window &window, edit::UIData &data);
void export_rofiworld_file_ui(const osi::Window &window, edit::UIData &data);
void import_file_ui(const osi::Window &window, edit::UIData &data);
void import_rofiworld_file_ui(const osi::Window &window, edit::UIData &data);
void start_new_rofiworld_ui(const osi::Window &window, edit::UIData &data);
void rotation_settings(const osi::Window &window, edit::UIData &data);
void experimental_warning(const osi::Window &window, edit::UIData &data);

/* SPECTATE */
void spectate_ui(const osi::Window &window);

/* DEBUG */
void debug_controls(edit::state &control_state);
std::string state_to_str(edit::state &control_state);

/* HELP */
void show_help(const osi::Window &window, bool &help_controls_displayed);
void show_help_minimized(const osi::Window &window);
void show_help_controls(const osi::Window &window, bool &help_controls_displayed);
void general_controls_tab();
void phase_i_controls_tab();
void phase_ii_controls_tab();

#endif
