/*
** 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 Session.hpp
 */

#ifndef SESSION_HPP
#define SESSION_HPP

class Palette;
class Color;
class QByteArray;
class QString;
class QStringList;
#include <QColor>
#include <QSettings>
#include <list>

/*!
 * \def RECENT_FILES
 * \brief The recent file key for Settings
 */
#define RECENT_FILES "recentFiles"

/*!
 * \def VERTICAL_LINE
 * \brief The setting for the vertical line
 */
#define VERTICAL_LINE "vertical_line"

/*!
 * \def RELOAD_TYPE
 * \brief The setting for the vertical line
 */
#define RELOAD_TYPE "reload_type"

/*!
 * \def HIDE_WARNINGS
 * \brief The setting for the hide warnings setting
 */
#define HIDE_WARNINGS "hide_warnings"

/*!
 * \def SHADED_STATE
 * \brief The setting for the shaded states
 */
#define SHADED_STATE "shaded_state"

/*!
 * \def PLUGIN_DIR
 * \brief The plugin directory key for Settings
 */
#define PLUGIN_DIR "plugin_dir"

/*!
 * \def CUR_PALETTE
 * \brief The current palette key for Settings
 */
#define CUR_PALETTE "/current_name"
/*!
 * \def PALETTE_NAMES
 * \brief The current palette names key for Settings
 */
#define PALETTE_NAMES "/palettes_name"


class MinimapSettings {
public:
    int _x, _y;
    int _width, _height;
    int _pen_size;
    QColor _pen_color, _brush_color;
    bool _is_closed;

    MinimapSettings();
    ~MinimapSettings();

    void load();
    void save();
    void save(int x, int y, int w, int h, bool hidden );
};

/*!
 * \brief Sub structure to store export information.
 */
class ExportSettings {

public:
    /*!
     * \brief Store the export file dialog state.
     */
    QByteArray file_dialog_state;

    ExportSettings();

    bool is_default();
};


/*!
 * \brief Class used to store information between two software launch.
 *
 */
class Session : public QSettings {

protected:
    static Session         *S;
    static MinimapSettings *_mmSettings;
    static ExportSettings  *_exportSettings;

    static Palette *_palettes_state;
    static Palette *_palettes_link;
    static Palette *_palettes_event;

    //boolean used to know if palettes are used (only one boolean for all types of palettes)
    static bool _use_palettes;
    //boolean used to know if the previous one is set (ugly but avoids rereading from settings file each time)
    static bool _use_palettes_is_set;

    /*!
     * \brief The class constructor.
     */
    Session();

    static void init();

public:

    static Session &getSession() {
        if (S == nullptr) {
            S = new Session();
            init();
        }
        return *S;
    }

    static MinimapSettings &getSessionMinimap() {
        return *(getSession()._mmSettings);
    }

    static ExportSettings &getSessionExport() {
        return *(getSession()._exportSettings);
    }

    /*!
     * \brief The class destructor.
     */
    ~Session() override;

    /*!
     * \brief maximum number of file shown in the recent files menu.
     */
    static const int _MAX_NB_RECENT_FILES = 10;

    static void save_config_file();
    static void load_config_file();

    /*!
     * \fn update_vertical_line_setting(bool b)
     * \brief set if we want to display the vertical line or not
     */
    static void update_vertical_line_setting(bool b);

    /*!
     * \fn get_vertical_line_setting()
     * \brief check if we want to display the vertical line or not
     */
    static bool get_vertical_line_setting();

    /*!
     * \fn update_reload_type_setting(bool b)
     * \brief set the type of reload we want (true : reload with parsing, false: reload without parsing)
     */
    static void update_reload_type_setting(bool b);


    /*!
     * \fn get_reload_type_setting()
     * \brief check the type of reload we want (true : reload with parsing, false: reload without parsing)
     */
    static bool get_reload_type_setting();

    /*!
     * \fn get_shaded_states_setting()
     * \brief set if we want to display shaded states in the trace or not
     */
    static void update_shaded_states_setting(bool b);

    /*!
     * \fn get_shaded_states_setting()
     * \brief check if we want to display shaded states in the trace or not
     */
    static bool get_shaded_states_setting();

    /*!
     * \fn get_hide_warnings_setting()
     * \brief chack if we want to display warnings or not after loading a trace
     */
    static bool get_hide_warnings_setting();

    /*!
     * \fn update_hide_warnings_settings(bool b)
     * \brief stores if we want to display warnings or not after loading a trace
     */
    static void update_hide_warnings_settings(bool b) ;

    /*!
     * \fn get_recent_files()
     * \brief Get the list of the recent files
     */
    static const QStringList get_recent_files();

    /*!
     * \fn add_recent_file(const QString &filename)
     * \brief Add to the recent files opened the new file.
     * \param filename : the name of the file read
     */
    static void add_recent_file(const QString &filename);

    /*!
     * \fn clear_recent_files()
     * \brief Clear all the recent files opened. Only in the QSettings files, not in the graphical interface.
     */
    static void clear_recent_files();

    /*!
     * \fn load_plugin_directories(QStringList &list)
     * \brief Fill the QStringList passed in parameter with the user plugin directories
     */
    static void load_plugin_directories(QStringList &list);
    /*!
     * \fn save_plugin_directories(const QStringList &list)
     * \brief Save the QStringList passed in parameter as the user plugin directories
     */
    static void save_plugin_directories(const QStringList &list);

    /*!
     * \fn set_use_palette(bool use)
     * \brief Set if we use the current palette when we load a trace.
     * \param use : true if we use the current palette.
     */
    static void set_use_palette(const std::string &type, bool use);

    /*!
     * \fn get_use_palette()
     * \brief Get if we use the current palette when we load a trace.
     */
    static bool get_use_palette(const std::string &type);
    /*!
     * \fn get_palettes_name(QStringList &list)
     * \brief Fill the list with all the existing palettes name.
     * \param list : the list filled
     */
    static void get_palettes_name(const std::string &type, QStringList &list);

    /*!
     * \fn get_palette(const std::string &name)
     * \brief Create and return the palette with the name passed in parameter.
     * \param name : the name of the required palette
     */
    static Palette *get_palette(const std::string &type, const std::string &name = "default");

    /*!
     * \fn get_current_palette()
     * \brief return the name of the current palette (last used)
     */
    static std::string get_current_palette(const std::string &type);
    /*!
     * \fn set_current_palette(const std::string &name)
     * \brief set the name of the current palette
     * \param name : the name of the palette
     */
    static void set_current_palette(const std::string &type, const std::string &name);

    /*!
     * \fn create_palette(const std::string &name)
     * \brief Create an empty palette named name.
     * \param name : the name of the palette
     */
    static void create_palette(const std::string &type, const std::string &name);
    /*!
     * \fn remove_palette(const std::string &name)
     * \brief Remove the palette named name.
     * \param name : the name of the palette
     */
    static void remove_palette(const std::string &type, const std::string &name);

    /*!
     * \fn copy_palette(const std::string &src, const std::string &dest)
     * \brief Copy the src palette to dest
     * \param src : the name of the source palette
     * \param dest : the name of the destination palette
     */
    static void copy_palette(const std::string &type, const std::string &src, const std::string &dest);
    /*!
     * \fn add_state_to_palette(const std::string &palette_name, const std::string &state_name, const Color &c)
     * \brief Add the state with its color of the palette.
     * \param palette_name : the palette name
     * \param state_name : the state name
     * \param c : the state color
     */
    static void add_state_to_palette(const std::string &type, const std::string &palette_name, const std::string &state_name, const Color &c, bool visible);
    /*!
     * \fn remove_state_to_palette(const std::string &palette_name, const std::string &state_name)
     * \brief Remove the state of the palette.
     * \param palette_name : the palette name
     * \param state_name : the state name
     */
    static void remove_state_to_palette(const std::string &type, const std::string &palette_name, const std::string &state_name);
};

#endif
