/*
** This file is part of the ViTE project.
**
** This software is governed by the CeCILL-A license under French law
** and abiding by the rules of distribution of free software. You can
** use, modify and/or redistribute the software under the terms of the
** CeCILL-A license as circulated by CEA, CNRS and INRIA at the following
** URL: "http://www.cecill.info".
**
** As a counterpart to the access to the source code and rights to copy,
** modify and redistribute granted by the license, users are provided
** only with a limited warranty and the software's author, the holder of
** the economic rights, and the successive licensors have only limited
** liability.
**
** In this respect, the user's attention is drawn to the risks associated
** with loading, using, modifying and/or developing or reproducing the
** software by the user in light of its specific status of free software,
** that may mean that it is complicated to manipulate, and that also
** therefore means that it is reserved for developers and experienced
** professionals having in-depth computer knowledge. Users are therefore
** encouraged to load and test the software's suitability as regards
** their requirements in conditions enabling the security of their
** systems and/or data to be ensured and, more generally, to use and
** operate it in the same conditions as regards security.
**
** The fact that you are presently reading this means that you have had
** knowledge of the CeCILL-A license and that you accept its terms.
**
**
** ViTE developers are (for version 0.* to 1.0):
**
**        - COULOMB Kevin
**        - FAVERGE Mathieu
**        - JAZEIX Johnny
**        - LAGRASSE Olivier
**        - MARCOUEILLE Jule
**        - NOISETTE Pascal
**        - REDONDY Arthur
**        - VUCHENER Clément
**
*/
/*!
 *\file Interface_graphic.hpp
 */

#ifndef INTERFACE_GRAPHIC_HPP
#define INTERFACE_GRAPHIC_HPP


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

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

/* Global informations */
#include "interface/Interface.hpp"
#include "interface/Settings_window.hpp"
#include "interface/Node_select.hpp"
#include "interface/Interval_select.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 Interface{
    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.
     */
    QGLWidget* _ui_render_area;

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

    /*!
     * \brief This variable contains the instance of the horizontal scroll bar.
     */
    QScrollBar* _ui_x_scroll;

    /*!
     * \brief This variable contains the instance of the vertical scroll bar.
     */
    QScrollBar* _ui_y_scroll;

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

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

    /*!
     * \brief Contains the zoom box instance.
     */
    QComboBox* _ui_zoom_box;

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

    /*!
     * \brief Contains the last zoom value. (Prevent recursive calls)
     */
    QString _zoom_box_check_value;

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

    /*!
     * \brief Contains the conversion factor between x virtual and real scroll unit.
     */
    double _x_factor_virtual_to_real;

    /*!
     * \brief Contains the conversion factor between y virtual and real scroll unit.
     */
    double _y_factor_virtual_to_real;

    /*!
     * \brief Contains the real x scroll bar length.
     */
    static const int _REAL_X_SCROLL_LENGTH = 10000;

    /*!
     * \brief Contains the real x scroll bar length.
     */
    static const int _REAL_Y_SCROLL_LENGTH = 10000;

    /***********************************
     *
     * 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 export box window of the application.
     */
    QWidget* _ui_time_selection_export;

    /*!
     * \brief Dialog box to give some help for user.
     */
    QWidget* _ui_help_window;

    /*!
     * \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.
     */
    QTextEdit* _ui_info_selection_text;

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

    /*!
     * \brief The window to use an extern command on the trace
     */
    Command_window * _cmd_window;

    /*!
     * \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.
     */
    QWidget* _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 Prevent recursive callings when changing manualy scroll bars.
     */
    bool _on_manual_change;

    /*!
     * \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;



    /***********************************
     *
     * Informative message functions.
     *
     **********************************/

    /*!
     * \brief The function takes strings and/or numbers then displayed an info box containing it, then the program go on with an indeterminated behaviour.
     * \param string The string to be displayed.
     */
    void error(const std::string &string) const override;


    /*!
     * \brief The function takes strings and/or numbers then displayed an info box containing it, then the program go on with an indeterminated behaviour.
     * \param string The string to be displayed.
     */
    void warning(const std::string &string) const override;


    /*!
     * \brief The function takes strings and/or numbers then displayed an info box containing it, then the program go on.
     * \param string The string to be displayed.
     */
    void information(const std::string &string) const override;



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

    /*!
     * \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 &string) const override;

    /***********************************
     *
     * 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 Bind a render area to the main window.
     * \param render_area A pointer to a QGLWidget.
     */
    void bind_render_area(QGLWidget* render_area);

    /*!
     * \brief Ajust scroll bar length.
     * \param new_x_virtual_length The new virtual x length of the scroll bar.
     * \param new_y_virtual_length The new virtual y length of the scroll bar.
     */
    void set_scroll_bars_length(Element_pos new_x_virtual_length, Element_pos new_y_virtual_length);

    /*!
     * \brief Ajust scroll bar values when there is a translation.
     * \param x_bar_new_value The new x_scroll bar value.
     * \param y_bar_new_value The new y_scroll bar value.
     */
    void linking_scroll_bars(Element_pos x_bar_new_value, Element_pos y_bar_new_value);

    /*!
     * \brief Convert scroll units from real scroll bar unit to render area scroll unit.
     * \param scroll_position The real value to convert.
     * \param axe The choiced axe conversion ('x' for horizontal scrolling or 'y' for vertical scrolling)
     * \return The converted value.
     */
    Element_pos real_to_virtual_scroll_unit(int scroll_position, const char &axe);

    /*!
     * \brief Convert scroll units from virtual render area scroll unit to real scroll bar unit.
     * \param scroll_position The virtual value to convert.
     * \param axe The choiced axe conversion ('x' for horizontal scrolling or 'y' for vertical scrolling)
     * \return The converted value.
     */
    int virtual_to_real_scroll_unit(Element_pos scroll_position, const char &axe);

    /*!
     * \brief Change the current value of the zoom box.
     * \param new_value The new zoom value.
     */
    void change_zoom_box_value(int new_value);

    /*!
     * \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;

    /*!
     * \brief Get the name of the current trace file.
     *
     * \return The name of the current trace file
     */
    const std::string get_filename() const override;

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

         /*!
     * \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();

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



protected 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 'quit' in the menu is clicked.
     */
    void on_quit_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 'help' in the menu is clicked.
     */
    void on_help_triggered();

    /*!
     *\brief A slot called when 'about' in the menu is clicked.
     */
    void on_about_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 'command' in the menu is clicked.
     */
    void on_actionCommand_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 'zoom_in' in the menu is clicked.
     */
    void on_zoom_in_triggered();

    /*!
     *\brief A slot called when 'zoom_out' in the menu is clicked.
     */
    void on_zoom_out_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 A slot called when 'zoom_box' widget is triggered.
     *
     * \param s The new string value of the zoom box.
     */
#if QT_VERSION < 0x050000
    void on_zoom_box_textChanged(const QString &s);
#else
    void on_zoom_box_currentTextChanged(const QString &s);
#endif

    /*!
     * \brief Change the x position of camera view for state drawing area.
     * \param new_value The new position.
     */
    void on_x_scroll_valueChanged(int new_value);/* temporary slot */

    /*!
     * \brief Change the y position of camera view for state drawing area.
     * \param new_value The new position.
     */
    void on_y_scroll_valueChanged(int new_value);/* temporary slot */

    /*!
     * \brief Change the percentage taken by container display in the render area.
     * \param new_value The new percentage (between 0 to 100).
     */
    void on_scale_container_state_valueChanged(int new_value);/* temporary slot */
    /*!
     * \brief Says to the concerned classes that settings has been changed.
     */
    void update_settings();

};

#endif
