/**
 *
 * @file src/interface/Interface_graphic.hpp
 *
 * @copyright 2008-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
 *                      Univ. Bordeaux. All rights reserved.
 *
 * @author Camille Ordronneau
 * @author Johnny Jazeix
 * @author Nolan Bredel
 * @author Mathieu Faverge
 * @author Francois Trahay
 * @author Kevin Coulomb
 * @author Jule Marcoueille
 * @author Lucas Guedon
 * @author Olivier Lagrasse
 * @author Augustin Degomme
 *
 * @date 2024-07-17
 */
/*!
 *\file Interface_graphic.hpp
 */

#ifndef INTERFACE_GRAPHIC_HPP
#define INTERFACE_GRAPHIC_HPP

class Core;
class Interface_graphic;
class Plugin_window;
class RenderLayout;
class Svg;
class Variable;
class QProgressDialog;

/* Includes needed by the moc */
#include <QTextEdit>
#include <QRadioButton>
#include <QPushButton>
#include <QWidget>
/* -- */
#include "common/common.hpp"
#include "common/Log.hpp"
#include "common/Session.hpp"
/* -- */
#include "ui_main_window.h" /* the main window graphical interface */

/* Global information */
#include "interface/Settings_window.hpp"
#include "interface/Node_select.hpp"
#include "interface/Interval_select.hpp"
/* -- */
#include "render/Render.hpp"
#include "render/Render_windowed.hpp"
/*!
 *\brief This class is a graphical interface which creates a window, it inherited from the Interface interface.
 */
class Interface_graphic : public QMainWindow, protected Ui::main_window, public Log
{
    Q_OBJECT
protected:
    /***********************************
     *
     * Window function.
     *
     **********************************/

    /*!
     * \brief This functions load the windows from .ui files and init widgets.
     */
    void load_windows();

    /*!
     *\brief Drag and drop functions
     */
    void dragEnterEvent(QDragEnterEvent *event) override;
    void dragMoveEvent(QDragMoveEvent *event) override;
    void dragLeaveEvent(QDragLeaveEvent *event) override;
    void dropEvent(QDropEvent *event) override;

    /*!
     *\brief Open the trace of filename. Create a new process if necessary
     */
    void open_trace(const QString &filename);

    /***********************************
     *
     * Main window widget attributes.
     *
     **********************************/

    /*!
     * \brief This variable contains the action to switch in fullscreen mode.
     */
    QAction *_ui_fullscreen_menu;

    /*!
     * \brief This variable contains the toolbar
     */
    QToolBar *_ui_toolbar;

    /*!
     * \brief This variable contains the OpenGL render area.
     */
    RenderLayout *_render_layout;

    /*!
     * \brief Layout which will contain the render area.
     */
    QVBoxLayout *_ui_render_area_container_layout;

    /*!
     * \brief Layout which will contain the render area.
     */
    QWidget *_ui_render_area_container_widget;

    /*!
     *\brief To show the avancement of parsing.
     */
    QProgressDialog *_progress_dialog;

    /*!
     * \brief Contains the Core parent instance.
     */
    Core *_core;

    /*!
     * \brief Use to store the filename when the trace is exported.
     */
    QString _export_filename;

    /*!
     * \brief Contains the trace displayed path.
     */
    std::string _trace_path;

    /***********************************
     *
     * Informative window widget attributes.
     *
     **********************************/

    /*!
     * \brief This variable contains the floatting info box window of the application.
     */
    QWidget *_ui_info_window;

    /*!
     * \brief This variable contains the floatting box window for information on user selection in the application.
     */
    QWidget *_ui_select_info_window;

    /*!
     * \brief This variable contains the floatting export box window of the application.
     */
    QWidget *_ui_time_selection_export;

    /*!
     * \brief Dialog box to allow user to set its ViTE environment. (change color, text size, etc.)
     */
    Settings_window *_ui_settings;

    /*!
     * \brief Dialog box to allow user to select nodes to display
     */
    Node_select *_ui_node_selection;

    /*!
     * \brief Dialog box to allow user to select nodes to display
     */
    Interval_select *_ui_interval_selection;

    /*!
     * \brief Text area which informs the user about the trace resume.
     */
    QTextEdit *_ui_info_trace_text;

    /*!
     * \brief Text area which informs the user about the selected entity information.
     */
    QTabWidget *_ui_info_selection_tabs;

    /*!
     * \brief The menu where recent files are printed
     */
    QMenu *_ui_recent_files_menu;

    /*!
     * \brief The window to use plugins
     */
    Plugin_window *_plugin_window;

    /***********************************
     *
     * Export windows.
     *
     **********************************/

    /*!
     * \brief ComboBox which allow the choice between svg export and counter export.
     */
    QWidget *_ui_kind_of_export_choice;
    QRadioButton *_ui_svg_export_button;
    QRadioButton *_ui_png_export_button;
    QRadioButton *_ui_counter_export_button;

    /*!
     * \brief ComboBox which allow the choice between all the counters to be exported.
     */
    QDialog *_ui_counter_choice_to_export;
    QComboBox *_counter_list_names;
    std::map<std::string, Variable *> _all_variables;

    /***********************************
     *
     * Help window.
     *
     **********************************/

    /*!
     * \brief Button uses to close the help window.
     */
    QPushButton *_ui_help_ok_button;

    /***********************************
     *
     * Render area attribute.
     *
     **********************************/

    /*!
     * \brief The state of render.
     */
    bool _is_rendering_trace;

    /*!
     * \brief Prevent warnings to be displayed (used with malformed traces to prevent Qt spending too much time).
     */
    bool _no_warning;

    /*!
     * \brief if true, reload button reloads it from the trace (new parsing), if false, just update the render
     */
    bool _reload_type;

    /*!
     * \brief Contains the list of the recent files and the associated action
     */
    QAction *_recent_file_actions[Session::_MAX_NB_RECENT_FILES];

public:
    /***********************************
     *
     * Constructors and destructor.
     *
     **********************************/

    /*!
     * \brief The default constructor
     * \param core The Core object which launch the Interface_graphic. It can be viewed as the application core.
     * \param parent The parent widget of the graphical interface. Should be ignored.
     */
    Interface_graphic(Core *core, QWidget *parent = nullptr);

    /*!
     * \brief The destructor
     */
    ~Interface_graphic() override;

    /***********************************
     *
     * Log function :
     *
     **********************************/

    /*!
     * \brief The function takes a string then displayed it into the log_window
     * \param string The string to be displayed.
     */
    void error(const std::string &string) const override;

    /*!
     * \brief The function takes a string then displayed it into the log_window
     * \param string The string to be displayed.
     */
    void warning(const std::string &string) const override;

    /*!
     * \brief The function takes a strings then displayed it into the log_window
     * \param string The string to be displayed.
     */
    void information(const std::string &string) const override;

    /***********************************
     *
     * Selected Trace entity informative function.
     *
     **********************************/

    /*!
     * \brief Clear all entity tabs in the select_info_window.
     */
    void selection_information_clear() const;

    /*!
     * \brief Show the select_info_window.
     */
    void selection_information_show() const;

    /*!
     * \brief The function takes strings and/or numbers then displayed it in the entity informative text area in the info window.
     * \param string The string to be displayed.
     */
    void selection_information(const std::string &tab_name, const std::string &content) const;

    /***********************************
     *
     * Parsing functions.
     *
     **********************************/

    /*!
     * \brief Initialize the progress dialog bar and disable the main window.
     * \param filename The file name of the file parsed.
     */
    void init_parsing(const std::string &filename);

    /*!
     * \brief Update the bar with the new time and the percentage loaded.
     * \param filename The file name of the file parsed.
     */
    void update_progress_bar(const QString &text, const int loaded);

    /*!
     * \brief Says if the user has canceled the parsing operation. This means that he clicked on the cancel button of the progress dialog.
     */
    bool is_parsing_canceled();

    /*!
     * \brief Finish the parsing by hiding the progress bar and enable the main window.
     */
    void end_parsing();

    /***********************************
     *
     * Tool functions.
     *
     **********************************/

    /*!
     * \brief Create a Parser and a DataStructure to display a trace file.
     * \param path The path of the file.
     */
    void opening_file(const std::string &path);

    /*!
     * \brief Function called when close event is received.
     * \param event The event.
     *
     * This function can be used to display message for user to store its work before application closes.
     */
    void closeEvent(QCloseEvent *event) override;

    /*!
     * \fn get_console()
     * \brief To get the interface console
     */
    Core *get_console();

    /*!
     * \brief Getter for the render windowed shown
     */
    Render_windowed *get_render_area();

    /*!
     * \fn get_node_select()
     * \brief To get the node selection console
     */
    Node_select *get_node_select();

    /*!
     * \fn get_interval_select()
     * \brief To get the node selection console
     */
    Interval_select *get_interval_select();

    /**
     * \brief Called by RenderLayout to update slider value in IntervalSelect when it is change from the view
     */
    void update_interval_select();

    /*!
     * \fn update_recent_files_menu()
     * \brief update the recent files opened menu
     *
     */
    void update_recent_files_menu();

    /*!
     * \fn get_trace() const
     *\brief Accessor to the trace
     */
    Trace *get_trace() const;

    void set_trace(Trace *trace);

    /*!
     * \brief Changes goto_start and goto_end icons
     * \param is_along_y_axis True if goto icons should be along the y axis, otherwise it is along the x axis
     */
    void set_axis_icon(const bool is_along_y_axis);

    /***********************************
     *
     * Render area functions.
     *
     **********************************/

    /*!
     * \brief Set the render translation to a registered translation value.
     * \param id The id of the registered translation.
     */
    void render_area_registered_translate(const int &id);

    /*!
     * \brief Empty/Clean the render area.
     */
    void render_area_clean();

    /*!
     * \brief Show the minimap of the render area.
     */
    void render_show_minimap();

    /*!
     * \brief Zoom along the x axis between two values
     * \param begin The beginning time of the interval
     * \param end The end time of the interval
     */
    void render_zoom_on_interval(const Element_pos &begin, const Element_pos &end);

    /*!
     * \brief Initialize the render_area
     */
    void init_render_area();

    /*!
     * \brief Display information about a selected entity.
     */
    void render_display_information();

    /*!
     * \brief This method invert two containers laying on the same depth
     * \param x1 x coordinate of the first container
     * \param y1 y coordinate of the first container
     * \param x2 x coordinate of the second container
     * \param y2 y coordinate of the second container
     */
    void switch_container(const Element_pos &x1, const Element_pos &x2, const Element_pos &y1, const Element_pos &y2);

    /*!
     * \brief Return a new render depending on if Vulkan, VBO or OpenGL is activated
     */
    Render_windowed *create_render();

    /*!
     * \brief Release currently shown trace
     *
     */
    void release_render_area();

public Q_SLOTS:
    /*!
     *\brief A slot called when 'quit' in the menu is clicked.
     */
    void on_quit_triggered();

protected Q_SLOTS:

    /***********************************
     *
     * Widget slot functions.
     *
     **********************************/

    /*!
     *\brief A slot called when 'open' in the menu is clicked.
     */
    void on_open_triggered();

    /*!
     *\brief A slot called when 'export' in the menu is clicked.
     */
    void on_export_file_triggered();

    /*!
     *\brief A slot called when 'reload' in the menu is clicked.
     */
    void on_reload_triggered();

    /*!
     * \brief A slot called when a file on recent files is chosen.
     */
    void open_recent_file();

    /*!
     *\brief A slot called when 'Clear recent files' in the menu is clicked.
     */
    void on_clear_recent_files_triggered();

    /*!
     *\brief A slot called when the choice of the export is done and ok.
     */
    //  void choice_of_the_export_pressed();

    /*!
     *\brief A slot called when the choice of the counter is done and ok.
     */
    void counter_choosed_triggered();

    /*!
     *\brief A slot called when the options in export are ok.
     */
    void option_export_ok_pressed();

    /*!
     *\brief A slot called when 'close' in the menu is clicked.
     */
    void on_close_triggered();

    /*!
     *\brief A slot called when 'fullscreen' in the menu is clicked.
     */
    void on_fullscreen_triggered();

    /*!
     *\brief A slot called when 'Shaded states' in the menu is clicked.
     */
    void on_shaded_states_triggered();

    /*!
     *\brief A slot called when 'Vertical line' in the menu is clicked.
     */
    void on_vertical_line_triggered();

    /*!
     *\brief A slot called when 'Show toolbar' in the menu is clicked.
     */
    void on_toolbar_menu_triggered();

    /*!
     *\brief A slot called when 'Show minimap' in the menu is clicked.
     */
    void on_minimap_menu_triggered();

    /*!
     *\brief A slot called when 'show infos' in the menu is clicked.
     */
    void on_show_info_triggered();

    /*!
     *\brief A slot called when 'about' in the menu is clicked.
     */
    void on_about_triggered();

    /*!
     *\brief A slot called when 'Documentation' in the menu is clicked.
     */
    void on_documentation_triggered();

    /*!
     *\brief A slot called when 'Report Issue' in the menu is clicked.
     */
    void on_mail_triggered();

    /*!
     *\brief A slot called when 'Plugins' in the menu is clicked.
     */
    void on_show_plugins_triggered();

    /*!
     *\brief A slot called when 'Settings' in the menu is clicked.
     */
    void on_show_settings_triggered();

    /*!
     *\brief A slot called when 'Node selection' in the menu is clicked.
     */
    void on_node_selection_triggered();

    /*!
     *\brief A slot called when 'Node selection' in the menu is clicked.
     */
    void on_interval_selection_triggered();

    /*!
     *\brief A slot called when 'no_warning' in the menu is clicked.
     */
    void on_no_warning_triggered();

    /*!
     *\brief A slot called when 'reload_from_file' in the menu is clicked.
     */
    void on_reload_from_file_triggered();

    /*!
     *\brief A slot called when 'no_arrows' in the menu is clicked.
     */
    void on_no_arrows_triggered();

    /*!
     *\brief A slot called when 'no_events' in the menu is clicked.
     */
    void on_no_events_triggered();

    /*!
     *\brief A slot called when 'goto_start' in the menu is clicked.
     */
    void on_goto_start_triggered();

    /*!
     *\brief A slot called when 'goto_end' in the menu is clicked.
     */
    void on_goto_end_triggered();

    /*!
     *\brief A slot called when 'show_all_trace' in the menu is clicked.
     */
    void on_show_all_trace_triggered();

    /*!
     * \brief Says to the concerned classes that settings has been changed.
     */
    void update_settings();

    /*!
     * \brief A slot used to send a signal to Core when parsing is canceled
     */
    void cancel_parsing();

Q_SIGNALS:
    /*!
     * A signal emmited to stop the event loop when waiting for the parsing to stop
     */
    void stop_parsing_event_loop();
};

#endif
